Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / doc / printhelper.cxx
blob2728c03169f5ab4db98089782dbdee54596a1a74
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "printhelper.hxx"
32 #include <com/sun/star/view/XPrintJob.hpp>
33 #include <com/sun/star/awt/Size.hpp>
34 #include <com/sun/star/lang/IllegalArgumentException.hpp>
35 #include <com/sun/star/view/PaperFormat.hpp>
36 #include <com/sun/star/view/PaperOrientation.hpp>
37 #include <com/sun/star/ucb/NameClash.hpp>
38 #include <com/sun/star/lang/XUnoTunnel.hpp>
39 #include <com/sun/star/frame/XModel.hpp>
40 #include <com/sun/star/lang/EventObject.hpp>
41 #include <com/sun/star/view/DuplexMode.hpp>
43 #include <svl/lstner.hxx>
44 #include <svl/stritem.hxx>
45 #include <svl/intitem.hxx>
46 #include <svl/eitem.hxx>
47 #include <unotools/tempfile.hxx>
48 #include <unotools/localfilehelper.hxx>
49 #include <osl/file.hxx>
50 #include <osl/thread.hxx>
51 #include <tools/urlobj.hxx>
52 #include <ucbhelper/content.hxx>
53 #include <cppuhelper/interfacecontainer.hxx>
54 #include <osl/mutex.hxx>
55 #include <cppuhelper/implbase1.hxx>
57 #include <sfx2/viewfrm.hxx>
58 #include <sfx2/viewsh.hxx>
59 #include <sfx2/dispatch.hxx>
60 #include <sfx2/request.hxx>
61 #include <sfx2/printer.hxx>
62 #include <sfx2/app.hxx>
63 #include <sfx2/objsh.hxx>
64 #include <sfx2/event.hxx>
66 using namespace ::com::sun::star;
67 using namespace ::com::sun::star::uno;
69 struct IMPL_PrintListener_DataContainer : public SfxListener
71 SfxObjectShellRef m_pObjectShell;
72 ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer;
73 uno::Reference< com::sun::star::view::XPrintJob> m_xPrintJob;
74 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > m_aPrintOptions;
76 IMPL_PrintListener_DataContainer( ::osl::Mutex& aMutex)
77 : m_pObjectShell ( 0 )
78 , m_aInterfaceContainer ( aMutex )
83 void Notify( SfxBroadcaster& aBC ,
84 const SfxHint& aHint ) ;
87 awt::Size impl_Size_Object2Struct( const Size& aSize )
89 awt::Size aReturnValue;
90 aReturnValue.Width = aSize.Width() ;
91 aReturnValue.Height = aSize.Height() ;
92 return aReturnValue ;
95 Size impl_Size_Struct2Object( const awt::Size& aSize )
97 Size aReturnValue;
98 aReturnValue.Width() = aSize.Width ;
99 aReturnValue.Height() = aSize.Height ;
100 return aReturnValue ;
103 class SfxPrintJob_Impl : public cppu::WeakImplHelper1
105 com::sun::star::view::XPrintJob
108 IMPL_PrintListener_DataContainer* m_pData;
110 public:
111 SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData );
112 virtual Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPrintOptions( ) throw (RuntimeException);
113 virtual Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPrinter( ) throw (RuntimeException);
114 virtual Reference< ::com::sun::star::view::XPrintable > SAL_CALL getPrintable( ) throw (RuntimeException);
115 virtual void SAL_CALL cancelJob() throw (RuntimeException);
118 SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData )
119 : m_pData( pData )
123 Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrintOptions() throw (RuntimeException)
125 return m_pData->m_aPrintOptions;
128 Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrinter() throw (RuntimeException)
130 if( m_pData->m_pObjectShell.Is() )
132 Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell->GetModel(), UNO_QUERY );
133 if ( xPrintable.is() )
134 return xPrintable->getPrinter();
136 return Sequence< ::com::sun::star::beans::PropertyValue >();
139 Reference< ::com::sun::star::view::XPrintable > SAL_CALL SfxPrintJob_Impl::getPrintable() throw (RuntimeException)
141 Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->GetModel() : NULL, UNO_QUERY );
142 return xPrintable;
145 void SAL_CALL SfxPrintJob_Impl::cancelJob() throw (RuntimeException)
147 // FIXME: how to cancel PrintJob via API?!
148 if( m_pData->m_pObjectShell.Is() )
149 m_pData->m_pObjectShell->Broadcast( SfxPrintingHint( -2 ) );
152 SfxPrintHelper::SfxPrintHelper()
154 m_pData = new IMPL_PrintListener_DataContainer(m_aMutex);
157 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)
159 if ( aArguments.getLength() )
161 com::sun::star::uno::Reference < com::sun::star::frame::XModel > xModel;
162 aArguments[0] >>= xModel;
163 uno::Reference < lang::XUnoTunnel > xObj( xModel, uno::UNO_QUERY );
164 uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
165 sal_Int64 nHandle = xObj->getSomething( aSeq );
166 if ( nHandle )
168 m_pData->m_pObjectShell = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
169 m_pData->StartListening(*m_pData->m_pObjectShell);
174 SfxPrintHelper::~SfxPrintHelper()
176 delete m_pData;
179 namespace
181 view::PaperFormat convertToPaperFormat(Paper eFormat)
183 view::PaperFormat eRet;
184 switch (eFormat)
186 case PAPER_A3:
187 eRet = view::PaperFormat_A3;
188 break;
189 case PAPER_A4:
190 eRet = view::PaperFormat_A4;
191 break;
192 case PAPER_A5:
193 eRet = view::PaperFormat_A5;
194 break;
195 case PAPER_B4_ISO:
196 eRet = view::PaperFormat_B4;
197 break;
198 case PAPER_B5_ISO:
199 eRet = view::PaperFormat_B5;
200 break;
201 case PAPER_LETTER:
202 eRet = view::PaperFormat_LETTER;
203 break;
204 case PAPER_LEGAL:
205 eRet = view::PaperFormat_LEGAL;
206 break;
207 case PAPER_TABLOID:
208 eRet = view::PaperFormat_TABLOID;
209 break;
210 case PAPER_USER:
211 default:
212 eRet = view::PaperFormat_USER;
213 break;
215 return eRet;
218 Paper convertToPaper(view::PaperFormat eFormat)
220 Paper eRet(PAPER_USER);
221 switch (eFormat)
223 case view::PaperFormat_A3:
224 eRet = PAPER_A3;
225 break;
226 case view::PaperFormat_A4:
227 eRet = PAPER_A4;
228 break;
229 case view::PaperFormat_A5:
230 eRet = PAPER_A5;
231 break;
232 case view::PaperFormat_B4:
233 eRet = PAPER_B4_ISO;
234 break;
235 case view::PaperFormat_B5:
236 eRet = PAPER_B5_ISO;
237 break;
238 case view::PaperFormat_LETTER:
239 eRet = PAPER_LETTER;
240 break;
241 case view::PaperFormat_LEGAL:
242 eRet = PAPER_LEGAL;
243 break;
244 case view::PaperFormat_TABLOID:
245 eRet = PAPER_TABLOID;
246 break;
247 case view::PaperFormat_USER:
248 eRet = PAPER_USER;
249 break;
250 case view::PaperFormat_MAKE_FIXED_SIZE:
251 break;
252 //deliberate no default to force warn on a new papersize
254 return eRet;
258 //________________________________________________________________________________________________________
259 // XPrintable
260 //________________________________________________________________________________________________________
262 uno::Sequence< beans::PropertyValue > SAL_CALL SfxPrintHelper::getPrinter() throw(::com::sun::star::uno::RuntimeException)
264 // object already disposed?
265 SolarMutexGuard aGuard;
267 // search for any view of this document that is currently printing
268 const Printer *pPrinter = NULL;
269 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ? SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
270 SfxViewFrame* pFirst = pViewFrm;
271 while ( pViewFrm && !pPrinter )
273 pPrinter = pViewFrm->GetViewShell()->GetActivePrinter();
274 pViewFrm = SfxViewFrame::GetNext( *pViewFrm, m_pData->m_pObjectShell, sal_False );
277 // if no view is printing currently, use the permanent SfxPrinter instance
278 if ( !pPrinter && pFirst )
279 pPrinter = pFirst->GetViewShell()->GetPrinter(sal_True);
281 if ( !pPrinter )
282 return uno::Sequence< beans::PropertyValue >();
284 uno::Sequence< beans::PropertyValue > aPrinter(8);
286 aPrinter.getArray()[7].Name = DEFINE_CONST_UNICODE( "CanSetPaperSize" );
287 aPrinter.getArray()[7].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_PAPERSIZE ) );
289 aPrinter.getArray()[6].Name = DEFINE_CONST_UNICODE( "CanSetPaperFormat" );
290 aPrinter.getArray()[6].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_PAPER ) );
292 aPrinter.getArray()[5].Name = DEFINE_CONST_UNICODE( "CanSetPaperOrientation" );
293 aPrinter.getArray()[5].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_ORIENTATION ) );
295 aPrinter.getArray()[4].Name = DEFINE_CONST_UNICODE( "IsBusy" );
296 aPrinter.getArray()[4].Value <<= ( pPrinter->IsPrinting() );
298 aPrinter.getArray()[3].Name = DEFINE_CONST_UNICODE( "PaperSize" );
299 awt::Size aSize = impl_Size_Object2Struct(pPrinter->GetPaperSize() );
300 aPrinter.getArray()[3].Value <<= aSize;
302 aPrinter.getArray()[2].Name = DEFINE_CONST_UNICODE( "PaperFormat" );
303 view::PaperFormat eFormat = convertToPaperFormat(pPrinter->GetPaper());
304 aPrinter.getArray()[2].Value <<= eFormat;
306 aPrinter.getArray()[1].Name = DEFINE_CONST_UNICODE( "PaperOrientation" );
307 view::PaperOrientation eOrient = (view::PaperOrientation)pPrinter->GetOrientation();
308 aPrinter.getArray()[1].Value <<= eOrient;
310 aPrinter.getArray()[0].Name = DEFINE_CONST_UNICODE( "Name" );
311 String sStringTemp = pPrinter->GetName() ;
312 aPrinter.getArray()[0].Value <<= ::rtl::OUString( sStringTemp );
314 return aPrinter;
317 //________________________________________________________________________________________________________
318 // XPrintable
319 //________________________________________________________________________________________________________
321 void SfxPrintHelper::impl_setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter,SfxPrinter*& pPrinter,sal_uInt16& nChangeFlags,SfxViewShell*& pViewSh)
324 // Get old Printer
325 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
326 SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
327 if ( !pViewFrm )
328 return;
330 pViewSh = pViewFrm->GetViewShell();
331 pPrinter = pViewSh->GetPrinter(sal_True);
332 if ( !pPrinter )
333 return;
335 // new Printer-Name available?
336 nChangeFlags = 0;
337 sal_Int32 lDummy = 0;
338 for ( int n = 0; n < rPrinter.getLength(); ++n )
340 // get Property-Value from printer description
341 const beans::PropertyValue &rProp = rPrinter.getConstArray()[n];
343 // Name-Property?
344 if ( rProp.Name.compareToAscii( "Name" ) == 0 )
346 ::rtl::OUString aPrinterName;
347 if ( ! ( rProp.Value >>= aPrinterName ) )
348 throw ::com::sun::star::lang::IllegalArgumentException();
350 if ( aPrinterName != pPrinter->GetName() )
352 pPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aPrinterName );
353 nChangeFlags = SFX_PRINTER_PRINTER;
355 break;
359 Size aSetPaperSize( 0, 0);
360 view::PaperFormat nPaperFormat = view::PaperFormat_USER;
362 // other properties
363 for ( int i = 0; i < rPrinter.getLength(); ++i )
365 // get Property-Value from printer description
366 const beans::PropertyValue &rProp = rPrinter.getConstArray()[i];
368 // PaperOrientation-Property?
369 if ( rProp.Name.compareToAscii( "PaperOrientation" ) == 0 )
371 view::PaperOrientation eOrient;
372 if ( ( rProp.Value >>= eOrient ) == sal_False )
374 if ( ( rProp.Value >>= lDummy ) == sal_False )
375 throw ::com::sun::star::lang::IllegalArgumentException();
376 eOrient = ( view::PaperOrientation) lDummy;
379 if ( (Orientation) eOrient != pPrinter->GetOrientation() )
381 pPrinter->SetOrientation( (Orientation) eOrient );
382 nChangeFlags |= SFX_PRINTER_CHG_ORIENTATION;
386 // PaperFormat-Property?
387 else if ( rProp.Name.compareToAscii( "PaperFormat" ) == 0 )
389 if ( ( rProp.Value >>= nPaperFormat ) == sal_False )
391 if ( ( rProp.Value >>= lDummy ) == sal_False )
392 throw ::com::sun::star::lang::IllegalArgumentException();
393 nPaperFormat = ( view::PaperFormat ) lDummy;
396 if ( convertToPaper(nPaperFormat) != pPrinter->GetPaper() )
398 pPrinter->SetPaper( convertToPaper(nPaperFormat) );
399 nChangeFlags |= SFX_PRINTER_CHG_SIZE;
403 // PaperSize-Property?
404 else if ( rProp.Name.compareToAscii( "PaperSize" ) == 0 )
406 awt::Size aTempSize ;
407 if ( ( rProp.Value >>= aTempSize ) == sal_False )
409 throw ::com::sun::star::lang::IllegalArgumentException();
411 else
413 aSetPaperSize = impl_Size_Struct2Object(aTempSize);
417 // PrinterTray-Property
418 else if ( rProp.Name.compareToAscii( "PrinterPaperTray" ) == 0 )
420 rtl::OUString aTmp;
421 if ( ( rProp.Value >>= aTmp ) == sal_False )
422 throw ::com::sun::star::lang::IllegalArgumentException();
423 sal_uInt16 nCount = pPrinter->GetPaperBinCount();
424 for (sal_uInt16 nBin=0; nBin<nCount; nBin++)
426 ::rtl::OUString aName( pPrinter->GetPaperBinName(nBin) );
427 if ( aName == aTmp )
429 pPrinter->SetPaperBin(nBin);
430 break;
436 // The PaperSize may be set only when actually PAPER_USER
437 // applies, otherwise the driver could choose a invalid format.
438 if(nPaperFormat == view::PaperFormat_USER && aSetPaperSize.Width())
440 // Bug 56929 - MapMode of 100mm which recalculated when
441 // the device is set. Additionally only set if they were really changed.
442 aSetPaperSize = pPrinter->LogicToPixel( aSetPaperSize, MAP_100TH_MM );
443 if( aSetPaperSize != pPrinter->GetPaperSizePixel() )
445 pPrinter->SetPaperSizeUser( pPrinter->PixelToLogic( aSetPaperSize ) );
446 nChangeFlags |= SFX_PRINTER_CHG_SIZE;
450 //wait until printing is done
451 SfxPrinter* pDocPrinter = pViewSh->GetPrinter();
452 while ( pDocPrinter->IsPrinting() )
453 Application::Yield();
456 void SAL_CALL SfxPrintHelper::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter)
457 throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
459 // object already disposed?
460 SolarMutexGuard aGuard;
462 SfxViewShell* pViewSh = NULL;
463 SfxPrinter* pPrinter = NULL;
464 sal_uInt16 nChangeFlags = 0;
465 impl_setPrinter(rPrinter,pPrinter,nChangeFlags,pViewSh);
466 // set new printer
467 if ( pViewSh && pPrinter )
468 pViewSh->SetPrinter( pPrinter, nChangeFlags, false );
471 //________________________________________________________________________________________________________
472 // ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
473 //________________________________________________________________________________________________________
475 /* This implements a thread which will be started to wait for asynchronous
476 print jobs to temp. localy files. If they finish we move the temp. files
477 to her right locations by using the ucb.
479 class ImplUCBPrintWatcher : public ::osl::Thread
481 private:
482 /// of course we must know the printer which execute the job
483 SfxPrinter* m_pPrinter;
484 /// this describes the target location for the printed temp file
485 String m_sTargetURL;
486 /// it holds the temp file alive, till the print job will finish and remove it from disk automaticly if the object die
487 ::utl::TempFile* m_pTempFile;
489 public:
490 /* initialize this watcher but don't start it */
491 ImplUCBPrintWatcher( SfxPrinter* pPrinter, ::utl::TempFile* pTempFile, const String& sTargetURL )
492 : m_pPrinter ( pPrinter )
493 , m_sTargetURL( sTargetURL )
494 , m_pTempFile ( pTempFile )
497 /* waits for finishing of the print job and moves the temp file afterwards
498 Note: Starting of the job is done outside this thread!
499 But we have to free some of the given ressources on heap!
501 void SAL_CALL run()
503 /* SAFE { */
505 SolarMutexGuard aGuard;
506 while( m_pPrinter->IsPrinting() )
507 Application::Yield();
508 m_pPrinter = NULL; // don't delete it! It's borrowed only :-)
510 /* } SAFE */
512 // lock for further using of our member isn't neccessary - because
513 // we truns alone by defenition. Nobody join for us nor use us ...
514 moveAndDeleteTemp(&m_pTempFile,m_sTargetURL);
516 // finishing of this run() method will call onTerminate() automaticly
517 // kill this thread there!
520 /* nobody wait for this thread. We must kill ourself ...
522 void SAL_CALL onTerminated()
524 delete this;
527 /* static helper to move the temp. file to the target location by using the ucb
528 It's static to be useable from outside too. So it's not realy neccessary to start
529 the thread, if finishing of the job was detected outside this thread.
530 But it must be called without using a corresponding thread for the given parameter!
532 static void moveAndDeleteTemp( ::utl::TempFile** ppTempFile, const String& sTargetURL )
534 // move the file
537 INetURLObject aSplitter(sTargetURL);
538 String sFileName = aSplitter.getName(
539 INetURLObject::LAST_SEGMENT,
540 true,
541 INetURLObject::DECODE_WITH_CHARSET);
542 if (aSplitter.removeSegment() && sFileName.Len()>0)
544 ::ucbhelper::Content aSource(
545 ::rtl::OUString((*ppTempFile)->GetURL()),
546 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >());
548 ::ucbhelper::Content aTarget(
549 ::rtl::OUString(aSplitter.GetMainURL(INetURLObject::NO_DECODE)),
550 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >());
552 aTarget.transferContent(
553 aSource,
554 ::ucbhelper::InsertOperation_COPY,
555 ::rtl::OUString(sFileName),
556 ::com::sun::star::ucb::NameClash::OVERWRITE);
559 catch (const ::com::sun::star::ucb::ContentCreationException&)
561 OSL_FAIL("content create exception");
563 catch (const ::com::sun::star::ucb::CommandAbortedException&)
565 OSL_FAIL("command abort exception");
567 catch (const ::com::sun::star::uno::RuntimeException&)
569 OSL_FAIL("runtime exception");
571 catch (const ::com::sun::star::uno::Exception&)
573 OSL_FAIL("unknown exception");
576 // kill the temp file!
577 delete *ppTempFile;
578 *ppTempFile = NULL;
582 //------------------------------------------------
584 //________________________________________________________________________________________________________
585 // XPrintable
586 //________________________________________________________________________________________________________
587 void SAL_CALL SfxPrintHelper::print(const uno::Sequence< beans::PropertyValue >& rOptions)
588 throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
590 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
591 return;
593 // object already disposed?
594 // object already disposed?
595 SolarMutexGuard aGuard;
597 // get view for sfx printing capabilities
598 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
599 SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
600 if ( !pViewFrm )
601 return;
602 SfxViewShell* pView = pViewFrm->GetViewShell();
603 if ( !pView )
604 return;
605 sal_Bool bMonitor = sal_False;
606 // We need this information at the end of this method, if we start the vcl printer
607 // by executing the slot. Because if it is a ucb relevant URL we must wait for
608 // finishing the print job and move the temporary local file by using the ucb
609 // to the right location. But in case of no file name is given or it is already
610 // a local one we can supress this special handling. Because then vcl makes all
611 // right for us.
612 String sUcbUrl;
613 ::utl::TempFile* pUCBPrintTempFile = NULL;
615 uno::Sequence < beans::PropertyValue > aCheckedArgs( rOptions.getLength() );
616 sal_Int32 nProps = 0;
617 sal_Bool bWaitUntilEnd = sal_False;
618 sal_Int16 nDuplexMode = ::com::sun::star::view::DuplexMode::UNKNOWN;
619 for ( int n = 0; n < rOptions.getLength(); ++n )
621 // get Property-Value from options
622 const beans::PropertyValue &rProp = rOptions.getConstArray()[n];
624 // FileName-Property?
625 if ( rProp.Name.compareToAscii( "FileName" ) == 0 )
627 // unpack th URL and check for a valid and well known protocol
628 ::rtl::OUString sTemp;
629 if (
630 ( rProp.Value.getValueType()!=::getCppuType((const ::rtl::OUString*)0)) ||
631 (!(rProp.Value>>=sTemp))
634 throw ::com::sun::star::lang::IllegalArgumentException();
637 String sPath ;
638 String sURL (sTemp);
639 INetURLObject aCheck(sURL );
640 if (aCheck.GetProtocol()==INET_PROT_NOT_VALID)
642 // OK - it's not a valid URL. But may it's a simple
643 // system path directly. It will be supported for historical
644 // reasons. Otherwhise we break to much external code ...
645 // We try to convert it to a file URL. If its possible
646 // we put the system path to the item set and let vcl work with it.
647 // No ucb or thread will be neccessary then. In case it couldnt be
648 // converted its not an URL nor a system path. Then we can't accept
649 // this parameter and have to throw an exception.
650 ::rtl::OUString sSystemPath(sTemp);
651 ::rtl::OUString sFileURL;
652 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath,sFileURL)!=::osl::FileBase::E_None)
653 throw ::com::sun::star::lang::IllegalArgumentException();
654 aCheckedArgs[nProps].Name = rProp.Name;
655 aCheckedArgs[nProps++].Value <<= sFileURL;
656 // and append the local filename
657 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
658 aCheckedArgs[nProps].Name = rtl::OUString("LocalFileName");
659 aCheckedArgs[nProps++].Value <<= ::rtl::OUString( sTemp );
661 else
662 // It's a valid URL. but now we must know, if it is a local one or not.
663 // It's a question of using ucb or not!
664 if (::utl::LocalFileHelper::ConvertURLToSystemPath(sURL,sPath))
666 // it's a local file, we can use vcl without special handling
667 // And we have to use the system notation of the incoming URL.
668 // But it into the descriptor and let the slot be executed at
669 // the end of this method.
670 aCheckedArgs[nProps].Name = rProp.Name;
671 aCheckedArgs[nProps++].Value <<= sTemp;
672 // and append the local filename
673 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
674 aCheckedArgs[nProps].Name = rtl::OUString("LocalFileName");
675 aCheckedArgs[nProps++].Value <<= ::rtl::OUString( sPath );
677 else
679 // it's an ucb target. So we must use a temp. file for vcl
680 // and move it after printing by using the ucb.
681 // Create a temp file on the heap (because it must delete the
682 // real file on disk automaticly if it die - bt we have to share it with
683 // some other sources ... e.g. the ImplUCBPrintWatcher).
684 // And we put the name of this temp file to the descriptor instead
685 // of the URL. The URL we save for later using seperatly.
686 // Execution of the print job will be done later by executing
687 // a slot ...
688 pUCBPrintTempFile = new ::utl::TempFile();
689 pUCBPrintTempFile->EnableKillingFile();
691 //FIXME: does it work?
692 aCheckedArgs[nProps].Name = rtl::OUString("LocalFileName");
693 aCheckedArgs[nProps++].Value <<= ::rtl::OUString( pUCBPrintTempFile->GetFileName() );
694 sUcbUrl = sURL;
698 // CopyCount-Property
699 else if ( rProp.Name.compareToAscii( "CopyCount" ) == 0 )
701 sal_Int32 nCopies = 0;
702 if ( ( rProp.Value >>= nCopies ) == sal_False )
703 throw ::com::sun::star::lang::IllegalArgumentException();
705 aCheckedArgs[nProps].Name = rProp.Name;
706 aCheckedArgs[nProps++].Value <<= nCopies;
709 // Collate-Property
710 // Sort-Property (deprecated)
711 else if ( rProp.Name.compareToAscii( "Collate" ) == 0 ||
712 ( rProp.Name.compareToAscii( "Sort" ) == 0 ) )
714 sal_Bool bTemp = sal_Bool();
715 if ( rProp.Value >>= bTemp )
717 aCheckedArgs[nProps].Name = rtl::OUString("Collate");
718 aCheckedArgs[nProps++].Value <<= bTemp;
720 else
721 throw ::com::sun::star::lang::IllegalArgumentException();
724 // Pages-Property
725 else if ( rProp.Name.compareToAscii( "Pages" ) == 0 )
727 ::rtl::OUString sTemp;
728 if( rProp.Value >>= sTemp )
730 aCheckedArgs[nProps].Name = rProp.Name;
731 aCheckedArgs[nProps++].Value <<= sTemp;
733 else
734 throw ::com::sun::star::lang::IllegalArgumentException();
737 // MonitorVisible
738 else if ( rProp.Name.compareToAscii( "MonitorVisible" ) == 0 )
740 if( !(rProp.Value >>= bMonitor) )
741 throw ::com::sun::star::lang::IllegalArgumentException();
742 aCheckedArgs[nProps].Name = rProp.Name;
743 aCheckedArgs[nProps++].Value <<= bMonitor;
746 // Wait
747 else if ( rProp.Name.compareToAscii( "Wait" ) == 0 )
749 if ( !(rProp.Value >>= bWaitUntilEnd) )
750 throw ::com::sun::star::lang::IllegalArgumentException();
751 aCheckedArgs[nProps].Name = rProp.Name;
752 aCheckedArgs[nProps++].Value <<= bWaitUntilEnd;
755 else if ( rProp.Name.compareToAscii( "DuplexMode" ) == 0 )
757 if ( !(rProp.Value >>= nDuplexMode ) )
758 throw ::com::sun::star::lang::IllegalArgumentException();
759 aCheckedArgs[nProps].Name = rProp.Name;
760 aCheckedArgs[nProps++].Value <<= nDuplexMode;
764 if ( nProps != aCheckedArgs.getLength() )
765 aCheckedArgs.realloc(nProps);
767 // Execute the print request every time.
768 // It doesn'tmatter if it is a real printer used or we print to a local file
769 // nor if we print to a temp file and move it afterwards by using the ucb.
770 // That will be handled later. see pUCBPrintFile below!
771 pView->ExecPrint( aCheckedArgs, sal_True, sal_False );
773 // Ok - may be execution before has finished (or started!) printing.
774 // And may it was a printing to a file.
775 // Now we have to check if we can move the file (if neccessary) via ucb to his right location.
776 // Cases:
777 // a) printing finished => move the file directly and forget the watcher thread
778 // b) printing is asynchron and runs currently => start watcher thread and exit this method
779 // This thread make all neccessary things by itself.
780 if (pUCBPrintTempFile!=NULL)
782 // a)
783 SfxPrinter* pPrinter = pView->GetPrinter();
784 if ( ! pPrinter->IsPrinting() )
785 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl);
786 // b)
787 else
789 // Note: we create(d) some ressource on the heap. (thread and tep file)
790 // They will be delected by the thread automaticly if he finish his run() method.
791 ImplUCBPrintWatcher* pWatcher = new ImplUCBPrintWatcher( pPrinter, pUCBPrintTempFile, sUcbUrl );
792 pWatcher->create();
797 void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
799 if ( &rBC == m_pObjectShell )
801 SfxPrintingHint* pPrintHint = PTR_CAST( SfxPrintingHint, &rHint );
802 if ( pPrintHint )
804 if ( pPrintHint->GetWhich() == com::sun::star::view::PrintableState_JOB_STARTED )
806 if ( !m_xPrintJob.is() )
807 m_xPrintJob = new SfxPrintJob_Impl( this );
808 m_aPrintOptions = pPrintHint->GetOptions();
810 else if ( pPrintHint->GetWhich() != -2 ) // -2 : CancelPrintJob
812 view::PrintJobEvent aEvent;
813 aEvent.Source = m_xPrintJob;
814 aEvent.State = (com::sun::star::view::PrintableState) pPrintHint->GetWhich();
815 ::cppu::OInterfaceContainerHelper* pContainer = m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< view::XPrintJobListener >*) NULL ) );
816 if ( pContainer!=NULL )
818 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
819 while (pIterator.hasMoreElements())
820 ((view::XPrintJobListener*)pIterator.next())->printJobEvent( aEvent );
827 void SAL_CALL SfxPrintHelper::addPrintJobListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XPrintJobListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
829 SolarMutexGuard aGuard;
830 m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference < view::XPrintJobListener>*)0), xListener );
833 void SAL_CALL SfxPrintHelper::removePrintJobListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XPrintJobListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
835 SolarMutexGuard aGuard;
836 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference < view::XPrintJobListener>*)0), xListener );
840 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */