1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: printhelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include "printhelper.hxx"
36 #include <com/sun/star/view/XPrintJob.hpp>
37 #include <com/sun/star/awt/Size.hpp>
38 #include <com/sun/star/lang/IllegalArgumentException.hpp>
39 #include <com/sun/star/view/PaperFormat.hpp>
40 #include <com/sun/star/view/PaperOrientation.hpp>
41 #include <com/sun/star/ucb/NameClash.hpp>
42 #include <com/sun/star/lang/XUnoTunnel.hpp>
43 #include <com/sun/star/frame/XModel.hpp>
44 #include <com/sun/star/lang/EventObject.hpp>
46 #include <svtools/lstner.hxx>
47 #include <svtools/stritem.hxx>
48 #include <svtools/intitem.hxx>
49 #include <svtools/eitem.hxx>
50 #include <unotools/tempfile.hxx>
51 #include <unotools/localfilehelper.hxx>
52 #include <osl/file.hxx>
53 #include <osl/thread.hxx>
54 #include <tools/urlobj.hxx>
55 #include <ucbhelper/content.hxx>
56 #include <cppuhelper/interfacecontainer.hxx>
57 #include <vos/mutex.hxx>
58 #include <svtools/printdlg.hxx>
59 #include <cppuhelper/implbase1.hxx>
61 #include <sfx2/viewfrm.hxx>
62 #include <sfx2/viewsh.hxx>
63 #include <sfx2/dispatch.hxx>
64 #include <sfx2/request.hxx>
65 #include <sfx2/printer.hxx>
66 #include <sfx2/app.hxx>
67 #include <sfx2/objsh.hxx>
68 #include <sfx2/event.hxx>
70 using namespace ::com::sun::star
;
71 using namespace ::com::sun::star::uno
;
73 struct IMPL_PrintListener_DataContainer
: public SfxListener
75 SfxObjectShellRef m_pObjectShell
;
76 ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer
;
77 uno::Reference
< com::sun::star::view::XPrintJob
> m_xPrintJob
;
78 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> m_aPrintOptions
;
80 IMPL_PrintListener_DataContainer( ::osl::Mutex
& aMutex
)
81 : m_pObjectShell ( 0 )
82 , m_aInterfaceContainer ( aMutex
)
87 void Notify( SfxBroadcaster
& aBC
,
88 const SfxHint
& aHint
) ;
91 awt::Size
impl_Size_Object2Struct( const Size
& aSize
)
93 awt::Size aReturnValue
;
94 aReturnValue
.Width
= aSize
.Width() ;
95 aReturnValue
.Height
= aSize
.Height() ;
99 Size
impl_Size_Struct2Object( const awt::Size
& aSize
)
102 aReturnValue
.Width() = aSize
.Width
;
103 aReturnValue
.Height() = aSize
.Height
;
104 return aReturnValue
;
107 class SfxPrintJob_Impl
: public cppu::WeakImplHelper1
109 com::sun::star::view::XPrintJob
112 IMPL_PrintListener_DataContainer
* m_pData
;
115 SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
);
116 virtual Sequence
< ::com::sun::star::beans::PropertyValue
> SAL_CALL
getPrintOptions( ) throw (RuntimeException
);
117 virtual Sequence
< ::com::sun::star::beans::PropertyValue
> SAL_CALL
getPrinter( ) throw (RuntimeException
);
118 virtual Reference
< ::com::sun::star::view::XPrintable
> SAL_CALL
getPrintable( ) throw (RuntimeException
);
119 virtual void SAL_CALL
cancelJob() throw (RuntimeException
);
122 SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer
* pData
)
127 Sequence
< ::com::sun::star::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrintOptions() throw (RuntimeException
)
129 return m_pData
->m_aPrintOptions
;
132 Sequence
< ::com::sun::star::beans::PropertyValue
> SAL_CALL
SfxPrintJob_Impl::getPrinter() throw (RuntimeException
)
134 if( m_pData
->m_pObjectShell
.Is() )
136 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
->GetModel(), UNO_QUERY
);
137 if ( xPrintable
.is() )
138 return xPrintable
->getPrinter();
140 return Sequence
< ::com::sun::star::beans::PropertyValue
>();
143 Reference
< ::com::sun::star::view::XPrintable
> SAL_CALL
SfxPrintJob_Impl::getPrintable() throw (RuntimeException
)
145 Reference
< view::XPrintable
> xPrintable( m_pData
->m_pObjectShell
.Is() ? m_pData
->m_pObjectShell
->GetModel() : NULL
, UNO_QUERY
);
149 void SAL_CALL
SfxPrintJob_Impl::cancelJob() throw (RuntimeException
)
151 if( m_pData
->m_pObjectShell
.Is() )
152 m_pData
->m_pObjectShell
->Broadcast( SfxPrintingHint( -2, NULL
, NULL
) );
155 SfxPrintHelper::SfxPrintHelper()
157 m_pData
= new IMPL_PrintListener_DataContainer(m_aMutex
);
160 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
)
162 if ( aArguments
.getLength() )
164 com::sun::star::uno::Reference
< com::sun::star::frame::XModel
> xModel
;
165 aArguments
[0] >>= xModel
;
166 uno::Reference
< lang::XUnoTunnel
> xObj( xModel
, uno::UNO_QUERY
);
167 uno::Sequence
< sal_Int8
> aSeq( SvGlobalName( SFX_GLOBAL_CLASSID
).GetByteSequence() );
168 sal_Int64 nHandle
= xObj
->getSomething( aSeq
);
171 m_pData
->m_pObjectShell
= reinterpret_cast< SfxObjectShell
* >( sal::static_int_cast
< sal_IntPtr
>( nHandle
));
172 m_pData
->StartListening(*m_pData
->m_pObjectShell
);
177 SfxPrintHelper::~SfxPrintHelper()
184 view::PaperFormat
convertToPaperFormat(Paper eFormat
)
186 view::PaperFormat eRet
;
190 eRet
= view::PaperFormat_A3
;
193 eRet
= view::PaperFormat_A4
;
196 eRet
= view::PaperFormat_A5
;
199 eRet
= view::PaperFormat_B4
;
202 eRet
= view::PaperFormat_B5
;
205 eRet
= view::PaperFormat_LETTER
;
208 eRet
= view::PaperFormat_LEGAL
;
211 eRet
= view::PaperFormat_TABLOID
;
215 eRet
= view::PaperFormat_USER
;
221 Paper
convertToPaper(view::PaperFormat eFormat
)
223 Paper
eRet(PAPER_USER
);
226 case view::PaperFormat_A3
:
229 case view::PaperFormat_A4
:
232 case view::PaperFormat_A5
:
235 case view::PaperFormat_B4
:
238 case view::PaperFormat_B5
:
241 case view::PaperFormat_LETTER
:
244 case view::PaperFormat_LEGAL
:
247 case view::PaperFormat_TABLOID
:
248 eRet
= PAPER_TABLOID
;
250 case view::PaperFormat_USER
:
253 case view::PaperFormat_MAKE_FIXED_SIZE
:
255 //deliberate no default to force warn on a new papersize
261 //________________________________________________________________________________________________________
263 //________________________________________________________________________________________________________
265 uno::Sequence
< beans::PropertyValue
> SAL_CALL
SfxPrintHelper::getPrinter() throw(::com::sun::star::uno::RuntimeException
)
267 // object already disposed?
268 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
270 // Printer beschaffen
271 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.Is() ?
272 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
, 0, sal_False
) : 0;
274 return uno::Sequence
< beans::PropertyValue
>();
276 const SfxPrinter
*pPrinter
= pViewFrm
->GetViewShell()->GetPrinter(sal_True
);
278 return uno::Sequence
< beans::PropertyValue
>();
280 // Printer Eigenschaften uebertragen
281 uno::Sequence
< beans::PropertyValue
> aPrinter(8);
283 aPrinter
.getArray()[7].Name
= DEFINE_CONST_UNICODE( "CanSetPaperSize" );
284 aPrinter
.getArray()[7].Value
<<= ( pPrinter
->HasSupport( SUPPORT_SET_PAPERSIZE
) );
286 aPrinter
.getArray()[6].Name
= DEFINE_CONST_UNICODE( "CanSetPaperFormat" );
287 aPrinter
.getArray()[6].Value
<<= ( pPrinter
->HasSupport( SUPPORT_SET_PAPER
) );
289 aPrinter
.getArray()[5].Name
= DEFINE_CONST_UNICODE( "CanSetPaperOrientation" );
290 aPrinter
.getArray()[5].Value
<<= ( pPrinter
->HasSupport( SUPPORT_SET_ORIENTATION
) );
292 aPrinter
.getArray()[4].Name
= DEFINE_CONST_UNICODE( "IsBusy" );
293 aPrinter
.getArray()[4].Value
<<= ( pPrinter
->IsPrinting() );
295 aPrinter
.getArray()[3].Name
= DEFINE_CONST_UNICODE( "PaperSize" );
296 awt::Size aSize
= impl_Size_Object2Struct(pPrinter
->GetPaperSize() );
297 aPrinter
.getArray()[3].Value
<<= aSize
;
299 aPrinter
.getArray()[2].Name
= DEFINE_CONST_UNICODE( "PaperFormat" );
300 view::PaperFormat eFormat
= convertToPaperFormat(pPrinter
->GetPaper());
301 aPrinter
.getArray()[2].Value
<<= eFormat
;
303 aPrinter
.getArray()[1].Name
= DEFINE_CONST_UNICODE( "PaperOrientation" );
304 view::PaperOrientation eOrient
= (view::PaperOrientation
)pPrinter
->GetOrientation();
305 aPrinter
.getArray()[1].Value
<<= eOrient
;
307 aPrinter
.getArray()[0].Name
= DEFINE_CONST_UNICODE( "Name" );
308 String sStringTemp
= pPrinter
->GetName() ;
309 aPrinter
.getArray()[0].Value
<<= ::rtl::OUString( sStringTemp
);
314 //________________________________________________________________________________________________________
316 //________________________________________________________________________________________________________
318 void SfxPrintHelper::impl_setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
,SfxPrinter
*& pPrinter
,sal_uInt16
& nChangeFlags
,SfxViewShell
*& pViewSh
)
321 // alten Printer beschaffen
322 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.Is() ?
323 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
, 0, sal_False
) : 0;
327 pViewSh
= pViewFrm
->GetViewShell();
328 pPrinter
= pViewSh
->GetPrinter(sal_True
);
332 // new Printer-Name available?
334 sal_Int32 lDummy
= 0;
335 for ( int n
= 0; n
< rPrinter
.getLength(); ++n
)
337 // get Property-Value from printer description
338 const beans::PropertyValue
&rProp
= rPrinter
.getConstArray()[n
];
341 if ( rProp
.Name
.compareToAscii( "Name" ) == 0 )
344 if ( ( rProp
.Value
>>= sTemp
) == sal_False
)
345 throw ::com::sun::star::lang::IllegalArgumentException();
347 String
aPrinterName( sTemp
) ;
348 if ( aPrinterName
!= pPrinter
->GetName() )
350 pPrinter
= new SfxPrinter( pPrinter
->GetOptions().Clone(), aPrinterName
);
351 nChangeFlags
= SFX_PRINTER_PRINTER
;
357 Size
aSetPaperSize( 0, 0);
358 view::PaperFormat nPaperFormat
= view::PaperFormat_USER
;
361 for ( int i
= 0; i
< rPrinter
.getLength(); ++i
)
363 // get Property-Value from printer description
364 const beans::PropertyValue
&rProp
= rPrinter
.getConstArray()[i
];
366 // PaperOrientation-Property?
367 if ( rProp
.Name
.compareToAscii( "PaperOrientation" ) == 0 )
369 view::PaperOrientation eOrient
;
370 if ( ( rProp
.Value
>>= eOrient
) == sal_False
)
372 if ( ( rProp
.Value
>>= lDummy
) == sal_False
)
373 throw ::com::sun::star::lang::IllegalArgumentException();
374 eOrient
= ( view::PaperOrientation
) lDummy
;
377 if ( (Orientation
) eOrient
!= pPrinter
->GetOrientation() )
379 pPrinter
->SetOrientation( (Orientation
) eOrient
);
380 nChangeFlags
|= SFX_PRINTER_CHG_ORIENTATION
;
384 // PaperFormat-Property?
385 else if ( rProp
.Name
.compareToAscii( "PaperFormat" ) == 0 )
387 if ( ( rProp
.Value
>>= nPaperFormat
) == sal_False
)
389 if ( ( rProp
.Value
>>= lDummy
) == sal_False
)
390 throw ::com::sun::star::lang::IllegalArgumentException();
391 nPaperFormat
= ( view::PaperFormat
) lDummy
;
394 if ( convertToPaper(nPaperFormat
) != pPrinter
->GetPaper() )
396 pPrinter
->SetPaper( convertToPaper(nPaperFormat
) );
397 nChangeFlags
|= SFX_PRINTER_CHG_SIZE
;
401 // PaperSize-Property?
402 else if ( rProp
.Name
.compareToAscii( "PaperSize" ) == 0 )
404 awt::Size aTempSize
;
405 if ( ( rProp
.Value
>>= aTempSize
) == sal_False
)
407 throw ::com::sun::star::lang::IllegalArgumentException();
411 aSetPaperSize
= impl_Size_Struct2Object(aTempSize
);
415 // PrinterTray-Property
416 else if ( rProp
.Name
.compareToAscii( "PrinterPaperTray" ) == 0 )
419 if ( ( rProp
.Value
>>= aTmp
) == sal_False
)
420 throw ::com::sun::star::lang::IllegalArgumentException();
421 USHORT nCount
= pPrinter
->GetPaperBinCount();
422 for (USHORT nBin
=0; nBin
<nCount
; nBin
++)
424 ::rtl::OUString
aName( pPrinter
->GetPaperBinName(nBin
) );
427 pPrinter
->SetPaperBin(nBin
);
434 //os 12.11.98: die PaperSize darf nur gesetzt werden, wenn tatsaechlich
435 //PAPER_USER gilt, sonst koennte vom Treiber ein falsches Format gewaehlt werden
436 if(nPaperFormat
== view::PaperFormat_USER
&& aSetPaperSize
.Width())
438 //JP 23.09.98 - Bug 56929 - MapMode von 100mm in die am
439 // Device gesetzten umrechnen. Zusaetzlich nur dann
440 // setzen, wenn sie wirklich veraendert wurden.
441 aSetPaperSize
= pPrinter
->LogicToPixel( aSetPaperSize
, MAP_100TH_MM
);
442 if( aSetPaperSize
!= pPrinter
->GetPaperSizePixel() )
444 pPrinter
->SetPaperSizeUser( pPrinter
->PixelToLogic( aSetPaperSize
) );
445 nChangeFlags
|= SFX_PRINTER_CHG_SIZE
;
449 // #96772#: wait until printing is done
450 SfxPrinter
* pDocPrinter
= pViewSh
->GetPrinter();
451 while ( pDocPrinter
->IsPrinting() )
452 Application::Yield();
455 void SAL_CALL
SfxPrintHelper::setPrinter(const uno::Sequence
< beans::PropertyValue
>& rPrinter
)
456 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
458 // object already disposed?
459 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
461 SfxViewShell
* pViewSh
= NULL
;
462 SfxPrinter
* pPrinter
= NULL
;
463 sal_uInt16 nChangeFlags
= 0;
464 impl_setPrinter(rPrinter
,pPrinter
,nChangeFlags
,pViewSh
);
466 if ( pViewSh
&& pPrinter
)
467 pViewSh
->SetPrinter( pPrinter
, nChangeFlags
, false );
470 //________________________________________________________________________________________________________
471 // ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
472 //________________________________________________________________________________________________________
474 /* This implements a thread which will be started to wait for asynchronous
475 print jobs to temp. localy files. If they finish we move the temp. files
476 to her right locations by using the ucb.
478 class ImplUCBPrintWatcher
: public ::osl::Thread
481 /// of course we must know the printer which execute the job
482 SfxPrinter
* m_pPrinter
;
483 /// this describes the target location for the printed temp file
485 /// it holds the temp file alive, till the print job will finish and remove it from disk automaticly if the object die
486 ::utl::TempFile
* m_pTempFile
;
489 /* initialize this watcher but don't start it */
490 ImplUCBPrintWatcher( SfxPrinter
* pPrinter
, ::utl::TempFile
* pTempFile
, const String
& sTargetURL
)
491 : m_pPrinter ( pPrinter
)
492 , m_sTargetURL( sTargetURL
)
493 , m_pTempFile ( pTempFile
)
496 /* waits for finishing of the print job and moves the temp file afterwards
497 Note: Starting of the job is done outside this thread!
498 But we have to free some of the given ressources on heap!
504 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
505 while( m_pPrinter
->IsPrinting() )
506 Application::Yield();
507 m_pPrinter
= NULL
; // don't delete it! It's borrowed only :-)
511 // lock for further using of our member isn't neccessary - because
512 // we truns alone by defenition. Nobody join for us nor use us ...
513 ImplUCBPrintWatcher::moveAndDeleteTemp(&m_pTempFile
,m_sTargetURL
);
515 // finishing of this run() method will call onTerminate() automaticly
516 // kill this thread there!
519 /* nobody wait for this thread. We must kill ourself ...
521 void SAL_CALL
onTerminated()
526 /* static helper to move the temp. file to the target location by using the ucb
527 It's static to be useable from outside too. So it's not realy neccessary to start
528 the thread, if finishing of the job was detected outside this thread.
529 But it must be called without using a corresponding thread for the given parameter!
531 static void moveAndDeleteTemp( ::utl::TempFile
** ppTempFile
, const String
& sTargetURL
)
536 INetURLObject
aSplitter(sTargetURL
);
537 String sFileName
= aSplitter
.getName(
538 INetURLObject::LAST_SEGMENT
,
540 INetURLObject::DECODE_WITH_CHARSET
);
541 if (aSplitter
.removeSegment() && sFileName
.Len()>0)
543 ::ucbhelper::Content
aSource(
544 ::rtl::OUString((*ppTempFile
)->GetURL()),
545 ::com::sun::star::uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
>());
547 ::ucbhelper::Content
aTarget(
548 ::rtl::OUString(aSplitter
.GetMainURL(INetURLObject::NO_DECODE
)),
549 ::com::sun::star::uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
>());
551 aTarget
.transferContent(
553 ::ucbhelper::InsertOperation_COPY
,
554 ::rtl::OUString(sFileName
),
555 ::com::sun::star::ucb::NameClash::OVERWRITE
);
558 catch( ::com::sun::star::ucb::ContentCreationException
& ) { DBG_ERROR("content create exception"); }
559 catch( ::com::sun::star::ucb::CommandAbortedException
& ) { DBG_ERROR("command abort exception"); }
560 catch( ::com::sun::star::uno::RuntimeException
& ) { DBG_ERROR("runtime exception"); }
561 catch( ::com::sun::star::uno::Exception
& ) { DBG_ERROR("unknown exception"); }
563 // kill the temp file!
569 //------------------------------------------------
571 //________________________________________________________________________________________________________
573 //________________________________________________________________________________________________________
574 void SAL_CALL
SfxPrintHelper::print(const uno::Sequence
< beans::PropertyValue
>& rOptions
)
575 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
577 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
580 // object already disposed?
581 // object already disposed?
582 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
584 // get view for sfx printing capabilities
585 SfxViewFrame
*pViewFrm
= m_pData
->m_pObjectShell
.Is() ?
586 SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
, 0, sal_False
) : 0;
589 SfxViewShell
* pView
= pViewFrm
->GetViewShell();
593 SfxAllItemSet
aArgs( pView
->GetPool() );
594 sal_Bool bMonitor
= sal_False
;
595 // We need this information at the end of this method, if we start the vcl printer
596 // by executing the slot. Because if it is a ucb relevant URL we must wait for
597 // finishing the print job and move the temporary local file by using the ucb
598 // to the right location. But in case of no file name is given or it is already
599 // a local one we can supress this special handling. Because then vcl makes all
602 ::utl::TempFile
* pUCBPrintTempFile
= NULL
;
604 sal_Bool bWaitUntilEnd
= sal_False
;
605 for ( int n
= 0; n
< rOptions
.getLength(); ++n
)
607 // get Property-Value from options
608 const beans::PropertyValue
&rProp
= rOptions
.getConstArray()[n
];
610 // FileName-Property?
611 if ( rProp
.Name
.compareToAscii( "FileName" ) == 0 )
613 // unpack th URL and check for a valid and well known protocol
616 ( rProp
.Value
.getValueType()!=::getCppuType((const OUSTRING
*)0)) ||
617 (!(rProp
.Value
>>=sTemp
))
620 throw ::com::sun::star::lang::IllegalArgumentException();
625 INetURLObject
aCheck(sURL
);
626 if (aCheck
.GetProtocol()==INET_PROT_NOT_VALID
)
628 // OK - it's not a valid URL. But may it's a simple
629 // system path directly. It will be supported for historical
630 // reasons. Otherwhise we break to much external code ...
631 // We try to convert it to a file URL. If its possible
632 // we put the system path to the item set and let vcl work with it.
633 // No ucb or thread will be neccessary then. In case it couldnt be
634 // converted its not an URL nor a system path. Then we can't accept
635 // this parameter and have to throw an exception.
636 ::rtl::OUString
sSystemPath(sTemp
);
637 ::rtl::OUString sFileURL
;
638 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath
,sFileURL
)!=::osl::FileBase::E_None
)
639 throw ::com::sun::star::lang::IllegalArgumentException();
640 aArgs
.Put( SfxStringItem(SID_FILE_NAME
,sTemp
) );
643 // It's a valid URL. but now we must know, if it is a local one or not.
644 // It's a question of using ucb or not!
645 if (::utl::LocalFileHelper::ConvertURLToSystemPath(sURL
,sPath
))
647 // it's a local file, we can use vcl without special handling
648 // And we have to use the system notation of the incoming URL.
649 // But it into the descriptor and let the slot be executed at
650 // the end of this method.
651 aArgs
.Put( SfxStringItem(SID_FILE_NAME
,sPath
) );
655 // it's an ucb target. So we must use a temp. file for vcl
656 // and move it after printing by using the ucb.
657 // Create a temp file on the heap (because it must delete the
658 // real file on disk automaticly if it die - bt we have to share it with
659 // some other sources ... e.g. the ImplUCBPrintWatcher).
660 // And we put the name of this temp file to the descriptor instead
661 // of the URL. The URL we save for later using seperatly.
662 // Execution of the print job will be done later by executing
664 pUCBPrintTempFile
= new ::utl::TempFile();
665 pUCBPrintTempFile
->EnableKillingFile();
666 aArgs
.Put( SfxStringItem(SID_FILE_NAME
,pUCBPrintTempFile
->GetFileName()) );
671 // CopyCount-Property
672 else if ( rProp
.Name
.compareToAscii( "CopyCount" ) == 0 )
674 sal_Int32 nCopies
= 0;
675 if ( ( rProp
.Value
>>= nCopies
) == sal_False
)
676 throw ::com::sun::star::lang::IllegalArgumentException();
677 aArgs
.Put( SfxInt16Item( SID_PRINT_COPIES
, (USHORT
) nCopies
) );
681 else if ( rProp
.Name
.compareToAscii( "Collate" ) == 0 )
683 sal_Bool bTemp
= sal_Bool();
684 if ( rProp
.Value
>>= bTemp
)
685 aArgs
.Put( SfxBoolItem( SID_PRINT_COLLATE
, bTemp
) );
687 throw ::com::sun::star::lang::IllegalArgumentException();
691 else if ( rProp
.Name
.compareToAscii( "Sort" ) == 0 )
693 sal_Bool bTemp
= sal_Bool();
694 if( rProp
.Value
>>= bTemp
)
695 aArgs
.Put( SfxBoolItem( SID_PRINT_SORT
, bTemp
) );
697 throw ::com::sun::star::lang::IllegalArgumentException();
701 else if ( rProp
.Name
.compareToAscii( "Pages" ) == 0 )
704 if( rProp
.Value
>>= sTemp
)
705 aArgs
.Put( SfxStringItem( SID_PRINT_PAGES
, String( sTemp
) ) );
707 throw ::com::sun::star::lang::IllegalArgumentException();
711 else if ( rProp
.Name
.compareToAscii( "MonitorVisible" ) == 0 )
713 if( !(rProp
.Value
>>= bMonitor
) )
714 throw ::com::sun::star::lang::IllegalArgumentException();
718 else if ( rProp
.Name
.compareToAscii( "Wait" ) == 0 )
720 if ( !(rProp
.Value
>>= bWaitUntilEnd
) )
721 throw ::com::sun::star::lang::IllegalArgumentException();
725 // Execute the print request every time.
726 // It doesn'tmatter if it is a real printer used or we print to a local file
727 // nor if we print to a temp file and move it afterwards by using the ucb.
728 // That will be handled later. see pUCBPrintFile below!
729 aArgs
.Put( SfxBoolItem( SID_SILENT
, !bMonitor
) );
731 aArgs
.Put( SfxBoolItem( SID_ASYNCHRON
, sal_False
) );
732 SfxRequest
aReq( SID_PRINTDOC
, SFX_CALLMODE_SYNCHRON
| SFX_CALLMODE_API
, pView
->GetPool() );
733 aReq
.SetArgs( aArgs
);
734 pView
->ExecuteSlot( aReq
);
736 // Ok - may be execution before has finished (or started!) printing.
737 // And may it was a printing to a file.
738 // Now we have to check if we can move the file (if neccessary) via ucb to his right location.
740 // a) printing finished => move the file directly and forget the watcher thread
741 // b) printing is asynchron and runs currently => start watcher thread and exit this method
742 // This thread make all neccessary things by itself.
743 if (pUCBPrintTempFile
!=NULL
)
746 SfxPrinter
* pPrinter
= pView
->GetPrinter();
747 if ( ! pPrinter
->IsPrinting() )
748 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile
,sUcbUrl
);
752 // Note: we create(d) some ressource on the heap. (thread and tep file)
753 // They will be delected by the thread automaticly if he finish his run() method.
754 ImplUCBPrintWatcher
* pWatcher
= new ImplUCBPrintWatcher( pPrinter
, pUCBPrintTempFile
, sUcbUrl
);
760 void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
762 if ( &rBC
== m_pObjectShell
)
764 SfxPrintingHint
* pPrintHint
= PTR_CAST( SfxPrintingHint
, &rHint
);
767 if ( pPrintHint
->GetWhich() == -1 ) // -1 : Initialisation of PrintOptions
769 if ( !m_xPrintJob
.is() )
770 m_xPrintJob
= new SfxPrintJob_Impl( this );
772 PrintDialog
* pDlg
= pPrintHint
->GetPrintDialog();
773 Printer
* pPrinter
= pPrintHint
->GetPrinter();
774 ::rtl::OUString
aPrintFile ( ( pPrinter
&& pPrinter
->IsPrintFileEnabled() ) ? pPrinter
->GetPrintFile() : String() );
775 ::rtl::OUString
aRangeText ( ( pDlg
&& pDlg
->IsRangeChecked(PRINTDIALOG_RANGE
) ) ? pDlg
->GetRangeText() : String() );
776 sal_Bool bSelectionOnly
= ( ( pDlg
&& pDlg
->IsRangeChecked(PRINTDIALOG_SELECTION
) ) ? sal_True
: sal_False
);
779 if ( aPrintFile
.getLength() )
781 if ( aRangeText
.getLength() )
783 else if ( bSelectionOnly
)
786 m_aPrintOptions
.realloc(nArgs
);
787 m_aPrintOptions
[0].Name
= DEFINE_CONST_UNICODE("CopyCount");
788 m_aPrintOptions
[0].Value
<<= (sal_Int16
) (pPrinter
? pPrinter
->GetCopyCount() : 1 );
789 m_aPrintOptions
[1].Name
= DEFINE_CONST_UNICODE("Collate");
790 m_aPrintOptions
[1].Value
<<= (sal_Bool
) (pDlg
? pDlg
->IsCollateChecked() : sal_False
);
792 if ( bSelectionOnly
)
794 m_aPrintOptions
[2].Name
= DEFINE_CONST_UNICODE("Selection");
795 m_aPrintOptions
[2].Value
<<= bSelectionOnly
;
797 else if ( aRangeText
.getLength() )
799 m_aPrintOptions
[2].Name
= DEFINE_CONST_UNICODE("Pages");
800 m_aPrintOptions
[2].Value
<<= aRangeText
;
803 if ( aPrintFile
.getLength() )
805 m_aPrintOptions
[nArgs
-1].Name
= DEFINE_CONST_UNICODE("FileName");
806 m_aPrintOptions
[nArgs
-1].Value
<<= aPrintFile
;
809 else if ( pPrintHint
->GetWhich() == -3 ) // -3 : AdditionalPrintOptions
811 uno::Sequence
< beans::PropertyValue
>& lOldOpts
= m_aPrintOptions
;
812 const uno::Sequence
< beans::PropertyValue
>& lNewOpts
= pPrintHint
->GetAdditionalOptions();
813 sal_Int32 nOld
= lOldOpts
.getLength();
814 sal_Int32 nAdd
= lNewOpts
.getLength();
815 lOldOpts
.realloc( nOld
+ nAdd
);
817 // assume that all new elements are overwriting old ones and so don't need to be added
818 sal_Int32 nTotal
= nOld
;
819 for ( sal_Int32 n
=0; n
<nAdd
; n
++ )
822 for ( m
=0; m
<nOld
; m
++ )
823 if ( lNewOpts
[n
].Name
== lOldOpts
[m
].Name
)
824 // new option overwrites old one
829 // this is a new option, so add it to the resulting sequence - counter must be incremented
830 lOldOpts
[nTotal
].Name
= lNewOpts
[n
].Name
;
831 lOldOpts
[nTotal
++].Value
= lNewOpts
[n
].Value
;
834 // overwrite old option with new value, counter stays unmodified
835 lOldOpts
[m
].Value
= lNewOpts
[n
].Value
;
838 if ( nTotal
!= lOldOpts
.getLength() )
839 // at least one new options has overwritten an old one, so we allocated too much
840 lOldOpts
.realloc( nTotal
);
842 else if ( pPrintHint
->GetWhich() != -2 ) // -2 : CancelPrintJob
844 view::PrintJobEvent aEvent
;
845 aEvent
.Source
= m_xPrintJob
;
846 aEvent
.State
= (com::sun::star::view::PrintableState
) pPrintHint
->GetWhich();
847 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aInterfaceContainer
.getContainer( ::getCppuType( ( const uno::Reference
< view::XPrintJobListener
>*) NULL
) );
848 if ( pContainer
!=NULL
)
850 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
851 while (pIterator
.hasMoreElements())
852 ((view::XPrintJobListener
*)pIterator
.next())->printJobEvent( aEvent
);
859 void SAL_CALL
SfxPrintHelper::addPrintJobListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::view::XPrintJobListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
861 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
862 m_pData
->m_aInterfaceContainer
.addInterface( ::getCppuType((const uno::Reference
< view::XPrintJobListener
>*)0), xListener
);
865 void SAL_CALL
SfxPrintHelper::removePrintJobListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::view::XPrintJobListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
867 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
868 m_pData
->m_aInterfaceContainer
.removeInterface( ::getCppuType((const uno::Reference
< view::XPrintJobListener
>*)0), xListener
);