lok: impress: show only supported transitions in the side pane
[LibreOffice.git] / sfx2 / source / doc / printhelper.cxx
blob661074a9a1022b4250eea229869f3c6da241aa34
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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() ;
88 return aReturnValue ;
91 static Size impl_Size_Struct2Object( const awt::Size& aSize )
93 Size aReturnValue;
94 aReturnValue.setWidth( aSize.Width ) ;
95 aReturnValue.setHeight( aSize.Height ) ;
96 return aReturnValue ;
99 class SfxPrintJob_Impl : public cppu::WeakImplHelper
101 css::view::XPrintJob
104 IMPL_PrintListener_DataContainer* m_pData;
106 public:
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 )
115 : m_pData( 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 );
138 return xPrintable;
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() )
156 return;
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 );
163 if ( nHandle )
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()
174 namespace
176 view::PaperFormat convertToPaperFormat(Paper eFormat)
178 view::PaperFormat eRet;
179 switch (eFormat)
181 case PAPER_A3:
182 eRet = view::PaperFormat_A3;
183 break;
184 case PAPER_A4:
185 eRet = view::PaperFormat_A4;
186 break;
187 case PAPER_A5:
188 eRet = view::PaperFormat_A5;
189 break;
190 case PAPER_B4_ISO:
191 eRet = view::PaperFormat_B4;
192 break;
193 case PAPER_B5_ISO:
194 eRet = view::PaperFormat_B5;
195 break;
196 case PAPER_LETTER:
197 eRet = view::PaperFormat_LETTER;
198 break;
199 case PAPER_LEGAL:
200 eRet = view::PaperFormat_LEGAL;
201 break;
202 case PAPER_TABLOID:
203 eRet = view::PaperFormat_TABLOID;
204 break;
205 case PAPER_USER:
206 default:
207 eRet = view::PaperFormat_USER;
208 break;
210 return eRet;
213 Paper convertToPaper(view::PaperFormat eFormat)
215 Paper eRet(PAPER_USER);
216 switch (eFormat)
218 case view::PaperFormat_A3:
219 eRet = PAPER_A3;
220 break;
221 case view::PaperFormat_A4:
222 eRet = PAPER_A4;
223 break;
224 case view::PaperFormat_A5:
225 eRet = PAPER_A5;
226 break;
227 case view::PaperFormat_B4:
228 eRet = PAPER_B4_ISO;
229 break;
230 case view::PaperFormat_B5:
231 eRet = PAPER_B5_ISO;
232 break;
233 case view::PaperFormat_LETTER:
234 eRet = PAPER_LETTER;
235 break;
236 case view::PaperFormat_LEGAL:
237 eRet = PAPER_LEGAL;
238 break;
239 case view::PaperFormat_TABLOID:
240 eRet = PAPER_TABLOID;
241 break;
242 case view::PaperFormat_USER:
243 eRet = PAPER_USER;
244 break;
245 case view::PaperFormat::PaperFormat_MAKE_FIXED_SIZE:
246 break;
247 //deliberate no default to force warn on a new papersize
249 return eRet;
254 // XPrintable
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);
276 if ( !pPrinter )
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;
309 return aPrinter;
313 // XPrintable
316 void SfxPrintHelper::impl_setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter,
317 VclPtr<SfxPrinter>& pPrinter,
318 SfxPrinterChangeFlags& nChangeFlags,
319 SfxViewShell*& pViewSh)
322 // Get old Printer
323 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ?
324 SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr;
325 if ( !pViewFrm )
326 return;
328 pViewSh = pViewFrm->GetViewShell();
329 pPrinter = pViewSh->GetPrinter(true);
330 if ( !pPrinter )
331 return;
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;
354 // other properties
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" )
407 OUString aTmp;
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) );
414 if ( aName == aTmp )
416 pPrinter->SetPaperBin(nBin);
417 break;
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);
452 // set new printer
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
467 private:
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;
475 public:
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");
491 /* SAFE { */
493 SolarMutexGuard aGuard;
494 while( m_pPrinter->IsPrinting() )
495 Application::Yield();
496 m_pPrinter.clear(); // don't delete it! It's borrowed only :-)
498 /* } SAFE */
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
512 delete this;
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 )
522 // move the file
525 INetURLObject aSplitter(sTargetURL);
526 OUString sFileName = aSplitter.getName(
527 INetURLObject::LAST_SEGMENT,
528 true,
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(
543 aSource,
544 ::ucbhelper::InsertOperation::Copy,
545 sFileName,
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!
567 delete *ppTempFile;
568 *ppTempFile = nullptr;
573 // XPrintable
575 void SAL_CALL SfxPrintHelper::print(const uno::Sequence< beans::PropertyValue >& rOptions)
577 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
578 return;
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;
587 if ( !pViewFrm )
588 return;
589 SfxViewShell* pView = pViewFrm->GetViewShell();
590 if ( !pView )
591 return;
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
598 // right for us.
599 OUString sUcbUrl;
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
613 OUString sTemp;
614 if (
615 ( rProp.Value.getValueType()!=cppu::UnoType<OUString>::get()) ||
616 (!(rProp.Value>>=sTemp))
619 throw css::lang::IllegalArgumentException();
622 OUString sPath;
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);
636 OUString sFileURL;
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;
646 else
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;
662 else
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
672 // a slot ...
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();
680 sUcbUrl = sURL;
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;
694 // Collate-Property
695 // Sort-Property (deprecated)
696 else if ( rProp.Name == "Collate" || rProp.Name == "Sort" )
698 bool bTemp;
699 if ( !(rProp.Value >>= bTemp) )
700 throw css::lang::IllegalArgumentException();
701 aCheckedArgs[nProps].Name = "Collate";
702 aCheckedArgs[nProps++].Value <<= bTemp;
705 // Pages-Property
706 else if ( rProp.Name == "Pages" )
708 OUString sTemp;
709 if( !(rProp.Value >>= sTemp) )
710 throw css::lang::IllegalArgumentException();
711 aCheckedArgs[nProps].Name = rProp.Name;
712 aCheckedArgs[nProps++].Value <<= sTemp;
715 // MonitorVisible
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;
724 // Wait
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.
754 // Cases:
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)
759 return;
761 // a)
762 SfxPrinter* pPrinter = pView->GetPrinter();
763 if ( ! pPrinter->IsPrinting() )
764 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl);
765 // b)
766 else
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 );
771 pWatcher->create();
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()
779 || !pPrintHint
780 || pPrintHint->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB )
781 return;
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());
792 if ( !pContainer )
793 return;
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: */