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/lang/XUnoTunnel.hpp>
30 #include <com/sun/star/frame/XModel.hpp>
31 #include <com/sun/star/lang/EventObject.hpp>
32 #include <com/sun/star/view/DuplexMode.hpp>
33 #include <comphelper/processfactory.hxx>
34 #include <svl/lstner.hxx>
35 #include <svl/stritem.hxx>
36 #include <svl/intitem.hxx>
37 #include <svl/eitem.hxx>
38 #include <unotools/tempfile.hxx>
39 #include <unotools/localfilehelper.hxx>
40 #include <osl/file.hxx>
41 #include <osl/thread.hxx>
42 #include <tools/urlobj.hxx>
43 #include <ucbhelper/content.hxx>
44 #include <cppuhelper/interfacecontainer.hxx>
45 #include <osl/mutex.hxx>
46 #include <cppuhelper/implbase1.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <sfx2/viewsh.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <sfx2/request.hxx>
52 #include <sfx2/printer.hxx>
53 #include <sfx2/app.hxx>
54 #include <sfx2/objsh.hxx>
55 #include <sfx2/event.hxx>
57 using namespace ::com::sun::star
;
58 using namespace ::com::sun::star::uno
;
60 struct IMPL_PrintListener_DataContainer
: public SfxListener
62 SfxObjectShellRef m_pObjectShell
;
63 ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer
;
64 uno::Reference
< com::sun::star::view::XPrintJob
> m_xPrintJob
;
65 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> m_aPrintOptions
;
67 IMPL_PrintListener_DataContainer( ::osl::Mutex
& aMutex
)
68 : m_pObjectShell ( 0 )
69 , m_aInterfaceContainer ( aMutex
)
74 void Notify( SfxBroadcaster
& aBC
,
75 const SfxHint
& aHint
) ;
78 awt::Size
impl_Size_Object2Struct( const Size
& aSize
)
80 awt::Size aReturnValue
;
81 aReturnValue
.Width
= aSize
.Width() ;
82 aReturnValue
.Height
= aSize
.Height() ;
86 Size
impl_Size_Struct2Object( const awt::Size
& aSize
)
89 aReturnValue
.Width() = aSize
.Width
;
90 aReturnValue
.Height() = aSize
.Height
;
94 class SfxPrintJob_Impl
: public cppu::WeakImplHelper1
96 com::sun::star::view::XPrintJob
99 IMPL_PrintListener_DataContainer
* m_pData
;
102 SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
);
103 virtual Sequence
< ::com::sun::star::beans::PropertyValue
> SAL_CALL
getPrintOptions( ) throw (RuntimeException
);
104 virtual Sequence
< ::com::sun::star::beans::PropertyValue
> SAL_CALL
getPrinter( ) throw (RuntimeException
);
105 virtual Reference
< ::com::sun::star::view::XPrintable
> SAL_CALL
getPrintable( ) throw (RuntimeException
);
106 virtual void SAL_CALL
cancelJob() throw (RuntimeException
);
109 SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
)
114 Sequence
< ::com::sun::star::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrintOptions() throw (RuntimeException
)
116 return m_pData
->m_aPrintOptions
;
119 Sequence
< ::com::sun::star::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrinter() throw (RuntimeException
)
121 if( m_pData
->m_pObjectShell
.Is() )
123 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
->GetModel(), UNO_QUERY
);
124 if ( xPrintable
.is() )
125 return xPrintable
->getPrinter();
127 return Sequence
< ::com::sun::star::beans::PropertyValue
>();
130 Reference
< ::com::sun::star::view::XPrintable
> SAL_CALL
SfxPrintJob_Impl::getPrintable() throw (RuntimeException
)
132 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
.Is() ? m_pData
->m_pObjectShell
->GetModel() : NULL
, UNO_QUERY
);
136 void SAL_CALL
SfxPrintJob_Impl::cancelJob() throw (RuntimeException
)
138 // FIXME: how to cancel PrintJob via API?!
139 if( m_pData
->m_pObjectShell
.Is() )
140 m_pData
->m_pObjectShell
->Broadcast( SfxPrintingHint( -2 ) );
143 SfxPrintHelper::SfxPrintHelper()
145 m_pData
= new IMPL_PrintListener_DataContainer(m_aMutex
);
148 void SAL_CALL
SfxPrintHelper::initialize( const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Any
>& aArguments
) throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
150 if ( aArguments
.getLength() )
152 com::sun::star::uno::Reference
< com::sun::star::frame::XModel
> xModel
;
153 aArguments
[0] >>= xModel
;
154 uno::Reference
< lang::XUnoTunnel
> xObj( xModel
, uno::UNO_QUERY
);
155 uno::Sequence
< sal_Int8
> aSeq( SvGlobalName( SFX_GLOBAL_CLASSID
).GetByteSequence() );
156 sal_Int64 nHandle
= xObj
->getSomething( aSeq
);
159 m_pData
->m_pObjectShell
= reinterpret_cast< SfxObjectShell
* >( sal::static_int_cast
< sal_IntPtr
>( nHandle
));
160 m_pData
->StartListening(*m_pData
->m_pObjectShell
);
165 SfxPrintHelper::~SfxPrintHelper()
172 view::PaperFormat
convertToPaperFormat(Paper eFormat
)
174 view::PaperFormat eRet
;
178 eRet
= view::PaperFormat_A3
;
181 eRet
= view::PaperFormat_A4
;
184 eRet
= view::PaperFormat_A5
;
187 eRet
= view::PaperFormat_B4
;
190 eRet
= view::PaperFormat_B5
;
193 eRet
= view::PaperFormat_LETTER
;
196 eRet
= view::PaperFormat_LEGAL
;
199 eRet
= view::PaperFormat_TABLOID
;
203 eRet
= view::PaperFormat_USER
;
209 Paper
convertToPaper(view::PaperFormat eFormat
)
211 Paper
eRet(PAPER_USER
);
214 case view::PaperFormat_A3
:
217 case view::PaperFormat_A4
:
220 case view::PaperFormat_A5
:
223 case view::PaperFormat_B4
:
226 case view::PaperFormat_B5
:
229 case view::PaperFormat_LETTER
:
232 case view::PaperFormat_LEGAL
:
235 case view::PaperFormat_TABLOID
:
236 eRet
= PAPER_TABLOID
;
238 case view::PaperFormat_USER
:
241 case view::PaperFormat_MAKE_FIXED_SIZE
:
243 //deliberate no default to force warn on a new papersize
249 //________________________________________________________________________________________________________
251 //________________________________________________________________________________________________________
253 uno::Sequence
< beans::PropertyValue
> SAL_CALL
SfxPrintHelper::getPrinter() throw(::com::sun::star::uno::RuntimeException
)
255 // object already disposed?
256 SolarMutexGuard aGuard
;
258 // search for any view of this document that is currently printing
259 const Printer
*pPrinter
= NULL
;
260 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.Is() ? SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
, sal_False
) : 0;
261 SfxViewFrame
* pFirst
= pViewFrm
;
262 while ( pViewFrm
&& !pPrinter
)
264 pPrinter
= pViewFrm
->GetViewShell()->GetActivePrinter();
265 pViewFrm
= SfxViewFrame::GetNext( *pViewFrm
, m_pData
->m_pObjectShell
, sal_False
);
268 // if no view is printing currently, use the permanent SfxPrinter instance
269 if ( !pPrinter
&& pFirst
)
270 pPrinter
= pFirst
->GetViewShell()->GetPrinter(sal_True
);
273 return uno::Sequence
< beans::PropertyValue
>();
275 uno::Sequence
< beans::PropertyValue
> aPrinter(8);
277 aPrinter
.getArray()[7].Name
= "CanSetPaperSize";
278 aPrinter
.getArray()[7].Value
<<= ( pPrinter
->HasSupport( SUPPORT_SET_PAPERSIZE
) );
280 aPrinter
.getArray()[6].Name
= "CanSetPaperFormat";
281 aPrinter
.getArray()[6].Value
<<= ( pPrinter
->HasSupport( SUPPORT_SET_PAPER
) );
283 aPrinter
.getArray()[5].Name
= "CanSetPaperOrientation";
284 aPrinter
.getArray()[5].Value
<<= ( pPrinter
->HasSupport( SUPPORT_SET_ORIENTATION
) );
286 aPrinter
.getArray()[4].Name
= "IsBusy";
287 aPrinter
.getArray()[4].Value
<<= ( pPrinter
->IsPrinting() );
289 aPrinter
.getArray()[3].Name
= "PaperSize";
290 awt::Size aSize
= impl_Size_Object2Struct(pPrinter
->GetPaperSize() );
291 aPrinter
.getArray()[3].Value
<<= aSize
;
293 aPrinter
.getArray()[2].Name
= "PaperFormat";
294 view::PaperFormat eFormat
= convertToPaperFormat(pPrinter
->GetPaper());
295 aPrinter
.getArray()[2].Value
<<= eFormat
;
297 aPrinter
.getArray()[1].Name
= "PaperOrientation";
298 view::PaperOrientation eOrient
= (view::PaperOrientation
)pPrinter
->GetOrientation();
299 aPrinter
.getArray()[1].Value
<<= eOrient
;
301 aPrinter
.getArray()[0].Name
= "Name";
302 String sStringTemp
= pPrinter
->GetName() ;
303 aPrinter
.getArray()[0].Value
<<= OUString( sStringTemp
);
308 //________________________________________________________________________________________________________
310 //________________________________________________________________________________________________________
312 void SfxPrintHelper::impl_setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
,SfxPrinter
*& pPrinter
,sal_uInt16
& nChangeFlags
,SfxViewShell
*& pViewSh
)
316 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.Is() ?
317 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
, sal_False
) : 0;
321 pViewSh
= pViewFrm
->GetViewShell();
322 pPrinter
= pViewSh
->GetPrinter(sal_True
);
326 // new Printer-Name available?
328 sal_Int32 lDummy
= 0;
329 for ( int n
= 0; n
< rPrinter
.getLength(); ++n
)
331 // get Property-Value from printer description
332 const beans::PropertyValue
&rProp
= rPrinter
.getConstArray()[n
];
335 if ( rProp
.Name
.compareToAscii( "Name" ) == 0 )
337 OUString aPrinterName
;
338 if ( ! ( rProp
.Value
>>= aPrinterName
) )
339 throw ::com::sun::star::lang::IllegalArgumentException();
341 if ( aPrinterName
!= pPrinter
->GetName() )
343 pPrinter
= new SfxPrinter( pPrinter
->GetOptions().Clone(), aPrinterName
);
344 nChangeFlags
= SFX_PRINTER_PRINTER
;
350 Size
aSetPaperSize( 0, 0);
351 view::PaperFormat nPaperFormat
= view::PaperFormat_USER
;
354 for ( int i
= 0; i
< rPrinter
.getLength(); ++i
)
356 // get Property-Value from printer description
357 const beans::PropertyValue
&rProp
= rPrinter
.getConstArray()[i
];
359 // PaperOrientation-Property?
360 if ( rProp
.Name
.compareToAscii( "PaperOrientation" ) == 0 )
362 view::PaperOrientation eOrient
;
363 if ( ( rProp
.Value
>>= eOrient
) == sal_False
)
365 if ( ( rProp
.Value
>>= lDummy
) == sal_False
)
366 throw ::com::sun::star::lang::IllegalArgumentException();
367 eOrient
= ( view::PaperOrientation
) lDummy
;
370 if ( (Orientation
) eOrient
!= pPrinter
->GetOrientation() )
372 pPrinter
->SetOrientation( (Orientation
) eOrient
);
373 nChangeFlags
|= SFX_PRINTER_CHG_ORIENTATION
;
377 // PaperFormat-Property?
378 else if ( rProp
.Name
.compareToAscii( "PaperFormat" ) == 0 )
380 if ( ( rProp
.Value
>>= nPaperFormat
) == sal_False
)
382 if ( ( rProp
.Value
>>= lDummy
) == sal_False
)
383 throw ::com::sun::star::lang::IllegalArgumentException();
384 nPaperFormat
= ( view::PaperFormat
) lDummy
;
387 if ( convertToPaper(nPaperFormat
) != pPrinter
->GetPaper() )
389 pPrinter
->SetPaper( convertToPaper(nPaperFormat
) );
390 nChangeFlags
|= SFX_PRINTER_CHG_SIZE
;
394 // PaperSize-Property?
395 else if ( rProp
.Name
.compareToAscii( "PaperSize" ) == 0 )
397 awt::Size aTempSize
;
398 if ( ( rProp
.Value
>>= aTempSize
) == sal_False
)
400 throw ::com::sun::star::lang::IllegalArgumentException();
404 aSetPaperSize
= impl_Size_Struct2Object(aTempSize
);
408 // PrinterTray-Property
409 else if ( rProp
.Name
.compareToAscii( "PrinterPaperTray" ) == 0 )
412 if ( ( rProp
.Value
>>= aTmp
) == sal_False
)
413 throw ::com::sun::star::lang::IllegalArgumentException();
414 sal_uInt16 nCount
= pPrinter
->GetPaperBinCount();
415 for (sal_uInt16 nBin
=0; nBin
<nCount
; nBin
++)
417 OUString
aName( pPrinter
->GetPaperBinName(nBin
) );
420 pPrinter
->SetPaperBin(nBin
);
427 // The PaperSize may be set only when actually PAPER_USER
428 // applies, otherwise the driver could choose a invalid format.
429 if(nPaperFormat
== view::PaperFormat_USER
&& aSetPaperSize
.Width())
431 // Bug 56929 - MapMode of 100mm which recalculated when
432 // the device is set. Additionally only set if they were really changed.
433 aSetPaperSize
= pPrinter
->LogicToPixel( aSetPaperSize
, MAP_100TH_MM
);
434 if( aSetPaperSize
!= pPrinter
->GetPaperSizePixel() )
436 pPrinter
->SetPaperSizeUser( pPrinter
->PixelToLogic( aSetPaperSize
) );
437 nChangeFlags
|= SFX_PRINTER_CHG_SIZE
;
441 //wait until printing is done
442 SfxPrinter
* pDocPrinter
= pViewSh
->GetPrinter();
443 while ( pDocPrinter
->IsPrinting() )
444 Application::Yield();
447 void SAL_CALL
SfxPrintHelper::setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
)
448 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
450 // object already disposed?
451 SolarMutexGuard aGuard
;
453 SfxViewShell
* pViewSh
= NULL
;
454 SfxPrinter
* pPrinter
= NULL
;
455 sal_uInt16 nChangeFlags
= 0;
456 impl_setPrinter(rPrinter
,pPrinter
,nChangeFlags
,pViewSh
);
458 if ( pViewSh
&& pPrinter
)
459 pViewSh
->SetPrinter( pPrinter
, nChangeFlags
, false );
462 //________________________________________________________________________________________________________
463 // ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
464 //________________________________________________________________________________________________________
466 /* This implements a thread which will be started to wait for asynchronous
467 print jobs to temp. localy files. If they finish we move the temp. files
468 to her right locations by using the ucb.
470 class ImplUCBPrintWatcher
: public ::osl::Thread
473 /// of course we must know the printer which execute the job
474 SfxPrinter
* m_pPrinter
;
475 /// this describes the target location for the printed temp file
477 /// it holds the temp file alive, till the print job will finish and remove it from disk automaticly if the object die
478 ::utl::TempFile
* m_pTempFile
;
481 /* initialize this watcher but don't start it */
482 ImplUCBPrintWatcher( SfxPrinter
* pPrinter
, ::utl::TempFile
* pTempFile
, const String
& sTargetURL
)
483 : m_pPrinter ( pPrinter
)
484 , m_sTargetURL( sTargetURL
)
485 , m_pTempFile ( pTempFile
)
488 /* waits for finishing of the print job and moves the temp file afterwards
489 Note: Starting of the job is done outside this thread!
490 But we have to free some of the given resources on heap!
496 SolarMutexGuard aGuard
;
497 while( m_pPrinter
->IsPrinting() )
498 Application::Yield();
499 m_pPrinter
= NULL
; // don't delete it! It's borrowed only :-)
503 // lock for further using of our member isn't necessary - because
504 // we truns alone by defenition. Nobody join for us nor use us ...
505 moveAndDeleteTemp(&m_pTempFile
,m_sTargetURL
);
507 // finishing of this run() method will call onTerminate() automaticly
508 // kill this thread there!
511 /* nobody wait for this thread. We must kill ourself ...
513 void SAL_CALL
onTerminated()
518 /* static helper to move the temp. file to the target location by using the ucb
519 It's static to be useable from outside too. So it's not realy neccessary to start
520 the thread, if finishing of the job was detected outside this thread.
521 But it must be called without using a corresponding thread for the given parameter!
523 static void moveAndDeleteTemp( ::utl::TempFile
** ppTempFile
, const String
& sTargetURL
)
528 INetURLObject
aSplitter(sTargetURL
);
529 String sFileName
= aSplitter
.getName(
530 INetURLObject::LAST_SEGMENT
,
532 INetURLObject::DECODE_WITH_CHARSET
);
533 if (aSplitter
.removeSegment() && sFileName
.Len()>0)
535 ::ucbhelper::Content
aSource(
536 OUString((*ppTempFile
)->GetURL()),
537 ::com::sun::star::uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
>(),
538 comphelper::getProcessComponentContext());
540 ::ucbhelper::Content
aTarget(
541 OUString(aSplitter
.GetMainURL(INetURLObject::NO_DECODE
)),
542 ::com::sun::star::uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
>(),
543 comphelper::getProcessComponentContext());
545 aTarget
.transferContent(
547 ::ucbhelper::InsertOperation_COPY
,
549 ::com::sun::star::ucb::NameClash::OVERWRITE
);
552 catch (const ::com::sun::star::ucb::ContentCreationException
&)
554 OSL_FAIL("content create exception");
556 catch (const ::com::sun::star::ucb::CommandAbortedException
&)
558 OSL_FAIL("command abort exception");
560 catch (const ::com::sun::star::uno::RuntimeException
&)
562 OSL_FAIL("runtime exception");
564 catch (const ::com::sun::star::uno::Exception
&)
566 OSL_FAIL("unknown exception");
569 // kill the temp file!
575 //------------------------------------------------
577 //________________________________________________________________________________________________________
579 //________________________________________________________________________________________________________
580 void SAL_CALL
SfxPrintHelper::print(const uno::Sequence
< beans::PropertyValue
>& rOptions
)
581 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
583 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
586 // object already disposed?
587 // object already disposed?
588 SolarMutexGuard aGuard
;
590 // get view for sfx printing capabilities
591 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.Is() ?
592 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
, sal_False
) : 0;
595 SfxViewShell
* pView
= pViewFrm
->GetViewShell();
598 sal_Bool bMonitor
= sal_False
;
599 // We need this information at the end of this method, if we start the vcl printer
600 // by executing the slot. Because if it is a ucb relevant URL we must wait for
601 // finishing the print job and move the temporary local file by using the ucb
602 // to the right location. But in case of no file name is given or it is already
603 // a local one we can supress this special handling. Because then vcl makes all
606 ::utl::TempFile
* pUCBPrintTempFile
= NULL
;
608 uno::Sequence
< beans::PropertyValue
> aCheckedArgs( rOptions
.getLength() );
609 sal_Int32 nProps
= 0;
610 sal_Bool bWaitUntilEnd
= sal_False
;
611 sal_Int16 nDuplexMode
= ::com::sun::star::view::DuplexMode::UNKNOWN
;
612 for ( int n
= 0; n
< rOptions
.getLength(); ++n
)
614 // get Property-Value from options
615 const beans::PropertyValue
&rProp
= rOptions
.getConstArray()[n
];
617 // FileName-Property?
618 if ( rProp
.Name
.compareToAscii( "FileName" ) == 0 )
620 // unpack th URL and check for a valid and well known protocol
623 ( rProp
.Value
.getValueType()!=::getCppuType((const OUString
*)0)) ||
624 (!(rProp
.Value
>>=sTemp
))
627 throw ::com::sun::star::lang::IllegalArgumentException();
631 OUString
sURL (sTemp
);
632 INetURLObject
aCheck(sURL
);
633 if (aCheck
.GetProtocol()==INET_PROT_NOT_VALID
)
635 // OK - it's not a valid URL. But may it's a simple
636 // system path directly. It will be supported for historical
637 // reasons. Otherwhise we break to much external code ...
638 // We try to convert it to a file URL. If its possible
639 // we put the system path to the item set and let vcl work with it.
640 // No ucb or thread will be necessary then. In case it couldnt be
641 // converted its not an URL nor a system path. Then we can't accept
642 // this parameter and have to throw an exception.
643 OUString
sSystemPath(sTemp
);
645 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath
,sFileURL
)!=::osl::FileBase::E_None
)
646 throw ::com::sun::star::lang::IllegalArgumentException();
647 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
648 aCheckedArgs
[nProps
++].Value
<<= sFileURL
;
649 // and append the local filename
650 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
651 aCheckedArgs
[nProps
].Name
= OUString("LocalFileName");
652 aCheckedArgs
[nProps
++].Value
<<= OUString( sTemp
);
655 // It's a valid URL. but now we must know, if it is a local one or not.
656 // It's a question of using ucb or not!
657 if (::utl::LocalFileHelper::ConvertURLToSystemPath(sURL
,sPath
))
659 // it's a local file, we can use vcl without special handling
660 // And we have to use the system notation of the incoming URL.
661 // But it into the descriptor and let the slot be executed at
662 // the end of this method.
663 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
664 aCheckedArgs
[nProps
++].Value
<<= sTemp
;
665 // and append the local filename
666 aCheckedArgs
.realloc( aCheckedArgs
.getLength()+1 );
667 aCheckedArgs
[nProps
].Name
= OUString("LocalFileName");
668 aCheckedArgs
[nProps
++].Value
<<= sPath
;
672 // it's an ucb target. So we must use a temp. file for vcl
673 // and move it after printing by using the ucb.
674 // Create a temp file on the heap (because it must delete the
675 // real file on disk automaticly if it die - bt we have to share it with
676 // some other sources ... e.g. the ImplUCBPrintWatcher).
677 // And we put the name of this temp file to the descriptor instead
678 // of the URL. The URL we save for later using separately.
679 // Execution of the print job will be done later by executing
681 pUCBPrintTempFile
= new ::utl::TempFile();
682 pUCBPrintTempFile
->EnableKillingFile();
684 //FIXME: does it work?
685 aCheckedArgs
[nProps
].Name
= "LocalFileName";
686 aCheckedArgs
[nProps
++].Value
<<= OUString( pUCBPrintTempFile
->GetFileName() );
691 // CopyCount-Property
692 else if ( rProp
.Name
.compareToAscii( "CopyCount" ) == 0 )
694 sal_Int32 nCopies
= 0;
695 if ( ( rProp
.Value
>>= nCopies
) == sal_False
)
696 throw ::com::sun::star::lang::IllegalArgumentException();
698 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
699 aCheckedArgs
[nProps
++].Value
<<= nCopies
;
703 // Sort-Property (deprecated)
704 else if ( rProp
.Name
.compareToAscii( "Collate" ) == 0 ||
705 ( rProp
.Name
.compareToAscii( "Sort" ) == 0 ) )
707 sal_Bool bTemp
= sal_Bool();
708 if ( rProp
.Value
>>= bTemp
)
710 aCheckedArgs
[nProps
].Name
= OUString("Collate");
711 aCheckedArgs
[nProps
++].Value
<<= bTemp
;
714 throw ::com::sun::star::lang::IllegalArgumentException();
718 else if ( rProp
.Name
.compareToAscii( "Pages" ) == 0 )
721 if( rProp
.Value
>>= sTemp
)
723 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
724 aCheckedArgs
[nProps
++].Value
<<= sTemp
;
727 throw ::com::sun::star::lang::IllegalArgumentException();
731 else if ( rProp
.Name
.compareToAscii( "MonitorVisible" ) == 0 )
733 if( !(rProp
.Value
>>= bMonitor
) )
734 throw ::com::sun::star::lang::IllegalArgumentException();
735 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
736 aCheckedArgs
[nProps
++].Value
<<= bMonitor
;
740 else if ( rProp
.Name
.compareToAscii( "Wait" ) == 0 )
742 if ( !(rProp
.Value
>>= bWaitUntilEnd
) )
743 throw ::com::sun::star::lang::IllegalArgumentException();
744 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
745 aCheckedArgs
[nProps
++].Value
<<= bWaitUntilEnd
;
748 else if ( rProp
.Name
.compareToAscii( "DuplexMode" ) == 0 )
750 if ( !(rProp
.Value
>>= nDuplexMode
) )
751 throw ::com::sun::star::lang::IllegalArgumentException();
752 aCheckedArgs
[nProps
].Name
= rProp
.Name
;
753 aCheckedArgs
[nProps
++].Value
<<= nDuplexMode
;
757 if ( nProps
!= aCheckedArgs
.getLength() )
758 aCheckedArgs
.realloc(nProps
);
760 // Execute the print request every time.
761 // It doesn'tmatter if it is a real printer used or we print to a local file
762 // nor if we print to a temp file and move it afterwards by using the ucb.
763 // That will be handled later. see pUCBPrintFile below!
764 pView
->ExecPrint( aCheckedArgs
, sal_True
, sal_False
);
766 // Ok - may be execution before has finished (or started!) printing.
767 // And may it was a printing to a file.
768 // Now we have to check if we can move the file (if necessary) via ucb to his right location.
770 // a) printing finished => move the file directly and forget the watcher thread
771 // b) printing is asynchron and runs currently => start watcher thread and exit this method
772 // This thread make all necessary things by itself.
773 if (pUCBPrintTempFile
!=NULL
)
776 SfxPrinter
* pPrinter
= pView
->GetPrinter();
777 if ( ! pPrinter
->IsPrinting() )
778 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile
,sUcbUrl
);
782 // Note: we create(d) some resource on the heap. (thread and tep file)
783 // They will be delected by the thread automaticly if he finish his run() method.
784 ImplUCBPrintWatcher
* pWatcher
= new ImplUCBPrintWatcher( pPrinter
, pUCBPrintTempFile
, sUcbUrl
);
790 void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
792 if ( &rBC
== m_pObjectShell
)
794 SfxPrintingHint
* pPrintHint
= PTR_CAST( SfxPrintingHint
, &rHint
);
797 if ( pPrintHint
->GetWhich() == com::sun::star::view::PrintableState_JOB_STARTED
)
799 if ( !m_xPrintJob
.is() )
800 m_xPrintJob
= new SfxPrintJob_Impl( this );
801 m_aPrintOptions
= pPrintHint
->GetOptions();
803 else if ( pPrintHint
->GetWhich() != -2 ) // -2 : CancelPrintJob
805 view::PrintJobEvent aEvent
;
806 aEvent
.Source
= m_xPrintJob
;
807 aEvent
.State
= (com::sun::star::view::PrintableState
) pPrintHint
->GetWhich();
808 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aInterfaceContainer
.getContainer( ::getCppuType( ( const uno::Reference
< view::XPrintJobListener
>*) NULL
) );
809 if ( pContainer
!=NULL
)
811 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
812 while (pIterator
.hasMoreElements())
813 ((view::XPrintJobListener
*)pIterator
.next())->printJobEvent( aEvent
);
820 void SAL_CALL
SfxPrintHelper::addPrintJobListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::view::XPrintJobListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
822 SolarMutexGuard aGuard
;
823 m_pData
->m_aInterfaceContainer
.addInterface( ::getCppuType((const uno::Reference
< view::XPrintJobListener
>*)0), xListener
);
826 void SAL_CALL
SfxPrintHelper::removePrintJobListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::view::XPrintJobListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
828 SolarMutexGuard aGuard
;
829 m_pData
->m_aInterfaceContainer
.removeInterface( ::getCppuType((const uno::Reference
< view::XPrintJobListener
>*)0), xListener
);
833 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */