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/lang/EventObject.hpp>
34 #include <com/sun/star/view/DuplexMode.hpp>
35 #include <comphelper/processfactory.hxx>
36 #include <svl/lstner.hxx>
37 #include <svl/stritem.hxx>
38 #include <svl/intitem.hxx>
39 #include <svl/eitem.hxx>
40 #include <unotools/tempfile.hxx>
41 #include <osl/file.hxx>
42 #include <osl/thread.hxx>
43 #include <tools/globname.hxx>
44 #include <tools/urlobj.hxx>
45 #include <ucbhelper/content.hxx>
46 #include <cppuhelper/interfacecontainer.hxx>
47 #include <osl/mutex.hxx>
48 #include <cppuhelper/implbase.hxx>
49 #include <vcl/settings.hxx>
50 #include <vcl/svapp.hxx>
52 #include <sfx2/viewfrm.hxx>
53 #include <sfx2/viewsh.hxx>
54 #include <sfx2/dispatch.hxx>
55 #include <sfx2/request.hxx>
56 #include <sfx2/printer.hxx>
57 #include <sfx2/app.hxx>
58 #include <sfx2/objsh.hxx>
59 #include <sfx2/event.hxx>
61 #define SFX_PRINTABLESTATE_CANCELJOB css::view::PrintableState(-2)
63 using namespace ::com::sun::star
;
64 using namespace ::com::sun::star::uno
;
66 struct IMPL_PrintListener_DataContainer
: public SfxListener
68 SfxObjectShellRef m_pObjectShell
;
69 ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer
;
70 uno::Reference
< css::view::XPrintJob
> m_xPrintJob
;
71 css::uno::Sequence
< css::beans::PropertyValue
> m_aPrintOptions
;
73 explicit IMPL_PrintListener_DataContainer( ::osl::Mutex
& aMutex
)
74 : m_aInterfaceContainer ( aMutex
)
79 void Notify( SfxBroadcaster
& aBC
,
80 const SfxHint
& aHint
) override
;
83 static awt::Size
impl_Size_Object2Struct( const Size
& aSize
)
85 awt::Size aReturnValue
;
86 aReturnValue
.Width
= aSize
.Width() ;
87 aReturnValue
.Height
= aSize
.Height() ;
91 static Size
impl_Size_Struct2Object( const awt::Size
& aSize
)
94 aReturnValue
.setWidth( aSize
.Width
) ;
95 aReturnValue
.setHeight( aSize
.Height
) ;
99 class SfxPrintJob_Impl
: public cppu::WeakImplHelper
104 IMPL_PrintListener_DataContainer
* m_pData
;
107 explicit SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
);
108 virtual Sequence
< css::beans::PropertyValue
> SAL_CALL
getPrintOptions( ) override
;
109 virtual Sequence
< css::beans::PropertyValue
> SAL_CALL
getPrinter( ) override
;
110 virtual Reference
< css::view::XPrintable
> SAL_CALL
getPrintable( ) override
;
111 virtual void SAL_CALL
cancelJob() override
;
114 SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
)
119 Sequence
< css::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrintOptions()
121 return m_pData
->m_aPrintOptions
;
124 Sequence
< css::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrinter()
126 if( m_pData
->m_pObjectShell
.is() )
128 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
->GetModel(), UNO_QUERY
);
129 if ( xPrintable
.is() )
130 return xPrintable
->getPrinter();
132 return Sequence
< css::beans::PropertyValue
>();
135 Reference
< css::view::XPrintable
> SAL_CALL
SfxPrintJob_Impl::getPrintable()
137 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
.is() ? m_pData
->m_pObjectShell
->GetModel() : nullptr, UNO_QUERY
);
141 void SAL_CALL
SfxPrintJob_Impl::cancelJob()
143 // FIXME: how to cancel PrintJob via API?!
144 if( m_pData
->m_pObjectShell
.is() )
145 m_pData
->m_pObjectShell
->Broadcast( SfxPrintingHint( SFX_PRINTABLESTATE_CANCELJOB
) );
148 SfxPrintHelper::SfxPrintHelper()
150 m_pData
.reset(new IMPL_PrintListener_DataContainer(m_aMutex
));
153 void SAL_CALL
SfxPrintHelper::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
155 if ( !aArguments
.hasElements() )
158 css::uno::Reference
< css::frame::XModel
> xModel
;
159 aArguments
[0] >>= xModel
;
160 uno::Reference
< lang::XUnoTunnel
> xObj( xModel
, uno::UNO_QUERY
);
161 uno::Sequence
< sal_Int8
> aSeq( SvGlobalName( SFX_GLOBAL_CLASSID
).GetByteSequence() );
162 sal_Int64 nHandle
= xObj
->getSomething( aSeq
);
165 m_pData
->m_pObjectShell
= reinterpret_cast< SfxObjectShell
* >( sal::static_int_cast
< sal_IntPtr
>( nHandle
));
166 m_pData
->StartListening(*m_pData
->m_pObjectShell
);
170 SfxPrintHelper::~SfxPrintHelper()
176 view::PaperFormat
convertToPaperFormat(Paper eFormat
)
178 view::PaperFormat eRet
;
182 eRet
= view::PaperFormat_A3
;
185 eRet
= view::PaperFormat_A4
;
188 eRet
= view::PaperFormat_A5
;
191 eRet
= view::PaperFormat_B4
;
194 eRet
= view::PaperFormat_B5
;
197 eRet
= view::PaperFormat_LETTER
;
200 eRet
= view::PaperFormat_LEGAL
;
203 eRet
= view::PaperFormat_TABLOID
;
207 eRet
= view::PaperFormat_USER
;
213 Paper
convertToPaper(view::PaperFormat eFormat
)
215 Paper
eRet(PAPER_USER
);
218 case view::PaperFormat_A3
:
221 case view::PaperFormat_A4
:
224 case view::PaperFormat_A5
:
227 case view::PaperFormat_B4
:
230 case view::PaperFormat_B5
:
233 case view::PaperFormat_LETTER
:
236 case view::PaperFormat_LEGAL
:
239 case view::PaperFormat_TABLOID
:
240 eRet
= PAPER_TABLOID
;
242 case view::PaperFormat_USER
:
245 case view::PaperFormat::PaperFormat_MAKE_FIXED_SIZE
:
247 //deliberate no default to force warn on a new papersize
257 uno::Sequence
< beans::PropertyValue
> SAL_CALL
SfxPrintHelper::getPrinter()
259 // object already disposed?
260 SolarMutexGuard aGuard
;
262 // search for any view of this document that is currently printing
263 const Printer
*pPrinter
= nullptr;
264 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ? SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
265 SfxViewFrame
* pFirst
= pViewFrm
;
266 while ( pViewFrm
&& !pPrinter
)
268 pPrinter
= pViewFrm
->GetViewShell()->GetActivePrinter();
269 pViewFrm
= SfxViewFrame::GetNext( *pViewFrm
, m_pData
->m_pObjectShell
.get(), false );
272 // if no view is printing currently, use the permanent SfxPrinter instance
273 if ( !pPrinter
&& pFirst
)
274 pPrinter
= pFirst
->GetViewShell()->GetPrinter(true);
277 return uno::Sequence
< beans::PropertyValue
>();
279 uno::Sequence
< beans::PropertyValue
> aPrinter(8);
281 aPrinter
.getArray()[7].Name
= "CanSetPaperSize";
282 aPrinter
.getArray()[7].Value
<<= pPrinter
->HasSupport( PrinterSupport::SetPaperSize
);
284 aPrinter
.getArray()[6].Name
= "CanSetPaperFormat";
285 aPrinter
.getArray()[6].Value
<<= pPrinter
->HasSupport( PrinterSupport::SetPaper
);
287 aPrinter
.getArray()[5].Name
= "CanSetPaperOrientation";
288 aPrinter
.getArray()[5].Value
<<= pPrinter
->HasSupport( PrinterSupport::SetOrientation
);
290 aPrinter
.getArray()[4].Name
= "IsBusy";
291 aPrinter
.getArray()[4].Value
<<= pPrinter
->IsPrinting();
293 aPrinter
.getArray()[3].Name
= "PaperSize";
294 awt::Size aSize
= impl_Size_Object2Struct(pPrinter
->GetPaperSize() );
295 aPrinter
.getArray()[3].Value
<<= aSize
;
297 aPrinter
.getArray()[2].Name
= "PaperFormat";
298 view::PaperFormat eFormat
= convertToPaperFormat(pPrinter
->GetPaper());
299 aPrinter
.getArray()[2].Value
<<= eFormat
;
301 aPrinter
.getArray()[1].Name
= "PaperOrientation";
302 view::PaperOrientation eOrient
= static_cast<view::PaperOrientation
>(pPrinter
->GetOrientation());
303 aPrinter
.getArray()[1].Value
<<= eOrient
;
305 aPrinter
.getArray()[0].Name
= "Name";
306 OUString sStringTemp
= pPrinter
->GetName() ;
307 aPrinter
.getArray()[0].Value
<<= sStringTemp
;
316 void SfxPrintHelper::impl_setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
,
317 VclPtr
<SfxPrinter
>& pPrinter
,
318 SfxPrinterChangeFlags
& nChangeFlags
,
319 SfxViewShell
*& pViewSh
)
323 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ?
324 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
328 pViewSh
= pViewFrm
->GetViewShell();
329 pPrinter
= pViewSh
->GetPrinter(true);
333 // new Printer-Name available?
334 nChangeFlags
= SfxPrinterChangeFlags::NONE
;
335 sal_Int32 lDummy
= 0;
336 auto pProp
= std::find_if(rPrinter
.begin(), rPrinter
.end(),
337 [](const beans::PropertyValue
&rProp
) { return rProp
.Name
== "Name"; });
338 if (pProp
!= rPrinter
.end())
340 OUString aPrinterName
;
341 if ( ! ( pProp
->Value
>>= aPrinterName
) )
342 throw css::lang::IllegalArgumentException();
344 if ( aPrinterName
!= pPrinter
->GetName() )
346 pPrinter
= VclPtr
<SfxPrinter
>::Create( pPrinter
->GetOptions().Clone(), aPrinterName
);
347 nChangeFlags
= SfxPrinterChangeFlags::PRINTER
;
351 Size
aSetPaperSize( 0, 0);
352 view::PaperFormat nPaperFormat
= view::PaperFormat_USER
;
355 for ( const beans::PropertyValue
&rProp
: rPrinter
)
357 // get Property-Value from printer description
358 // PaperOrientation-Property?
359 if ( rProp
.Name
== "PaperOrientation" )
361 view::PaperOrientation eOrient
;
362 if ( !( rProp
.Value
>>= eOrient
) )
364 if ( !( rProp
.Value
>>= lDummy
) )
365 throw css::lang::IllegalArgumentException();
366 eOrient
= static_cast<view::PaperOrientation
>(lDummy
);
369 if ( static_cast<Orientation
>(eOrient
) != pPrinter
->GetOrientation() )
371 pPrinter
->SetOrientation( static_cast<Orientation
>(eOrient
) );
372 nChangeFlags
|= SfxPrinterChangeFlags::CHG_ORIENTATION
;
376 // PaperFormat-Property?
377 else if ( rProp
.Name
== "PaperFormat" )
379 if ( !( rProp
.Value
>>= nPaperFormat
) )
381 if ( !( rProp
.Value
>>= lDummy
) )
382 throw css::lang::IllegalArgumentException();
383 nPaperFormat
= static_cast<view::PaperFormat
>(lDummy
);
386 if ( convertToPaper(nPaperFormat
) != pPrinter
->GetPaper() )
388 pPrinter
->SetPaper( convertToPaper(nPaperFormat
) );
389 nChangeFlags
|= SfxPrinterChangeFlags::CHG_SIZE
;
393 // PaperSize-Property?
394 else if ( rProp
.Name
== "PaperSize" )
396 awt::Size aTempSize
;
397 if ( !( rProp
.Value
>>= aTempSize
) )
399 throw css::lang::IllegalArgumentException();
401 aSetPaperSize
= impl_Size_Struct2Object(aTempSize
);
404 // PrinterTray-Property
405 else if ( rProp
.Name
== "PrinterPaperTray" )
408 if ( !( rProp
.Value
>>= aTmp
) )
409 throw css::lang::IllegalArgumentException();
410 const sal_uInt16 nCount
= pPrinter
->GetPaperBinCount();
411 for (sal_uInt16 nBin
=0; nBin
<nCount
; nBin
++)
413 OUString
aName( pPrinter
->GetPaperBinName(nBin
) );
416 pPrinter
->SetPaperBin(nBin
);
423 // The PaperSize may be set only when actually PAPER_USER
424 // applies, otherwise the driver could choose an invalid format.
425 if(nPaperFormat
== view::PaperFormat_USER
&& aSetPaperSize
.Width())
427 // Bug 56929 - MapMode of 100mm which recalculated when
428 // the device is set. Additionally only set if they were really changed.
429 aSetPaperSize
= pPrinter
->LogicToPixel(aSetPaperSize
, MapMode(MapUnit::Map100thMM
));
430 if( aSetPaperSize
!= pPrinter
->GetPaperSizePixel() )
432 pPrinter
->SetPaperSizeUser( pPrinter
->PixelToLogic( aSetPaperSize
) );
433 nChangeFlags
|= SfxPrinterChangeFlags::CHG_SIZE
;
437 //wait until printing is done
438 SfxPrinter
* pDocPrinter
= pViewSh
->GetPrinter();
439 while ( pDocPrinter
->IsPrinting() )
440 Application::Yield();
443 void SAL_CALL
SfxPrintHelper::setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
)
445 // object already disposed?
446 SolarMutexGuard aGuard
;
448 SfxViewShell
* pViewSh
= nullptr;
449 VclPtr
<SfxPrinter
> pPrinter
;
450 SfxPrinterChangeFlags nChangeFlags
= SfxPrinterChangeFlags::NONE
;
451 impl_setPrinter(rPrinter
,pPrinter
,nChangeFlags
,pViewSh
);
453 if ( pViewSh
&& pPrinter
)
454 pViewSh
->SetPrinter( pPrinter
, nChangeFlags
);
458 // ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
461 /* This implements a thread which will be started to wait for asynchronous
462 print jobs to temp. locally files. If they finish we move the temp. files
463 to their right locations by using the ucb.
465 class ImplUCBPrintWatcher
: public ::osl::Thread
468 /// of course we must know the printer which execute the job
469 VclPtr
<SfxPrinter
> m_pPrinter
;
470 /// this describes the target location for the printed temp file
471 OUString
const m_sTargetURL
;
472 /// it holds the temp file alive, till the print job will finish and remove it from disk automatically if the object die
473 ::utl::TempFile
* m_pTempFile
;
476 /* initialize this watcher but don't start it */
477 ImplUCBPrintWatcher( SfxPrinter
* pPrinter
, ::utl::TempFile
* pTempFile
, const OUString
& sTargetURL
)
478 : m_pPrinter ( pPrinter
)
479 , m_sTargetURL( sTargetURL
)
480 , m_pTempFile ( pTempFile
)
483 /* waits for finishing of the print job and moves the temp file afterwards
484 Note: Starting of the job is done outside this thread!
485 But we have to free some of the given resources on heap!
487 void SAL_CALL
run() override
489 osl_setThreadName("ImplUCBPrintWatcher");
493 SolarMutexGuard aGuard
;
494 while( m_pPrinter
->IsPrinting() )
495 Application::Yield();
496 m_pPrinter
.clear(); // don't delete it! It's borrowed only :-)
500 // lock for further using of our member isn't necessary - because
501 // we run alone by definition. Nobody join for us nor use us...
502 moveAndDeleteTemp(&m_pTempFile
,m_sTargetURL
);
504 // finishing of this run() method will call onTerminate() automatically
505 // kill this thread there!
508 /* nobody wait for this thread. We must kill ourself ...
510 void SAL_CALL
onTerminated() override
515 /* static helper to move the temp. file to the target location by using the ucb
516 It's static to be usable from outside too. So it's not really necessary to start
517 the thread, if finishing of the job was detected outside this thread.
518 But it must be called without using a corresponding thread for the given parameter!
520 static void moveAndDeleteTemp( ::utl::TempFile
** ppTempFile
, const OUString
& sTargetURL
)
525 INetURLObject
aSplitter(sTargetURL
);
526 OUString sFileName
= aSplitter
.getName(
527 INetURLObject::LAST_SEGMENT
,
529 INetURLObject::DecodeMechanism::WithCharset
);
530 if (aSplitter
.removeSegment() && !sFileName
.isEmpty())
532 ::ucbhelper::Content
aSource(
533 (*ppTempFile
)->GetURL(),
534 css::uno::Reference
< css::ucb::XCommandEnvironment
>(),
535 comphelper::getProcessComponentContext());
537 ::ucbhelper::Content
aTarget(
538 aSplitter
.GetMainURL(INetURLObject::DecodeMechanism::NONE
),
539 css::uno::Reference
< css::ucb::XCommandEnvironment
>(),
540 comphelper::getProcessComponentContext());
542 aTarget
.transferContent(
544 ::ucbhelper::InsertOperation::Copy
,
546 css::ucb::NameClash::OVERWRITE
);
549 catch (const css::ucb::ContentCreationException
&)
551 OSL_FAIL("content create exception");
553 catch (const css::ucb::CommandAbortedException
&)
555 OSL_FAIL("command abort exception");
557 catch (const css::uno::RuntimeException
&)
559 OSL_FAIL("runtime exception");
561 catch (const css::uno::Exception
&)
563 OSL_FAIL("unknown exception");
566 // kill the temp file!
568 *ppTempFile
= nullptr;
575 void SAL_CALL
SfxPrintHelper::print(const uno::Sequence
< beans::PropertyValue
>& rOptions
)
577 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
580 // object already disposed?
581 // object already disposed?
582 SolarMutexGuard aGuard
;
584 // get view for sfx printing capabilities
585 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.is() ?
586 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false ) : nullptr;
589 SfxViewShell
* pView
= pViewFrm
->GetViewShell();
592 bool bMonitor
= false;
593 // We need this information at the end of this method, if we start the vcl printer
594 // by executing the slot. Because if it is a ucb relevant URL we must wait for
595 // finishing the print job and move the temporary local file by using the ucb
596 // to the right location. But in case of no file name is given or it is already
597 // a local one we can suppress this special handling. Because then vcl makes all
600 ::utl::TempFile
* pUCBPrintTempFile
= nullptr;
602 uno::Sequence
< beans::PropertyValue
> aCheckedArgs( rOptions
.getLength() );
603 sal_Int32 nProps
= 0;
604 bool bWaitUntilEnd
= false;
605 sal_Int16 nDuplexMode
= css::view::DuplexMode::UNKNOWN
;
606 for ( const beans::PropertyValue
&rProp
: rOptions
)
608 // get Property-Value from options
609 // FileName-Property?
610 if ( rProp
.Name
== "FileName" )
612 // unpack th URL and check for a valid and well known protocol
615 ( rProp
.Value
.getValueType()!=cppu::UnoType
<OUString
>::get()) ||
616 (!(rProp
.Value
>>=sTemp
))
619 throw css::lang::IllegalArgumentException();
623 OUString
sURL (sTemp
);
624 INetURLObject
aCheck(sURL
);
625 if (aCheck
.GetProtocol()==INetProtocol::NotValid
)
627 // OK - it's not a valid URL. But may it's a simple
628 // system path directly. It will be supported for historical
629 // reasons. Otherwise we break too much external code...
630 // We try to convert it to a file URL. If its possible
631 // we put the system path to the item set and let vcl work with it.
632 // No ucb or thread will be necessary then. In case it couldn't be
633 // converted it's not a URL nor a system path. Then we can't accept
634 // this parameter and have to throw an exception.
635 const OUString
& sSystemPath(sTemp
);
637 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath
,sFileURL
)!=::osl::FileBase::E_None
)
638 throw css::lang::IllegalArgumentException();
639 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
640 aCheckedArgs
[nProps
++].Value
<<= sFileURL
;
641 // and append the local filename
642 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
643 aCheckedArgs
[nProps
].Name
= "LocalFileName";
644 aCheckedArgs
[nProps
++].Value
<<= sTemp
;
647 // It's a valid URL. but now we must know, if it is a local one or not.
648 // It's a question of using ucb or not!
649 if (osl::FileBase::getSystemPathFromFileURL(sURL
, sPath
) == osl::FileBase::E_None
)
651 // it's a local file, we can use vcl without special handling
652 // And we have to use the system notation of the incoming URL.
653 // But it into the descriptor and let the slot be executed at
654 // the end of this method.
655 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
656 aCheckedArgs
[nProps
++].Value
<<= sTemp
;
657 // and append the local filename
658 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
659 aCheckedArgs
[nProps
].Name
= "LocalFileName";
660 aCheckedArgs
[nProps
++].Value
<<= sPath
;
664 // it's a ucb target. So we must use a temp. file for vcl
665 // and move it after printing by using the ucb.
666 // Create a temp file on the heap (because it must delete the
667 // real file on disk automatically if it die - bt we have to share it with
668 // some other sources ... e.g. the ImplUCBPrintWatcher).
669 // And we put the name of this temp file to the descriptor instead
670 // of the URL. The URL we save for later using separately.
671 // Execution of the print job will be done later by executing
673 if(!pUCBPrintTempFile
)
674 pUCBPrintTempFile
= new ::utl::TempFile();
675 pUCBPrintTempFile
->EnableKillingFile();
677 //FIXME: does it work?
678 aCheckedArgs
[nProps
].Name
= "LocalFileName";
679 aCheckedArgs
[nProps
++].Value
<<= pUCBPrintTempFile
->GetFileName();
684 // CopyCount-Property
685 else if ( rProp
.Name
== "CopyCount" )
687 sal_Int32 nCopies
= 0;
688 if ( !( rProp
.Value
>>= nCopies
) )
689 throw css::lang::IllegalArgumentException();
690 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
691 aCheckedArgs
[nProps
++].Value
<<= nCopies
;
695 // Sort-Property (deprecated)
696 else if ( rProp
.Name
== "Collate" || rProp
.Name
== "Sort" )
699 if ( !(rProp
.Value
>>= bTemp
) )
700 throw css::lang::IllegalArgumentException();
701 aCheckedArgs
[nProps
].Name
= "Collate";
702 aCheckedArgs
[nProps
++].Value
<<= bTemp
;
706 else if ( rProp
.Name
== "Pages" )
709 if( !(rProp
.Value
>>= sTemp
) )
710 throw css::lang::IllegalArgumentException();
711 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
712 aCheckedArgs
[nProps
++].Value
<<= sTemp
;
716 else if ( rProp
.Name
== "MonitorVisible" )
718 if( !(rProp
.Value
>>= bMonitor
) )
719 throw css::lang::IllegalArgumentException();
720 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
721 aCheckedArgs
[nProps
++].Value
<<= bMonitor
;
725 else if ( rProp
.Name
== "Wait" )
727 if ( !(rProp
.Value
>>= bWaitUntilEnd
) )
728 throw css::lang::IllegalArgumentException();
729 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
730 aCheckedArgs
[nProps
++].Value
<<= bWaitUntilEnd
;
733 else if ( rProp
.Name
== "DuplexMode" )
735 if ( !(rProp
.Value
>>= nDuplexMode
) )
736 throw css::lang::IllegalArgumentException();
737 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
738 aCheckedArgs
[nProps
++].Value
<<= nDuplexMode
;
742 if ( nProps
!= aCheckedArgs
.getLength() )
743 aCheckedArgs
.realloc(nProps
);
745 // Execute the print request every time.
746 // It doesn't matter if it is a real printer used or we print to a local file
747 // nor if we print to a temp file and move it afterwards by using the ucb.
748 // That will be handled later. see pUCBPrintFile below!
749 pView
->ExecPrint( aCheckedArgs
, true, false );
751 // Ok - may be execution before has finished (or started!) printing.
752 // And may it was a printing to a file.
753 // Now we have to check if we can move the file (if necessary) via UCB to its right location.
755 // a) printing finished => move the file directly and forget the watcher thread
756 // b) printing is asynchron and runs currently => start watcher thread and exit this method
757 // This thread make all necessary things by itself.
758 if (!pUCBPrintTempFile
)
762 SfxPrinter
* pPrinter
= pView
->GetPrinter();
763 if ( ! pPrinter
->IsPrinting() )
764 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile
,sUcbUrl
);
768 // Note: we create(d) some resource on the heap (thread and temp file).
769 // They will be deleted by the thread automatically if it finishes its run() method.
770 ImplUCBPrintWatcher
* pWatcher
= new ImplUCBPrintWatcher( pPrinter
, pUCBPrintTempFile
, sUcbUrl
);
775 void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
777 const SfxPrintingHint
* pPrintHint
= dynamic_cast<const SfxPrintingHint
*>(&rHint
);
778 if ( &rBC
!= m_pObjectShell
.get()
780 || pPrintHint
->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB
)
783 if ( pPrintHint
->GetWhich() == css::view::PrintableState_JOB_STARTED
)
785 if ( !m_xPrintJob
.is() )
786 m_xPrintJob
= new SfxPrintJob_Impl( this );
787 m_aPrintOptions
= pPrintHint
->GetOptions();
790 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aInterfaceContainer
.getContainer(
791 cppu::UnoType
<view::XPrintJobListener
>::get());
795 view::PrintJobEvent aEvent
;
796 aEvent
.Source
= m_xPrintJob
;
797 aEvent
.State
= pPrintHint
->GetWhich();
799 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
800 while (pIterator
.hasMoreElements())
801 static_cast<view::XPrintJobListener
*>(pIterator
.next())->printJobEvent( aEvent
);
804 void SAL_CALL
SfxPrintHelper::addPrintJobListener( const css::uno::Reference
< css::view::XPrintJobListener
>& xListener
)
806 SolarMutexGuard aGuard
;
807 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<view::XPrintJobListener
>::get(), xListener
);
810 void SAL_CALL
SfxPrintHelper::removePrintJobListener( const css::uno::Reference
< css::view::XPrintJobListener
>& xListener
)
812 SolarMutexGuard aGuard
;
813 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<view::XPrintJobListener
>::get(), xListener
);
817 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */