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/frame/XModel.hpp>
30 #include <com/sun/star/view/DuplexMode.hpp>
31 #include <comphelper/processfactory.hxx>
32 #include <comphelper/propertyvalue.hxx>
33 #include <svl/itemset.hxx>
34 #include <svl/lstner.hxx>
35 #include <unotools/tempfile.hxx>
36 #include <osl/file.hxx>
37 #include <osl/thread.hxx>
38 #include <tools/urlobj.hxx>
39 #include <comphelper/diagnose_ex.hxx>
40 #include <ucbhelper/content.hxx>
41 #include <comphelper/interfacecontainer4.hxx>
42 #include <cppuhelper/implbase.hxx>
44 #include <vcl/settings.hxx>
45 #include <vcl/svapp.hxx>
47 #include <sfx2/viewfrm.hxx>
48 #include <sfx2/viewsh.hxx>
49 #include <sfx2/printer.hxx>
50 #include <sfx2/objsh.hxx>
51 #include <sfx2/event.hxx>
53 #define SFX_PRINTABLESTATE_CANCELJOB css::view::PrintableState(-2)
55 using namespace ::com::sun::star
;
56 using namespace ::com::sun::star::uno
;
58 struct IMPL_PrintListener_DataContainer
: public SfxListener
60 SfxObjectShellRef m_pObjectShell
;
62 comphelper::OInterfaceContainerHelper4
<view::XPrintJobListener
> m_aJobListeners
;
63 uno::Reference
< css::view::XPrintJob
> m_xPrintJob
;
64 css::uno::Sequence
< css::beans::PropertyValue
> m_aPrintOptions
;
66 explicit IMPL_PrintListener_DataContainer()
71 void Notify( SfxBroadcaster
& aBC
,
72 const SfxHint
& aHint
) override
;
75 static awt::Size
impl_Size_Object2Struct( const Size
& aSize
)
77 awt::Size aReturnValue
;
78 aReturnValue
.Width
= aSize
.Width() ;
79 aReturnValue
.Height
= aSize
.Height() ;
83 static Size
impl_Size_Struct2Object( const awt::Size
& aSize
)
86 aReturnValue
.setWidth( aSize
.Width
) ;
87 aReturnValue
.setHeight( aSize
.Height
) ;
93 class SfxPrintJob_Impl
: public cppu::WeakImplHelper
98 IMPL_PrintListener_DataContainer
* m_pData
;
101 explicit SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
);
102 virtual Sequence
< css::beans::PropertyValue
> SAL_CALL
getPrintOptions( ) override
;
103 virtual Sequence
< css::beans::PropertyValue
> SAL_CALL
getPrinter( ) override
;
104 virtual Reference
< css::view::XPrintable
> SAL_CALL
getPrintable( ) override
;
105 virtual void SAL_CALL
cancelJob() override
;
110 SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
)
115 Sequence
< css::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrintOptions()
117 return m_pData
->m_aPrintOptions
;
120 Sequence
< css::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrinter()
122 if( m_pData
->m_pObjectShell
.is() )
124 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
->GetModel(), UNO_QUERY
);
125 if ( xPrintable
.is() )
126 return xPrintable
->getPrinter();
128 return Sequence
< css::beans::PropertyValue
>();
131 Reference
< css::view::XPrintable
> SAL_CALL
SfxPrintJob_Impl::getPrintable()
133 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
.is() ? m_pData
->m_pObjectShell
->GetModel() : nullptr, UNO_QUERY
);
137 void SAL_CALL
SfxPrintJob_Impl::cancelJob()
139 // FIXME: how to cancel PrintJob via API?!
140 if( m_pData
->m_pObjectShell
.is() )
141 m_pData
->m_pObjectShell
->Broadcast( SfxPrintingHint( SFX_PRINTABLESTATE_CANCELJOB
) );
144 SfxPrintHelper::SfxPrintHelper()
146 m_pData
.reset(new IMPL_PrintListener_DataContainer());
149 void SAL_CALL
SfxPrintHelper::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
151 if ( !aArguments
.hasElements() )
154 css::uno::Reference
< css::frame::XModel
> xModel
;
155 aArguments
[0] >>= xModel
;
156 m_pData
->m_pObjectShell
= SfxObjectShell::GetShellFromComponent(xModel
);
157 if (m_pData
->m_pObjectShell
)
158 m_pData
->StartListening(*m_pData
->m_pObjectShell
);
161 SfxPrintHelper::~SfxPrintHelper()
167 view::PaperFormat
convertToPaperFormat(Paper eFormat
)
169 view::PaperFormat eRet
;
173 eRet
= view::PaperFormat_A3
;
176 eRet
= view::PaperFormat_A4
;
179 eRet
= view::PaperFormat_A5
;
182 eRet
= view::PaperFormat_B4
;
185 eRet
= view::PaperFormat_B5
;
188 eRet
= view::PaperFormat_LETTER
;
191 eRet
= view::PaperFormat_LEGAL
;
194 eRet
= view::PaperFormat_TABLOID
;
198 eRet
= view::PaperFormat_USER
;
204 Paper
convertToPaper(view::PaperFormat eFormat
)
206 Paper
eRet(PAPER_USER
);
209 case view::PaperFormat_A3
:
212 case view::PaperFormat_A4
:
215 case view::PaperFormat_A5
:
218 case view::PaperFormat_B4
:
221 case view::PaperFormat_B5
:
224 case view::PaperFormat_LETTER
:
227 case view::PaperFormat_LEGAL
:
230 case view::PaperFormat_TABLOID
:
231 eRet
= PAPER_TABLOID
;
233 case view::PaperFormat_USER
:
236 case view::PaperFormat::PaperFormat_MAKE_FIXED_SIZE
:
238 //deliberate no default to force warn on a new papersize
248 uno::Sequence
< beans::PropertyValue
> SAL_CALL
SfxPrintHelper::getPrinter()
250 // object already disposed?
251 SolarMutexGuard aGuard
;
253 // search for any view of this document that is currently printing
254 const Printer
*pPrinter
= nullptr;
255 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ? SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
256 SfxViewFrame
* pFirst
= pViewFrm
;
257 while ( pViewFrm
&& !pPrinter
)
259 pPrinter
= pViewFrm
->GetViewShell()->GetActivePrinter();
260 pViewFrm
= SfxViewFrame::GetNext( *pViewFrm
, m_pData
->m_pObjectShell
.get(), false );
263 // if no view is printing currently, use the permanent SfxPrinter instance
264 if ( !pPrinter
&& pFirst
)
265 pPrinter
= pFirst
->GetViewShell()->GetPrinter(true);
268 return uno::Sequence
< beans::PropertyValue
>();
272 comphelper::makePropertyValue("Name", pPrinter
->GetName()),
273 comphelper::makePropertyValue("PaperOrientation", static_cast<view::PaperOrientation
>(pPrinter
->GetOrientation())),
274 comphelper::makePropertyValue("PaperFormat", convertToPaperFormat(pPrinter
->GetPaper())),
275 comphelper::makePropertyValue("PaperSize", impl_Size_Object2Struct(pPrinter
->GetPaperSize() )),
276 comphelper::makePropertyValue("IsBusy", pPrinter
->IsPrinting()),
277 comphelper::makePropertyValue("CanSetPaperOrientation", pPrinter
->HasSupport( PrinterSupport::SetOrientation
)),
278 comphelper::makePropertyValue("CanSetPaperFormat", pPrinter
->HasSupport( PrinterSupport::SetPaper
)),
279 comphelper::makePropertyValue("CanSetPaperSize", pPrinter
->HasSupport( PrinterSupport::SetPaperSize
))
287 void SfxPrintHelper::impl_setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
,
288 VclPtr
<SfxPrinter
>& pPrinter
,
289 SfxPrinterChangeFlags
& nChangeFlags
,
290 SfxViewShell
*& pViewSh
)
294 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ?
295 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
299 pViewSh
= pViewFrm
->GetViewShell();
300 pPrinter
= pViewSh
->GetPrinter(true);
304 // new Printer-Name available?
305 nChangeFlags
= SfxPrinterChangeFlags::NONE
;
306 sal_Int32 lDummy
= 0;
307 auto pProp
= std::find_if(rPrinter
.begin(), rPrinter
.end(),
308 [](const beans::PropertyValue
&rProp
) { return rProp
.Name
== "Name"; });
309 if (pProp
!= rPrinter
.end())
311 OUString aPrinterName
;
312 if ( ! ( pProp
->Value
>>= aPrinterName
) )
313 throw css::lang::IllegalArgumentException();
315 if ( aPrinterName
!= pPrinter
->GetName() )
317 pPrinter
= VclPtr
<SfxPrinter
>::Create( pPrinter
->GetOptions().Clone(), aPrinterName
);
318 nChangeFlags
= SfxPrinterChangeFlags::PRINTER
;
322 Size
aSetPaperSize( 0, 0);
323 view::PaperFormat nPaperFormat
= view::PaperFormat_USER
;
326 for ( const beans::PropertyValue
&rProp
: rPrinter
)
328 // get Property-Value from printer description
329 // PaperOrientation-Property?
330 if ( rProp
.Name
== "PaperOrientation" )
332 view::PaperOrientation eOrient
;
333 if ( !( rProp
.Value
>>= eOrient
) )
335 if ( !( rProp
.Value
>>= lDummy
) )
336 throw css::lang::IllegalArgumentException();
337 eOrient
= static_cast<view::PaperOrientation
>(lDummy
);
340 if ( static_cast<Orientation
>(eOrient
) != pPrinter
->GetOrientation() )
342 pPrinter
->SetOrientation( static_cast<Orientation
>(eOrient
) );
343 nChangeFlags
|= SfxPrinterChangeFlags::CHG_ORIENTATION
;
347 // PaperFormat-Property?
348 else if ( rProp
.Name
== "PaperFormat" )
350 if ( !( rProp
.Value
>>= nPaperFormat
) )
352 if ( !( rProp
.Value
>>= lDummy
) )
353 throw css::lang::IllegalArgumentException();
354 nPaperFormat
= static_cast<view::PaperFormat
>(lDummy
);
357 if ( convertToPaper(nPaperFormat
) != pPrinter
->GetPaper() )
359 pPrinter
->SetPaper( convertToPaper(nPaperFormat
) );
360 nChangeFlags
|= SfxPrinterChangeFlags::CHG_SIZE
;
364 // PaperSize-Property?
365 else if ( rProp
.Name
== "PaperSize" )
367 awt::Size aTempSize
;
368 if ( !( rProp
.Value
>>= aTempSize
) )
370 throw css::lang::IllegalArgumentException();
372 aSetPaperSize
= impl_Size_Struct2Object(aTempSize
);
375 // PrinterTray-Property
376 else if ( rProp
.Name
== "PrinterPaperTray" )
379 if ( !( rProp
.Value
>>= aTmp
) )
380 throw css::lang::IllegalArgumentException();
381 const sal_uInt16 nCount
= pPrinter
->GetPaperBinCount();
382 for (sal_uInt16 nBin
=0; nBin
<nCount
; nBin
++)
384 OUString
aName( pPrinter
->GetPaperBinName(nBin
) );
387 pPrinter
->SetPaperBin(nBin
);
394 // The PaperSize may be set only when actually PAPER_USER
395 // applies, otherwise the driver could choose an invalid format.
396 if(nPaperFormat
== view::PaperFormat_USER
&& aSetPaperSize
.Width())
398 // Bug 56929 - MapMode of 100mm which recalculated when
399 // the device is set. Additionally only set if they were really changed.
400 aSetPaperSize
= pPrinter
->LogicToPixel(aSetPaperSize
, MapMode(MapUnit::Map100thMM
));
401 if( aSetPaperSize
!= pPrinter
->GetPaperSizePixel() )
403 pPrinter
->SetPaperSizeUser( pPrinter
->PixelToLogic( aSetPaperSize
) );
404 nChangeFlags
|= SfxPrinterChangeFlags::CHG_SIZE
;
408 //wait until printing is done
409 SfxPrinter
* pDocPrinter
= pViewSh
->GetPrinter();
410 while ( pDocPrinter
->IsPrinting() && !Application::IsQuit())
411 Application::Yield();
414 void SAL_CALL
SfxPrintHelper::setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
)
416 // object already disposed?
417 SolarMutexGuard aGuard
;
419 SfxViewShell
* pViewSh
= nullptr;
420 VclPtr
<SfxPrinter
> pPrinter
;
421 SfxPrinterChangeFlags nChangeFlags
= SfxPrinterChangeFlags::NONE
;
422 impl_setPrinter(rPrinter
,pPrinter
,nChangeFlags
,pViewSh
);
424 if ( pViewSh
&& pPrinter
)
425 pViewSh
->SetPrinter( pPrinter
, nChangeFlags
);
429 // ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
433 /* This implements a thread which will be started to wait for asynchronous
434 print jobs to temp. locally files. If they finish we move the temp. files
435 to their right locations by using the ucb.
437 class ImplUCBPrintWatcher
: public ::osl::Thread
440 /// of course we must know the printer which execute the job
441 VclPtr
<SfxPrinter
> m_pPrinter
;
442 /// this describes the target location for the printed temp file
443 OUString m_sTargetURL
;
444 /// it holds the temp file alive, till the print job will finish and remove it from disk automatically if the object die
445 ::utl::TempFileNamed
* m_pTempFile
;
448 /* initialize this watcher but don't start it */
449 ImplUCBPrintWatcher( SfxPrinter
* pPrinter
, ::utl::TempFileNamed
* pTempFile
, OUString sTargetURL
)
450 : m_pPrinter ( pPrinter
)
451 , m_sTargetURL(std::move( sTargetURL
))
452 , m_pTempFile ( pTempFile
)
455 /* waits for finishing of the print job and moves the temp file afterwards
456 Note: Starting of the job is done outside this thread!
457 But we have to free some of the given resources on heap!
459 void SAL_CALL
run() override
461 osl_setThreadName("ImplUCBPrintWatcher");
465 SolarMutexGuard aGuard
;
466 while( m_pPrinter
->IsPrinting() && !Application::IsQuit())
467 Application::Yield();
468 m_pPrinter
.clear(); // don't delete it! It's borrowed only :-)
472 // lock for further using of our member isn't necessary - because
473 // we run alone by definition. Nobody join for us nor use us...
474 moveAndDeleteTemp(&m_pTempFile
,m_sTargetURL
);
476 // finishing of this run() method will call onTerminate() automatically
477 // kill this thread there!
480 /* nobody wait for this thread. We must kill ourself ...
482 void SAL_CALL
onTerminated() override
487 /* static helper to move the temp. file to the target location by using the ucb
488 It's static to be usable from outside too. So it's not really necessary to start
489 the thread, if finishing of the job was detected outside this thread.
490 But it must be called without using a corresponding thread for the given parameter!
492 static void moveAndDeleteTemp( ::utl::TempFileNamed
** ppTempFile
, std::u16string_view sTargetURL
)
497 INetURLObject
aSplitter(sTargetURL
);
498 OUString sFileName
= aSplitter
.getName(
499 INetURLObject::LAST_SEGMENT
,
501 INetURLObject::DecodeMechanism::WithCharset
);
502 if (aSplitter
.removeSegment() && !sFileName
.isEmpty())
504 ::ucbhelper::Content
aSource(
505 (*ppTempFile
)->GetURL(),
506 css::uno::Reference
< css::ucb::XCommandEnvironment
>(),
507 comphelper::getProcessComponentContext());
509 ::ucbhelper::Content
aTarget(
510 aSplitter
.GetMainURL(INetURLObject::DecodeMechanism::NONE
),
511 css::uno::Reference
< css::ucb::XCommandEnvironment
>(),
512 comphelper::getProcessComponentContext());
514 aTarget
.transferContent(
516 ::ucbhelper::InsertOperation::Copy
,
518 css::ucb::NameClash::OVERWRITE
);
521 catch (const css::uno::Exception
&)
523 TOOLS_WARN_EXCEPTION( "sfx.doc", "");
526 // kill the temp file!
528 *ppTempFile
= nullptr;
536 void SAL_CALL
SfxPrintHelper::print(const uno::Sequence
< beans::PropertyValue
>& rOptions
)
538 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
541 // object already disposed?
542 // object already disposed?
543 SolarMutexGuard aGuard
;
545 // get view for sfx printing capabilities
546 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ?
547 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
550 SfxViewShell
* pView
= pViewFrm
->GetViewShell();
553 bool bMonitor
= false;
554 // We need this information at the end of this method, if we start the vcl printer
555 // by executing the slot. Because if it is a ucb relevant URL we must wait for
556 // finishing the print job and move the temporary local file by using the ucb
557 // to the right location. But in case of no file name is given or it is already
558 // a local one we can suppress this special handling. Because then vcl makes all
561 ::utl::TempFileNamed
* pUCBPrintTempFile
= nullptr;
563 uno::Sequence
< beans::PropertyValue
> aCheckedArgs( rOptions
.getLength() );
564 auto pCheckedArgs
= aCheckedArgs
.getArray();
565 sal_Int32 nProps
= 0;
566 bool bWaitUntilEnd
= false;
567 sal_Int16 nDuplexMode
= css::view::DuplexMode::UNKNOWN
;
568 for ( const beans::PropertyValue
&rProp
: rOptions
)
570 // get Property-Value from options
571 // FileName-Property?
572 if ( rProp
.Name
== "FileName" )
574 // unpack th URL and check for a valid and well known protocol
577 ( rProp
.Value
.getValueType()!=cppu::UnoType
<OUString
>::get()) ||
578 (!(rProp
.Value
>>=sTemp
))
581 throw css::lang::IllegalArgumentException();
585 OUString
sURL (sTemp
);
586 INetURLObject
aCheck(sURL
);
587 if (aCheck
.GetProtocol()==INetProtocol::NotValid
)
589 // OK - it's not a valid URL. But may it's a simple
590 // system path directly. It will be supported for historical
591 // reasons. Otherwise we break too much external code...
592 // We try to convert it to a file URL. If it's possible
593 // we put the system path to the item set and let vcl work with it.
594 // No ucb or thread will be necessary then. In case it couldn't be
595 // converted it's not a URL nor a system path. Then we can't accept
596 // this parameter and have to throw an exception.
597 const OUString
& sSystemPath(sTemp
);
599 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath
,sFileURL
)!=::osl::FileBase::E_None
)
600 throw css::lang::IllegalArgumentException();
601 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
602 pCheckedArgs
[nProps
++].Value
<<= sFileURL
;
603 // and append the local filename
604 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
605 pCheckedArgs
= aCheckedArgs
.getArray();
606 pCheckedArgs
[nProps
].Name
= "LocalFileName";
607 pCheckedArgs
[nProps
++].Value
<<= sTemp
;
610 // It's a valid URL. but now we must know, if it is a local one or not.
611 // It's a question of using ucb or not!
612 if (osl::FileBase::getSystemPathFromFileURL(sURL
, sPath
) == osl::FileBase::E_None
)
614 // it's a local file, we can use vcl without special handling
615 // And we have to use the system notation of the incoming URL.
616 // But it into the descriptor and let the slot be executed at
617 // the end of this method.
618 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
619 pCheckedArgs
[nProps
++].Value
<<= sTemp
;
620 // and append the local filename
621 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
622 pCheckedArgs
= aCheckedArgs
.getArray();
623 pCheckedArgs
[nProps
].Name
= "LocalFileName";
624 pCheckedArgs
[nProps
++].Value
<<= sPath
;
628 // it's a ucb target. So we must use a temp. file for vcl
629 // and move it after printing by using the ucb.
630 // Create a temp file on the heap (because it must delete the
631 // real file on disk automatically if it die - bt we have to share it with
632 // some other sources ... e.g. the ImplUCBPrintWatcher).
633 // And we put the name of this temp file to the descriptor instead
634 // of the URL. The URL we save for later using separately.
635 // Execution of the print job will be done later by executing
637 if(!pUCBPrintTempFile
)
638 pUCBPrintTempFile
= new ::utl::TempFileNamed();
639 pUCBPrintTempFile
->EnableKillingFile();
641 //FIXME: does it work?
642 pCheckedArgs
[nProps
].Name
= "LocalFileName";
643 pCheckedArgs
[nProps
++].Value
<<= pUCBPrintTempFile
->GetFileName();
648 // CopyCount-Property
649 else if ( rProp
.Name
== "CopyCount" )
651 sal_Int32 nCopies
= 0;
652 if ( !( rProp
.Value
>>= nCopies
) )
653 throw css::lang::IllegalArgumentException();
654 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
655 pCheckedArgs
[nProps
++].Value
<<= nCopies
;
659 // Sort-Property (deprecated)
660 else if ( rProp
.Name
== "Collate" || rProp
.Name
== "Sort" )
663 if ( !(rProp
.Value
>>= bTemp
) )
664 throw css::lang::IllegalArgumentException();
665 pCheckedArgs
[nProps
].Name
= "Collate";
666 pCheckedArgs
[nProps
++].Value
<<= bTemp
;
669 else if ( rProp
.Name
== "SinglePrintJobs" )
672 if ( !(rProp
.Value
>>= bTemp
) )
673 throw css::lang::IllegalArgumentException();
674 pCheckedArgs
[nProps
].Name
= "SinglePrintJobs";
675 pCheckedArgs
[nProps
++].Value
<<= bTemp
;
678 else if ( rProp
.Name
== "JobName" )
681 if( !(rProp
.Value
>>= sTemp
) )
682 throw css::lang::IllegalArgumentException();
683 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
684 pCheckedArgs
[nProps
++].Value
<<= sTemp
;
688 else if ( rProp
.Name
== "Pages" )
691 if( !(rProp
.Value
>>= sTemp
) )
692 throw css::lang::IllegalArgumentException();
693 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
694 pCheckedArgs
[nProps
++].Value
<<= sTemp
;
698 else if ( rProp
.Name
== "MonitorVisible" )
700 if( !(rProp
.Value
>>= bMonitor
) )
701 throw css::lang::IllegalArgumentException();
702 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
703 pCheckedArgs
[nProps
++].Value
<<= bMonitor
;
707 else if ( rProp
.Name
== "Wait" )
709 if ( !(rProp
.Value
>>= bWaitUntilEnd
) )
710 throw css::lang::IllegalArgumentException();
711 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
712 pCheckedArgs
[nProps
++].Value
<<= bWaitUntilEnd
;
715 else if ( rProp
.Name
== "DuplexMode" )
717 if ( !(rProp
.Value
>>= nDuplexMode
) )
718 throw css::lang::IllegalArgumentException();
719 pCheckedArgs
[nProps
].Name
= rProp
.Name
;
720 pCheckedArgs
[nProps
++].Value
<<= nDuplexMode
;
724 if ( nProps
!= aCheckedArgs
.getLength() )
725 aCheckedArgs
.realloc(nProps
);
727 // Execute the print request every time.
728 // It doesn't matter if it is a real printer used or we print to a local file
729 // nor if we print to a temp file and move it afterwards by using the ucb.
730 // That will be handled later. see pUCBPrintFile below!
731 pView
->ExecPrint( aCheckedArgs
, true, false );
733 // Ok - may be execution before has finished (or started!) printing.
734 // And may it was a printing to a file.
735 // Now we have to check if we can move the file (if necessary) via UCB to its right location.
737 // a) printing finished => move the file directly and forget the watcher thread
738 // b) printing is asynchron and runs currently => start watcher thread and exit this method
739 // This thread make all necessary things by itself.
740 if (!pUCBPrintTempFile
)
744 SfxPrinter
* pPrinter
= pView
->GetPrinter();
745 if ( ! pPrinter
->IsPrinting() )
746 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile
,sUcbUrl
);
750 // Note: we create(d) some resource on the heap (thread and temp file).
751 // They will be deleted by the thread automatically if it finishes its run() method.
752 ImplUCBPrintWatcher
* pWatcher
= new ImplUCBPrintWatcher( pPrinter
, pUCBPrintTempFile
, sUcbUrl
);
757 void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
759 const SfxPrintingHint
* pPrintHint
= dynamic_cast<const SfxPrintingHint
*>(&rHint
);
760 if ( &rBC
!= m_pObjectShell
.get()
762 || pPrintHint
->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB
)
765 if ( pPrintHint
->GetWhich() == css::view::PrintableState_JOB_STARTED
)
767 if ( !m_xPrintJob
.is() )
768 m_xPrintJob
= new SfxPrintJob_Impl( this );
769 m_aPrintOptions
= pPrintHint
->GetOptions();
772 std::unique_lock
aGuard(m_aMutex
);
773 if (!m_aJobListeners
.getLength(aGuard
))
775 view::PrintJobEvent aEvent
;
776 aEvent
.Source
= m_xPrintJob
;
777 aEvent
.State
= pPrintHint
->GetWhich();
779 comphelper::OInterfaceIteratorHelper4
pIterator(aGuard
, m_aJobListeners
);
781 while (pIterator
.hasMoreElements())
782 pIterator
.next()->printJobEvent( aEvent
);
785 void SAL_CALL
SfxPrintHelper::addPrintJobListener( const css::uno::Reference
< css::view::XPrintJobListener
>& xListener
)
787 std::unique_lock
aGuard(m_pData
->m_aMutex
);
788 m_pData
->m_aJobListeners
.addInterface( aGuard
, xListener
);
791 void SAL_CALL
SfxPrintHelper::removePrintJobListener( const css::uno::Reference
< css::view::XPrintJobListener
>& xListener
)
793 std::unique_lock
aGuard(m_pData
->m_aMutex
);
794 m_pData
->m_aJobListeners
.removeInterface( aGuard
, xListener
);
798 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */