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 .
21 #include "printhelper.hxx"
23 #include <com/sun/star/view/XPrintJob.hpp>
24 #include <com/sun/star/awt/Size.hpp>
25 #include <com/sun/star/lang/IllegalArgumentException.hpp>
26 #include <com/sun/star/view/PaperFormat.hpp>
27 #include <com/sun/star/view/PaperOrientation.hpp>
28 #include <com/sun/star/ucb/NameClash.hpp>
29 #include <com/sun/star/ucb/ContentCreationException.hpp>
30 #include <com/sun/star/ucb/CommandAbortedException.hpp>
31 #include <com/sun/star/frame/XModel.hpp>
32 #include <com/sun/star/view/DuplexMode.hpp>
33 #include <comphelper/processfactory.hxx>
34 #include <svl/itemset.hxx>
35 #include <svl/lstner.hxx>
36 #include <unotools/tempfile.hxx>
37 #include <osl/file.hxx>
38 #include <osl/thread.hxx>
39 #include <tools/urlobj.hxx>
40 #include <tools/diagnose_ex.h>
41 #include <ucbhelper/content.hxx>
42 #include <comphelper/multicontainer2.hxx>
43 #include <osl/mutex.hxx>
44 #include <cppuhelper/implbase.hxx>
45 #include <vcl/settings.hxx>
46 #include <vcl/svapp.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <sfx2/viewsh.hxx>
50 #include <sfx2/printer.hxx>
51 #include <sfx2/objsh.hxx>
52 #include <sfx2/event.hxx>
54 #define SFX_PRINTABLESTATE_CANCELJOB css::view::PrintableState(-2)
56 using namespace ::com::sun::star
;
57 using namespace ::com::sun::star::uno
;
59 struct IMPL_PrintListener_DataContainer
: public SfxListener
61 SfxObjectShellRef m_pObjectShell
;
62 comphelper::OMultiTypeInterfaceContainerHelper2 m_aInterfaceContainer
;
63 uno::Reference
< css::view::XPrintJob
> m_xPrintJob
;
64 css::uno::Sequence
< css::beans::PropertyValue
> m_aPrintOptions
;
66 explicit IMPL_PrintListener_DataContainer( ::osl::Mutex
& aMutex
)
67 : m_aInterfaceContainer ( aMutex
)
72 void Notify( SfxBroadcaster
& aBC
,
73 const SfxHint
& aHint
) override
;
76 static awt::Size
impl_Size_Object2Struct( const Size
& aSize
)
78 awt::Size aReturnValue
;
79 aReturnValue
.Width
= aSize
.Width() ;
80 aReturnValue
.Height
= aSize
.Height() ;
84 static Size
impl_Size_Struct2Object( const awt::Size
& aSize
)
87 aReturnValue
.setWidth( aSize
.Width
) ;
88 aReturnValue
.setHeight( aSize
.Height
) ;
94 class SfxPrintJob_Impl
: public cppu::WeakImplHelper
99 IMPL_PrintListener_DataContainer
* m_pData
;
102 explicit SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
);
103 virtual Sequence
< css::beans::PropertyValue
> SAL_CALL
getPrintOptions( ) override
;
104 virtual Sequence
< css::beans::PropertyValue
> SAL_CALL
getPrinter( ) override
;
105 virtual Reference
< css::view::XPrintable
> SAL_CALL
getPrintable( ) override
;
106 virtual void SAL_CALL
cancelJob() override
;
111 SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
)
116 Sequence
< css::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrintOptions()
118 return m_pData
->m_aPrintOptions
;
121 Sequence
< css::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrinter()
123 if( m_pData
->m_pObjectShell
.is() )
125 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
->GetModel(), UNO_QUERY
);
126 if ( xPrintable
.is() )
127 return xPrintable
->getPrinter();
129 return Sequence
< css::beans::PropertyValue
>();
132 Reference
< css::view::XPrintable
> SAL_CALL
SfxPrintJob_Impl::getPrintable()
134 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
.is() ? m_pData
->m_pObjectShell
->GetModel() : nullptr, UNO_QUERY
);
138 void SAL_CALL
SfxPrintJob_Impl::cancelJob()
140 // FIXME: how to cancel PrintJob via API?!
141 if( m_pData
->m_pObjectShell
.is() )
142 m_pData
->m_pObjectShell
->Broadcast( SfxPrintingHint( SFX_PRINTABLESTATE_CANCELJOB
) );
145 SfxPrintHelper::SfxPrintHelper()
147 m_pData
.reset(new IMPL_PrintListener_DataContainer(m_aMutex
));
150 void SAL_CALL
SfxPrintHelper::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
152 if ( !aArguments
.hasElements() )
155 css::uno::Reference
< css::frame::XModel
> xModel
;
156 aArguments
[0] >>= xModel
;
157 m_pData
->m_pObjectShell
= SfxObjectShell::GetShellFromComponent(xModel
);
158 if (m_pData
->m_pObjectShell
)
159 m_pData
->StartListening(*m_pData
->m_pObjectShell
);
162 SfxPrintHelper::~SfxPrintHelper()
168 view::PaperFormat
convertToPaperFormat(Paper eFormat
)
170 view::PaperFormat eRet
;
174 eRet
= view::PaperFormat_A3
;
177 eRet
= view::PaperFormat_A4
;
180 eRet
= view::PaperFormat_A5
;
183 eRet
= view::PaperFormat_B4
;
186 eRet
= view::PaperFormat_B5
;
189 eRet
= view::PaperFormat_LETTER
;
192 eRet
= view::PaperFormat_LEGAL
;
195 eRet
= view::PaperFormat_TABLOID
;
199 eRet
= view::PaperFormat_USER
;
205 Paper
convertToPaper(view::PaperFormat eFormat
)
207 Paper
eRet(PAPER_USER
);
210 case view::PaperFormat_A3
:
213 case view::PaperFormat_A4
:
216 case view::PaperFormat_A5
:
219 case view::PaperFormat_B4
:
222 case view::PaperFormat_B5
:
225 case view::PaperFormat_LETTER
:
228 case view::PaperFormat_LEGAL
:
231 case view::PaperFormat_TABLOID
:
232 eRet
= PAPER_TABLOID
;
234 case view::PaperFormat_USER
:
237 case view::PaperFormat::PaperFormat_MAKE_FIXED_SIZE
:
239 //deliberate no default to force warn on a new papersize
249 uno::Sequence
< beans::PropertyValue
> SAL_CALL
SfxPrintHelper::getPrinter()
251 // object already disposed?
252 SolarMutexGuard aGuard
;
254 // search for any view of this document that is currently printing
255 const Printer
*pPrinter
= nullptr;
256 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ? SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
257 SfxViewFrame
* pFirst
= pViewFrm
;
258 while ( pViewFrm
&& !pPrinter
)
260 pPrinter
= pViewFrm
->GetViewShell()->GetActivePrinter();
261 pViewFrm
= SfxViewFrame::GetNext( *pViewFrm
, m_pData
->m_pObjectShell
.get(), false );
264 // if no view is printing currently, use the permanent SfxPrinter instance
265 if ( !pPrinter
&& pFirst
)
266 pPrinter
= pFirst
->GetViewShell()->GetPrinter(true);
269 return uno::Sequence
< beans::PropertyValue
>();
271 uno::Sequence
< beans::PropertyValue
> aPrinter(8);
273 aPrinter
.getArray()[7].Name
= "CanSetPaperSize";
274 aPrinter
.getArray()[7].Value
<<= pPrinter
->HasSupport( PrinterSupport::SetPaperSize
);
276 aPrinter
.getArray()[6].Name
= "CanSetPaperFormat";
277 aPrinter
.getArray()[6].Value
<<= pPrinter
->HasSupport( PrinterSupport::SetPaper
);
279 aPrinter
.getArray()[5].Name
= "CanSetPaperOrientation";
280 aPrinter
.getArray()[5].Value
<<= pPrinter
->HasSupport( PrinterSupport::SetOrientation
);
282 aPrinter
.getArray()[4].Name
= "IsBusy";
283 aPrinter
.getArray()[4].Value
<<= pPrinter
->IsPrinting();
285 aPrinter
.getArray()[3].Name
= "PaperSize";
286 awt::Size aSize
= impl_Size_Object2Struct(pPrinter
->GetPaperSize() );
287 aPrinter
.getArray()[3].Value
<<= aSize
;
289 aPrinter
.getArray()[2].Name
= "PaperFormat";
290 view::PaperFormat eFormat
= convertToPaperFormat(pPrinter
->GetPaper());
291 aPrinter
.getArray()[2].Value
<<= eFormat
;
293 aPrinter
.getArray()[1].Name
= "PaperOrientation";
294 view::PaperOrientation eOrient
= static_cast<view::PaperOrientation
>(pPrinter
->GetOrientation());
295 aPrinter
.getArray()[1].Value
<<= eOrient
;
297 aPrinter
.getArray()[0].Name
= "Name";
298 OUString sStringTemp
= pPrinter
->GetName() ;
299 aPrinter
.getArray()[0].Value
<<= sStringTemp
;
308 void SfxPrintHelper::impl_setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
,
309 VclPtr
<SfxPrinter
>& pPrinter
,
310 SfxPrinterChangeFlags
& nChangeFlags
,
311 SfxViewShell
*& pViewSh
)
315 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ?
316 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
320 pViewSh
= pViewFrm
->GetViewShell();
321 pPrinter
= pViewSh
->GetPrinter(true);
325 // new Printer-Name available?
326 nChangeFlags
= SfxPrinterChangeFlags::NONE
;
327 sal_Int32 lDummy
= 0;
328 auto pProp
= std::find_if(rPrinter
.begin(), rPrinter
.end(),
329 [](const beans::PropertyValue
&rProp
) { return rProp
.Name
== "Name"; });
330 if (pProp
!= rPrinter
.end())
332 OUString aPrinterName
;
333 if ( ! ( pProp
->Value
>>= aPrinterName
) )
334 throw css::lang::IllegalArgumentException();
336 if ( aPrinterName
!= pPrinter
->GetName() )
338 pPrinter
= VclPtr
<SfxPrinter
>::Create( pPrinter
->GetOptions().Clone(), aPrinterName
);
339 nChangeFlags
= SfxPrinterChangeFlags::PRINTER
;
343 Size
aSetPaperSize( 0, 0);
344 view::PaperFormat nPaperFormat
= view::PaperFormat_USER
;
347 for ( const beans::PropertyValue
&rProp
: rPrinter
)
349 // get Property-Value from printer description
350 // PaperOrientation-Property?
351 if ( rProp
.Name
== "PaperOrientation" )
353 view::PaperOrientation eOrient
;
354 if ( !( rProp
.Value
>>= eOrient
) )
356 if ( !( rProp
.Value
>>= lDummy
) )
357 throw css::lang::IllegalArgumentException();
358 eOrient
= static_cast<view::PaperOrientation
>(lDummy
);
361 if ( static_cast<Orientation
>(eOrient
) != pPrinter
->GetOrientation() )
363 pPrinter
->SetOrientation( static_cast<Orientation
>(eOrient
) );
364 nChangeFlags
|= SfxPrinterChangeFlags::CHG_ORIENTATION
;
368 // PaperFormat-Property?
369 else if ( rProp
.Name
== "PaperFormat" )
371 if ( !( rProp
.Value
>>= nPaperFormat
) )
373 if ( !( rProp
.Value
>>= lDummy
) )
374 throw css::lang::IllegalArgumentException();
375 nPaperFormat
= static_cast<view::PaperFormat
>(lDummy
);
378 if ( convertToPaper(nPaperFormat
) != pPrinter
->GetPaper() )
380 pPrinter
->SetPaper( convertToPaper(nPaperFormat
) );
381 nChangeFlags
|= SfxPrinterChangeFlags::CHG_SIZE
;
385 // PaperSize-Property?
386 else if ( rProp
.Name
== "PaperSize" )
388 awt::Size aTempSize
;
389 if ( !( rProp
.Value
>>= aTempSize
) )
391 throw css::lang::IllegalArgumentException();
393 aSetPaperSize
= impl_Size_Struct2Object(aTempSize
);
396 // PrinterTray-Property
397 else if ( rProp
.Name
== "PrinterPaperTray" )
400 if ( !( rProp
.Value
>>= aTmp
) )
401 throw css::lang::IllegalArgumentException();
402 const sal_uInt16 nCount
= pPrinter
->GetPaperBinCount();
403 for (sal_uInt16 nBin
=0; nBin
<nCount
; nBin
++)
405 OUString
aName( pPrinter
->GetPaperBinName(nBin
) );
408 pPrinter
->SetPaperBin(nBin
);
415 // The PaperSize may be set only when actually PAPER_USER
416 // applies, otherwise the driver could choose an invalid format.
417 if(nPaperFormat
== view::PaperFormat_USER
&& aSetPaperSize
.Width())
419 // Bug 56929 - MapMode of 100mm which recalculated when
420 // the device is set. Additionally only set if they were really changed.
421 aSetPaperSize
= pPrinter
->LogicToPixel(aSetPaperSize
, MapMode(MapUnit::Map100thMM
));
422 if( aSetPaperSize
!= pPrinter
->GetPaperSizePixel() )
424 pPrinter
->SetPaperSizeUser( pPrinter
->PixelToLogic( aSetPaperSize
) );
425 nChangeFlags
|= SfxPrinterChangeFlags::CHG_SIZE
;
429 //wait until printing is done
430 SfxPrinter
* pDocPrinter
= pViewSh
->GetPrinter();
431 while ( pDocPrinter
->IsPrinting() && !Application::IsQuit())
432 Application::Yield();
435 void SAL_CALL
SfxPrintHelper::setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
)
437 // object already disposed?
438 SolarMutexGuard aGuard
;
440 SfxViewShell
* pViewSh
= nullptr;
441 VclPtr
<SfxPrinter
> pPrinter
;
442 SfxPrinterChangeFlags nChangeFlags
= SfxPrinterChangeFlags::NONE
;
443 impl_setPrinter(rPrinter
,pPrinter
,nChangeFlags
,pViewSh
);
445 if ( pViewSh
&& pPrinter
)
446 pViewSh
->SetPrinter( pPrinter
, nChangeFlags
);
450 // ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
454 /* This implements a thread which will be started to wait for asynchronous
455 print jobs to temp. locally files. If they finish we move the temp. files
456 to their right locations by using the ucb.
458 class ImplUCBPrintWatcher
: public ::osl::Thread
461 /// of course we must know the printer which execute the job
462 VclPtr
<SfxPrinter
> m_pPrinter
;
463 /// this describes the target location for the printed temp file
464 OUString m_sTargetURL
;
465 /// it holds the temp file alive, till the print job will finish and remove it from disk automatically if the object die
466 ::utl::TempFile
* m_pTempFile
;
469 /* initialize this watcher but don't start it */
470 ImplUCBPrintWatcher( SfxPrinter
* pPrinter
, ::utl::TempFile
* pTempFile
, const OUString
& sTargetURL
)
471 : m_pPrinter ( pPrinter
)
472 , m_sTargetURL( sTargetURL
)
473 , m_pTempFile ( pTempFile
)
476 /* waits for finishing of the print job and moves the temp file afterwards
477 Note: Starting of the job is done outside this thread!
478 But we have to free some of the given resources on heap!
480 void SAL_CALL
run() override
482 osl_setThreadName("ImplUCBPrintWatcher");
486 SolarMutexGuard aGuard
;
487 while( m_pPrinter
->IsPrinting() && !Application::IsQuit())
488 Application::Yield();
489 m_pPrinter
.clear(); // don't delete it! It's borrowed only :-)
493 // lock for further using of our member isn't necessary - because
494 // we run alone by definition. Nobody join for us nor use us...
495 moveAndDeleteTemp(&m_pTempFile
,m_sTargetURL
);
497 // finishing of this run() method will call onTerminate() automatically
498 // kill this thread there!
501 /* nobody wait for this thread. We must kill ourself ...
503 void SAL_CALL
onTerminated() override
508 /* static helper to move the temp. file to the target location by using the ucb
509 It's static to be usable from outside too. So it's not really necessary to start
510 the thread, if finishing of the job was detected outside this thread.
511 But it must be called without using a corresponding thread for the given parameter!
513 static void moveAndDeleteTemp( ::utl::TempFile
** ppTempFile
, const OUString
& sTargetURL
)
518 INetURLObject
aSplitter(sTargetURL
);
519 OUString sFileName
= aSplitter
.getName(
520 INetURLObject::LAST_SEGMENT
,
522 INetURLObject::DecodeMechanism::WithCharset
);
523 if (aSplitter
.removeSegment() && !sFileName
.isEmpty())
525 ::ucbhelper::Content
aSource(
526 (*ppTempFile
)->GetURL(),
527 css::uno::Reference
< css::ucb::XCommandEnvironment
>(),
528 comphelper::getProcessComponentContext());
530 ::ucbhelper::Content
aTarget(
531 aSplitter
.GetMainURL(INetURLObject::DecodeMechanism::NONE
),
532 css::uno::Reference
< css::ucb::XCommandEnvironment
>(),
533 comphelper::getProcessComponentContext());
535 aTarget
.transferContent(
537 ::ucbhelper::InsertOperation::Copy
,
539 css::ucb::NameClash::OVERWRITE
);
542 catch (const css::uno::Exception
&)
544 TOOLS_WARN_EXCEPTION( "sfx.doc", "");
547 // kill the temp file!
549 *ppTempFile
= nullptr;
557 void SAL_CALL
SfxPrintHelper::print(const uno::Sequence
< beans::PropertyValue
>& rOptions
)
559 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
562 // object already disposed?
563 // object already disposed?
564 SolarMutexGuard aGuard
;
566 // get view for sfx printing capabilities
567 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ?
568 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
571 SfxViewShell
* pView
= pViewFrm
->GetViewShell();
574 bool bMonitor
= false;
575 // We need this information at the end of this method, if we start the vcl printer
576 // by executing the slot. Because if it is a ucb relevant URL we must wait for
577 // finishing the print job and move the temporary local file by using the ucb
578 // to the right location. But in case of no file name is given or it is already
579 // a local one we can suppress this special handling. Because then vcl makes all
582 ::utl::TempFile
* pUCBPrintTempFile
= nullptr;
584 uno::Sequence
< beans::PropertyValue
> aCheckedArgs( rOptions
.getLength() );
585 auto pCheckedArgs
= aCheckedArgs
.getArray();
586 sal_Int32 nProps
= 0;
587 bool bWaitUntilEnd
= false;
588 sal_Int16 nDuplexMode
= css::view::DuplexMode::UNKNOWN
;
589 for ( const beans::PropertyValue
&rProp
: rOptions
)
591 // get Property-Value from options
592 // FileName-Property?
593 if ( rProp
.Name
== "FileName" )
595 // unpack th URL and check for a valid and well known protocol
598 ( rProp
.Value
.getValueType()!=cppu::UnoType
<OUString
>::get()) ||
599 (!(rProp
.Value
>>=sTemp
))
602 throw css::lang::IllegalArgumentException();
606 OUString
sURL (sTemp
);
607 INetURLObject
aCheck(sURL
);
608 if (aCheck
.GetProtocol()==INetProtocol::NotValid
)
610 // OK - it's not a valid URL. But may it's a simple
611 // system path directly. It will be supported for historical
612 // reasons. Otherwise we break too much external code...
613 // We try to convert it to a file URL. If it's possible
614 // we put the system path to the item set and let vcl work with it.
615 // No ucb or thread will be necessary then. In case it couldn't be
616 // converted it's not a URL nor a system path. Then we can't accept
617 // this parameter and have to throw an exception.
618 const OUString
& sSystemPath(sTemp
);
620 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath
,sFileURL
)!=::osl::FileBase::E_None
)
621 throw css::lang::IllegalArgumentException();
622 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
623 pCheckedArgs
[nProps
++].Value
<<= sFileURL
;
624 // and append the local filename
625 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
626 pCheckedArgs
= aCheckedArgs
.getArray();
627 pCheckedArgs
[nProps
].Name
= "LocalFileName";
628 pCheckedArgs
[nProps
++].Value
<<= sTemp
;
631 // It's a valid URL. but now we must know, if it is a local one or not.
632 // It's a question of using ucb or not!
633 if (osl::FileBase::getSystemPathFromFileURL(sURL
, sPath
) == osl::FileBase::E_None
)
635 // it's a local file, we can use vcl without special handling
636 // And we have to use the system notation of the incoming URL.
637 // But it into the descriptor and let the slot be executed at
638 // the end of this method.
639 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
640 pCheckedArgs
[nProps
++].Value
<<= sTemp
;
641 // and append the local filename
642 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
643 pCheckedArgs
= aCheckedArgs
.getArray();
644 pCheckedArgs
[nProps
].Name
= "LocalFileName";
645 pCheckedArgs
[nProps
++].Value
<<= sPath
;
649 // it's a ucb target. So we must use a temp. file for vcl
650 // and move it after printing by using the ucb.
651 // Create a temp file on the heap (because it must delete the
652 // real file on disk automatically if it die - bt we have to share it with
653 // some other sources ... e.g. the ImplUCBPrintWatcher).
654 // And we put the name of this temp file to the descriptor instead
655 // of the URL. The URL we save for later using separately.
656 // Execution of the print job will be done later by executing
658 if(!pUCBPrintTempFile
)
659 pUCBPrintTempFile
= new ::utl::TempFile();
660 pUCBPrintTempFile
->EnableKillingFile();
662 //FIXME: does it work?
663 pCheckedArgs
[nProps
].Name
= "LocalFileName";
664 pCheckedArgs
[nProps
++].Value
<<= pUCBPrintTempFile
->GetFileName();
669 // CopyCount-Property
670 else if ( rProp
.Name
== "CopyCount" )
672 sal_Int32 nCopies
= 0;
673 if ( !( rProp
.Value
>>= nCopies
) )
674 throw css::lang::IllegalArgumentException();
675 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
676 pCheckedArgs
[nProps
++].Value
<<= nCopies
;
680 // Sort-Property (deprecated)
681 else if ( rProp
.Name
== "Collate" || rProp
.Name
== "Sort" )
684 if ( !(rProp
.Value
>>= bTemp
) )
685 throw css::lang::IllegalArgumentException();
686 pCheckedArgs
[nProps
].Name
= "Collate";
687 pCheckedArgs
[nProps
++].Value
<<= bTemp
;
690 else if ( rProp
.Name
== "SinglePrintJobs" )
693 if ( !(rProp
.Value
>>= bTemp
) )
694 throw css::lang::IllegalArgumentException();
695 pCheckedArgs
[nProps
].Name
= "SinglePrintJobs";
696 pCheckedArgs
[nProps
++].Value
<<= bTemp
;
700 else if ( rProp
.Name
== "Pages" )
703 if( !(rProp
.Value
>>= sTemp
) )
704 throw css::lang::IllegalArgumentException();
705 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
706 pCheckedArgs
[nProps
++].Value
<<= sTemp
;
710 else if ( rProp
.Name
== "MonitorVisible" )
712 if( !(rProp
.Value
>>= bMonitor
) )
713 throw css::lang::IllegalArgumentException();
714 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
715 pCheckedArgs
[nProps
++].Value
<<= bMonitor
;
719 else if ( rProp
.Name
== "Wait" )
721 if ( !(rProp
.Value
>>= bWaitUntilEnd
) )
722 throw css::lang::IllegalArgumentException();
723 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
724 pCheckedArgs
[nProps
++].Value
<<= bWaitUntilEnd
;
727 else if ( rProp
.Name
== "DuplexMode" )
729 if ( !(rProp
.Value
>>= nDuplexMode
) )
730 throw css::lang::IllegalArgumentException();
731 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
732 pCheckedArgs
[nProps
++].Value
<<= nDuplexMode
;
736 if ( nProps
!= aCheckedArgs
.getLength() )
737 aCheckedArgs
.realloc(nProps
);
739 // Execute the print request every time.
740 // It doesn't matter if it is a real printer used or we print to a local file
741 // nor if we print to a temp file and move it afterwards by using the ucb.
742 // That will be handled later. see pUCBPrintFile below!
743 pView
->ExecPrint( aCheckedArgs
, true, false );
745 // Ok - may be execution before has finished (or started!) printing.
746 // And may it was a printing to a file.
747 // Now we have to check if we can move the file (if necessary) via UCB to its right location.
749 // a) printing finished => move the file directly and forget the watcher thread
750 // b) printing is asynchron and runs currently => start watcher thread and exit this method
751 // This thread make all necessary things by itself.
752 if (!pUCBPrintTempFile
)
756 SfxPrinter
* pPrinter
= pView
->GetPrinter();
757 if ( ! pPrinter
->IsPrinting() )
758 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile
,sUcbUrl
);
762 // Note: we create(d) some resource on the heap (thread and temp file).
763 // They will be deleted by the thread automatically if it finishes its run() method.
764 ImplUCBPrintWatcher
* pWatcher
= new ImplUCBPrintWatcher( pPrinter
, pUCBPrintTempFile
, sUcbUrl
);
769 void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
771 const SfxPrintingHint
* pPrintHint
= dynamic_cast<const SfxPrintingHint
*>(&rHint
);
772 if ( &rBC
!= m_pObjectShell
.get()
774 || pPrintHint
->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB
)
777 if ( pPrintHint
->GetWhich() == css::view::PrintableState_JOB_STARTED
)
779 if ( !m_xPrintJob
.is() )
780 m_xPrintJob
= new SfxPrintJob_Impl( this );
781 m_aPrintOptions
= pPrintHint
->GetOptions();
784 comphelper::OInterfaceContainerHelper2
* pContainer
= m_aInterfaceContainer
.getContainer(
785 cppu::UnoType
<view::XPrintJobListener
>::get());
789 view::PrintJobEvent aEvent
;
790 aEvent
.Source
= m_xPrintJob
;
791 aEvent
.State
= pPrintHint
->GetWhich();
793 comphelper::OInterfaceIteratorHelper2
pIterator(*pContainer
);
794 while (pIterator
.hasMoreElements())
795 static_cast<view::XPrintJobListener
*>(pIterator
.next())->printJobEvent( aEvent
);
798 void SAL_CALL
SfxPrintHelper::addPrintJobListener( const css::uno::Reference
< css::view::XPrintJobListener
>& xListener
)
800 SolarMutexGuard aGuard
;
801 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<view::XPrintJobListener
>::get(), xListener
);
804 void SAL_CALL
SfxPrintHelper::removePrintJobListener( const css::uno::Reference
< css::view::XPrintJobListener
>& xListener
)
806 SolarMutexGuard aGuard
;
807 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<view::XPrintJobListener
>::get(), xListener
);
811 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */