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/lang/XUnoTunnel.hpp>
32 #include <com/sun/star/frame/XModel.hpp>
33 #include <com/sun/star/view/DuplexMode.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <svl/itemset.hxx>
36 #include <svl/lstner.hxx>
37 #include <unotools/tempfile.hxx>
38 #include <osl/file.hxx>
39 #include <osl/thread.hxx>
40 #include <tools/urlobj.hxx>
41 #include <ucbhelper/content.hxx>
42 #include <cppuhelper/interfacecontainer.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 ::cppu::OMultiTypeInterfaceContainerHelper 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() )
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() )
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::ucb::ContentCreationException
&)
544 OSL_FAIL("content create exception");
546 catch (const css::ucb::CommandAbortedException
&)
548 OSL_FAIL("command abort exception");
550 catch (const css::uno::RuntimeException
&)
552 OSL_FAIL("runtime exception");
554 catch (const css::uno::Exception
&)
556 OSL_FAIL("unknown exception");
559 // kill the temp file!
561 *ppTempFile
= nullptr;
569 void SAL_CALL
SfxPrintHelper::print(const uno::Sequence
< beans::PropertyValue
>& rOptions
)
571 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
574 // object already disposed?
575 // object already disposed?
576 SolarMutexGuard aGuard
;
578 // get view for sfx printing capabilities
579 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ?
580 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
583 SfxViewShell
* pView
= pViewFrm
->GetViewShell();
586 bool bMonitor
= false;
587 // We need this information at the end of this method, if we start the vcl printer
588 // by executing the slot. Because if it is a ucb relevant URL we must wait for
589 // finishing the print job and move the temporary local file by using the ucb
590 // to the right location. But in case of no file name is given or it is already
591 // a local one we can suppress this special handling. Because then vcl makes all
594 ::utl::TempFile
* pUCBPrintTempFile
= nullptr;
596 uno::Sequence
< beans::PropertyValue
> aCheckedArgs( rOptions
.getLength() );
597 sal_Int32 nProps
= 0;
598 bool bWaitUntilEnd
= false;
599 sal_Int16 nDuplexMode
= css::view::DuplexMode::UNKNOWN
;
600 for ( const beans::PropertyValue
&rProp
: rOptions
)
602 // get Property-Value from options
603 // FileName-Property?
604 if ( rProp
.Name
== "FileName" )
606 // unpack th URL and check for a valid and well known protocol
609 ( rProp
.Value
.getValueType()!=cppu::UnoType
<OUString
>::get()) ||
610 (!(rProp
.Value
>>=sTemp
))
613 throw css::lang::IllegalArgumentException();
617 OUString
sURL (sTemp
);
618 INetURLObject
aCheck(sURL
);
619 if (aCheck
.GetProtocol()==INetProtocol::NotValid
)
621 // OK - it's not a valid URL. But may it's a simple
622 // system path directly. It will be supported for historical
623 // reasons. Otherwise we break too much external code...
624 // We try to convert it to a file URL. If it's possible
625 // we put the system path to the item set and let vcl work with it.
626 // No ucb or thread will be necessary then. In case it couldn't be
627 // converted it's not a URL nor a system path. Then we can't accept
628 // this parameter and have to throw an exception.
629 const OUString
& sSystemPath(sTemp
);
631 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath
,sFileURL
)!=::osl::FileBase::E_None
)
632 throw css::lang::IllegalArgumentException();
633 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
634 aCheckedArgs
[nProps
++].Value
<<= sFileURL
;
635 // and append the local filename
636 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
637 aCheckedArgs
[nProps
].Name
= "LocalFileName";
638 aCheckedArgs
[nProps
++].Value
<<= sTemp
;
641 // It's a valid URL. but now we must know, if it is a local one or not.
642 // It's a question of using ucb or not!
643 if (osl::FileBase::getSystemPathFromFileURL(sURL
, sPath
) == osl::FileBase::E_None
)
645 // it's a local file, we can use vcl without special handling
646 // And we have to use the system notation of the incoming URL.
647 // But it into the descriptor and let the slot be executed at
648 // the end of this method.
649 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
650 aCheckedArgs
[nProps
++].Value
<<= sTemp
;
651 // and append the local filename
652 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
653 aCheckedArgs
[nProps
].Name
= "LocalFileName";
654 aCheckedArgs
[nProps
++].Value
<<= sPath
;
658 // it's a ucb target. So we must use a temp. file for vcl
659 // and move it after printing by using the ucb.
660 // Create a temp file on the heap (because it must delete the
661 // real file on disk automatically if it die - bt we have to share it with
662 // some other sources ... e.g. the ImplUCBPrintWatcher).
663 // And we put the name of this temp file to the descriptor instead
664 // of the URL. The URL we save for later using separately.
665 // Execution of the print job will be done later by executing
667 if(!pUCBPrintTempFile
)
668 pUCBPrintTempFile
= new ::utl::TempFile();
669 pUCBPrintTempFile
->EnableKillingFile();
671 //FIXME: does it work?
672 aCheckedArgs
[nProps
].Name
= "LocalFileName";
673 aCheckedArgs
[nProps
++].Value
<<= pUCBPrintTempFile
->GetFileName();
678 // CopyCount-Property
679 else if ( rProp
.Name
== "CopyCount" )
681 sal_Int32 nCopies
= 0;
682 if ( !( rProp
.Value
>>= nCopies
) )
683 throw css::lang::IllegalArgumentException();
684 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
685 aCheckedArgs
[nProps
++].Value
<<= nCopies
;
689 // Sort-Property (deprecated)
690 else if ( rProp
.Name
== "Collate" || rProp
.Name
== "Sort" )
693 if ( !(rProp
.Value
>>= bTemp
) )
694 throw css::lang::IllegalArgumentException();
695 aCheckedArgs
[nProps
].Name
= "Collate";
696 aCheckedArgs
[nProps
++].Value
<<= bTemp
;
699 else if ( rProp
.Name
== "SinglePrintJobs" )
702 if ( !(rProp
.Value
>>= bTemp
) )
703 throw css::lang::IllegalArgumentException();
704 aCheckedArgs
[nProps
].Name
= "SinglePrintJobs";
705 aCheckedArgs
[nProps
++].Value
<<= bTemp
;
709 else if ( rProp
.Name
== "Pages" )
712 if( !(rProp
.Value
>>= sTemp
) )
713 throw css::lang::IllegalArgumentException();
714 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
715 aCheckedArgs
[nProps
++].Value
<<= sTemp
;
719 else if ( rProp
.Name
== "MonitorVisible" )
721 if( !(rProp
.Value
>>= bMonitor
) )
722 throw css::lang::IllegalArgumentException();
723 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
724 aCheckedArgs
[nProps
++].Value
<<= bMonitor
;
728 else if ( rProp
.Name
== "Wait" )
730 if ( !(rProp
.Value
>>= bWaitUntilEnd
) )
731 throw css::lang::IllegalArgumentException();
732 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
733 aCheckedArgs
[nProps
++].Value
<<= bWaitUntilEnd
;
736 else if ( rProp
.Name
== "DuplexMode" )
738 if ( !(rProp
.Value
>>= nDuplexMode
) )
739 throw css::lang::IllegalArgumentException();
740 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
741 aCheckedArgs
[nProps
++].Value
<<= nDuplexMode
;
745 if ( nProps
!= aCheckedArgs
.getLength() )
746 aCheckedArgs
.realloc(nProps
);
748 // Execute the print request every time.
749 // It doesn't matter if it is a real printer used or we print to a local file
750 // nor if we print to a temp file and move it afterwards by using the ucb.
751 // That will be handled later. see pUCBPrintFile below!
752 pView
->ExecPrint( aCheckedArgs
, true, false );
754 // Ok - may be execution before has finished (or started!) printing.
755 // And may it was a printing to a file.
756 // Now we have to check if we can move the file (if necessary) via UCB to its right location.
758 // a) printing finished => move the file directly and forget the watcher thread
759 // b) printing is asynchron and runs currently => start watcher thread and exit this method
760 // This thread make all necessary things by itself.
761 if (!pUCBPrintTempFile
)
765 SfxPrinter
* pPrinter
= pView
->GetPrinter();
766 if ( ! pPrinter
->IsPrinting() )
767 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile
,sUcbUrl
);
771 // Note: we create(d) some resource on the heap (thread and temp file).
772 // They will be deleted by the thread automatically if it finishes its run() method.
773 ImplUCBPrintWatcher
* pWatcher
= new ImplUCBPrintWatcher( pPrinter
, pUCBPrintTempFile
, sUcbUrl
);
778 void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
780 const SfxPrintingHint
* pPrintHint
= dynamic_cast<const SfxPrintingHint
*>(&rHint
);
781 if ( &rBC
!= m_pObjectShell
.get()
783 || pPrintHint
->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB
)
786 if ( pPrintHint
->GetWhich() == css::view::PrintableState_JOB_STARTED
)
788 if ( !m_xPrintJob
.is() )
789 m_xPrintJob
= new SfxPrintJob_Impl( this );
790 m_aPrintOptions
= pPrintHint
->GetOptions();
793 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aInterfaceContainer
.getContainer(
794 cppu::UnoType
<view::XPrintJobListener
>::get());
798 view::PrintJobEvent aEvent
;
799 aEvent
.Source
= m_xPrintJob
;
800 aEvent
.State
= pPrintHint
->GetWhich();
802 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
803 while (pIterator
.hasMoreElements())
804 static_cast<view::XPrintJobListener
*>(pIterator
.next())->printJobEvent( aEvent
);
807 void SAL_CALL
SfxPrintHelper::addPrintJobListener( const css::uno::Reference
< css::view::XPrintJobListener
>& xListener
)
809 SolarMutexGuard aGuard
;
810 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<view::XPrintJobListener
>::get(), xListener
);
813 void SAL_CALL
SfxPrintHelper::removePrintJobListener( const css::uno::Reference
< css::view::XPrintJobListener
>& xListener
)
815 SolarMutexGuard aGuard
;
816 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<view::XPrintJobListener
>::get(), xListener
);
820 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */