tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / sfx2 / source / doc / printhelper.cxx
blob45e5b1b26bda0d0f44ad2bf416dca1ec2306de40
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/frame/XModel.hpp>
30 #include <com/sun/star/view/DuplexMode.hpp>
31 #include <comphelper/processfactory.hxx>
32 #include <comphelper/propertyvalue.hxx>
33 #include <svl/itemset.hxx>
34 #include <svl/lstner.hxx>
35 #include <unotools/tempfile.hxx>
36 #include <osl/file.hxx>
37 #include <osl/thread.hxx>
38 #include <tools/urlobj.hxx>
39 #include <comphelper/diagnose_ex.hxx>
40 #include <ucbhelper/content.hxx>
41 #include <comphelper/interfacecontainer4.hxx>
42 #include <cppuhelper/implbase.hxx>
43 #include <utility>
44 #include <vcl/settings.hxx>
45 #include <vcl/svapp.hxx>
47 #include <sfx2/viewfrm.hxx>
48 #include <sfx2/viewsh.hxx>
49 #include <sfx2/printer.hxx>
50 #include <sfx2/objsh.hxx>
51 #include <sfx2/event.hxx>
53 #define SFX_PRINTABLESTATE_CANCELJOB css::view::PrintableState(-2)
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
57 namespace {
58 class SfxPrintJob_Impl;
61 struct IMPL_PrintListener_DataContainer : public SfxListener
63 SfxObjectShellRef m_pObjectShell;
64 std::mutex m_aMutex;
65 comphelper::OInterfaceContainerHelper4<view::XPrintJobListener> m_aJobListeners;
66 rtl::Reference<SfxPrintJob_Impl> m_xPrintJob;
67 css::uno::Sequence< css::beans::PropertyValue > m_aPrintOptions;
69 explicit IMPL_PrintListener_DataContainer()
74 void Notify( SfxBroadcaster& aBC ,
75 const SfxHint& aHint ) override ;
78 static awt::Size impl_Size_Object2Struct( const Size& aSize )
80 awt::Size aReturnValue;
81 aReturnValue.Width = aSize.Width() ;
82 aReturnValue.Height = aSize.Height() ;
83 return aReturnValue ;
86 static Size impl_Size_Struct2Object( const awt::Size& aSize )
88 Size aReturnValue;
89 aReturnValue.setWidth( aSize.Width ) ;
90 aReturnValue.setHeight( aSize.Height ) ;
91 return aReturnValue ;
94 namespace {
96 class SfxPrintJob_Impl : public cppu::WeakImplHelper
98 css::view::XPrintJob
101 IMPL_PrintListener_DataContainer* m_pData;
103 public:
104 explicit SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData );
105 virtual Sequence< css::beans::PropertyValue > SAL_CALL getPrintOptions( ) override;
106 virtual Sequence< css::beans::PropertyValue > SAL_CALL getPrinter( ) override;
107 virtual Reference< css::view::XPrintable > SAL_CALL getPrintable( ) override;
108 virtual void SAL_CALL cancelJob() override;
113 SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData )
114 : m_pData( pData )
118 Sequence< css::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrintOptions()
120 return m_pData->m_aPrintOptions;
123 Sequence< css::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrinter()
125 if( m_pData->m_pObjectShell.is() )
127 Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell->GetModel(), UNO_QUERY );
128 if ( xPrintable.is() )
129 return xPrintable->getPrinter();
131 return Sequence< css::beans::PropertyValue >();
134 Reference< css::view::XPrintable > SAL_CALL SfxPrintJob_Impl::getPrintable()
136 Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell.is() ? m_pData->m_pObjectShell->GetModel() : nullptr, UNO_QUERY );
137 return xPrintable;
140 void SAL_CALL SfxPrintJob_Impl::cancelJob()
142 // FIXME: how to cancel PrintJob via API?!
143 if( m_pData->m_pObjectShell.is() )
144 m_pData->m_pObjectShell->Broadcast( SfxPrintingHint( SFX_PRINTABLESTATE_CANCELJOB ) );
147 SfxPrintHelper::SfxPrintHelper()
149 m_pData.reset(new IMPL_PrintListener_DataContainer());
152 void SAL_CALL SfxPrintHelper::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
154 if ( !aArguments.hasElements() )
155 return;
157 css::uno::Reference < css::frame::XModel > xModel;
158 aArguments[0] >>= xModel;
159 m_pData->m_pObjectShell = SfxObjectShell::GetShellFromComponent(xModel);
160 if (m_pData->m_pObjectShell)
161 m_pData->StartListening(*m_pData->m_pObjectShell);
164 SfxPrintHelper::~SfxPrintHelper()
168 namespace
170 view::PaperFormat convertToPaperFormat(Paper eFormat)
172 view::PaperFormat eRet;
173 switch (eFormat)
175 case PAPER_A3:
176 eRet = view::PaperFormat_A3;
177 break;
178 case PAPER_A4:
179 eRet = view::PaperFormat_A4;
180 break;
181 case PAPER_A5:
182 eRet = view::PaperFormat_A5;
183 break;
184 case PAPER_B4_ISO:
185 eRet = view::PaperFormat_B4;
186 break;
187 case PAPER_B5_ISO:
188 eRet = view::PaperFormat_B5;
189 break;
190 case PAPER_LETTER:
191 eRet = view::PaperFormat_LETTER;
192 break;
193 case PAPER_LEGAL:
194 eRet = view::PaperFormat_LEGAL;
195 break;
196 case PAPER_TABLOID:
197 eRet = view::PaperFormat_TABLOID;
198 break;
199 case PAPER_USER:
200 default:
201 eRet = view::PaperFormat_USER;
202 break;
204 return eRet;
207 Paper convertToPaper(view::PaperFormat eFormat)
209 Paper eRet(PAPER_USER);
210 switch (eFormat)
212 case view::PaperFormat_A3:
213 eRet = PAPER_A3;
214 break;
215 case view::PaperFormat_A4:
216 eRet = PAPER_A4;
217 break;
218 case view::PaperFormat_A5:
219 eRet = PAPER_A5;
220 break;
221 case view::PaperFormat_B4:
222 eRet = PAPER_B4_ISO;
223 break;
224 case view::PaperFormat_B5:
225 eRet = PAPER_B5_ISO;
226 break;
227 case view::PaperFormat_LETTER:
228 eRet = PAPER_LETTER;
229 break;
230 case view::PaperFormat_LEGAL:
231 eRet = PAPER_LEGAL;
232 break;
233 case view::PaperFormat_TABLOID:
234 eRet = PAPER_TABLOID;
235 break;
236 case view::PaperFormat_USER:
237 eRet = PAPER_USER;
238 break;
239 case view::PaperFormat::PaperFormat_MAKE_FIXED_SIZE:
240 break;
241 //deliberate no default to force warn on a new papersize
243 return eRet;
248 // XPrintable
251 uno::Sequence< beans::PropertyValue > SAL_CALL SfxPrintHelper::getPrinter()
253 // object already disposed?
254 SolarMutexGuard aGuard;
256 // search for any view of this document that is currently printing
257 const Printer *pPrinter = nullptr;
258 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ? SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr;
259 SfxViewFrame* pFirst = pViewFrm;
260 while ( pViewFrm && !pPrinter )
262 pPrinter = pViewFrm->GetViewShell()->GetActivePrinter();
263 pViewFrm = SfxViewFrame::GetNext( *pViewFrm, m_pData->m_pObjectShell.get(), false );
266 // if no view is printing currently, use the permanent SfxPrinter instance
267 if ( !pPrinter && pFirst )
268 pPrinter = pFirst->GetViewShell()->GetPrinter(true);
270 if ( !pPrinter )
271 return uno::Sequence< beans::PropertyValue >();
273 return
275 comphelper::makePropertyValue(u"Name"_ustr, pPrinter->GetName()),
276 comphelper::makePropertyValue(u"PaperOrientation"_ustr, static_cast<view::PaperOrientation>(pPrinter->GetOrientation())),
277 comphelper::makePropertyValue(u"PaperFormat"_ustr, convertToPaperFormat(pPrinter->GetPaper())),
278 comphelper::makePropertyValue(u"PaperSize"_ustr, impl_Size_Object2Struct(pPrinter->GetPaperSize() )),
279 comphelper::makePropertyValue(u"IsBusy"_ustr, pPrinter->IsPrinting()),
280 comphelper::makePropertyValue(u"CanSetPaperOrientation"_ustr, pPrinter->HasSupport( PrinterSupport::SetOrientation )),
281 comphelper::makePropertyValue(u"CanSetPaperFormat"_ustr, pPrinter->HasSupport( PrinterSupport::SetPaper )),
282 comphelper::makePropertyValue(u"CanSetPaperSize"_ustr, pPrinter->HasSupport( PrinterSupport::SetPaperSize ))
287 // XPrintable
290 void SfxPrintHelper::impl_setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter,
291 VclPtr<SfxPrinter>& pPrinter,
292 SfxPrinterChangeFlags& nChangeFlags,
293 SfxViewShell*& pViewSh)
296 // Get old Printer
297 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ?
298 SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr;
299 if ( !pViewFrm )
300 return;
302 pViewSh = pViewFrm->GetViewShell();
303 pPrinter = pViewSh->GetPrinter(true);
304 if ( !pPrinter )
305 return;
307 // new Printer-Name available?
308 nChangeFlags = SfxPrinterChangeFlags::NONE;
309 sal_Int32 lDummy = 0;
310 auto pProp = std::find_if(rPrinter.begin(), rPrinter.end(),
311 [](const beans::PropertyValue &rProp) { return rProp.Name == "Name"; });
312 if (pProp != rPrinter.end())
314 OUString aPrinterName;
315 if ( ! ( pProp->Value >>= aPrinterName ) )
316 throw css::lang::IllegalArgumentException();
318 if ( aPrinterName != pPrinter->GetName() )
320 pPrinter = VclPtr<SfxPrinter>::Create( pPrinter->GetOptions().Clone(), aPrinterName );
321 nChangeFlags = SfxPrinterChangeFlags::PRINTER;
325 Size aSetPaperSize( 0, 0);
326 view::PaperFormat nPaperFormat = view::PaperFormat_USER;
328 // other properties
329 for ( const beans::PropertyValue &rProp : rPrinter )
331 // get Property-Value from printer description
332 // PaperOrientation-Property?
333 if ( rProp.Name == "PaperOrientation" )
335 view::PaperOrientation eOrient;
336 if ( !( rProp.Value >>= eOrient ) )
338 if ( !( rProp.Value >>= lDummy ) )
339 throw css::lang::IllegalArgumentException();
340 eOrient = static_cast<view::PaperOrientation>(lDummy);
343 if ( static_cast<Orientation>(eOrient) != pPrinter->GetOrientation() )
345 pPrinter->SetOrientation( static_cast<Orientation>(eOrient) );
346 nChangeFlags |= SfxPrinterChangeFlags::CHG_ORIENTATION;
350 // PaperFormat-Property?
351 else if ( rProp.Name == "PaperFormat" )
353 if ( !( rProp.Value >>= nPaperFormat ) )
355 if ( !( rProp.Value >>= lDummy ) )
356 throw css::lang::IllegalArgumentException();
357 nPaperFormat = static_cast<view::PaperFormat>(lDummy);
360 if ( convertToPaper(nPaperFormat) != pPrinter->GetPaper() )
362 pPrinter->SetPaper( convertToPaper(nPaperFormat) );
363 nChangeFlags |= SfxPrinterChangeFlags::CHG_SIZE;
367 // PaperSize-Property?
368 else if ( rProp.Name == "PaperSize" )
370 awt::Size aTempSize ;
371 if ( !( rProp.Value >>= aTempSize ) )
373 throw css::lang::IllegalArgumentException();
375 aSetPaperSize = impl_Size_Struct2Object(aTempSize);
378 // PrinterTray-Property
379 else if ( rProp.Name == "PrinterPaperTray" )
381 OUString aTmp;
382 if ( !( rProp.Value >>= aTmp ) )
383 throw css::lang::IllegalArgumentException();
384 const sal_uInt16 nCount = pPrinter->GetPaperBinCount();
385 for (sal_uInt16 nBin=0; nBin<nCount; nBin++)
387 OUString aName( pPrinter->GetPaperBinName(nBin) );
388 if ( aName == aTmp )
390 pPrinter->SetPaperBin(nBin);
391 break;
397 // The PaperSize may be set only when actually PAPER_USER
398 // applies, otherwise the driver could choose an invalid format.
399 if(nPaperFormat == view::PaperFormat_USER && aSetPaperSize.Width())
401 // Bug 56929 - MapMode of 100mm which recalculated when
402 // the device is set. Additionally only set if they were really changed.
403 aSetPaperSize = pPrinter->LogicToPixel(aSetPaperSize, MapMode(MapUnit::Map100thMM));
404 if( aSetPaperSize != pPrinter->GetPaperSizePixel() )
406 pPrinter->SetPaperSizeUser( pPrinter->PixelToLogic( aSetPaperSize ) );
407 nChangeFlags |= SfxPrinterChangeFlags::CHG_SIZE;
411 //wait until printing is done
412 SfxPrinter* pDocPrinter = pViewSh->GetPrinter();
413 while ( pDocPrinter->IsPrinting() && !Application::IsQuit())
414 Application::Yield();
417 void SAL_CALL SfxPrintHelper::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter)
419 // object already disposed?
420 SolarMutexGuard aGuard;
422 SfxViewShell* pViewSh = nullptr;
423 VclPtr<SfxPrinter> pPrinter;
424 SfxPrinterChangeFlags nChangeFlags = SfxPrinterChangeFlags::NONE;
425 impl_setPrinter(rPrinter,pPrinter,nChangeFlags,pViewSh);
426 // set new printer
427 if ( pViewSh && pPrinter )
428 pViewSh->SetPrinter( pPrinter, nChangeFlags );
432 // ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
434 namespace {
436 /* This implements a thread which will be started to wait for asynchronous
437 print jobs to temp. locally files. If they finish we move the temp. files
438 to their right locations by using the ucb.
440 class ImplUCBPrintWatcher : public ::osl::Thread
442 private:
443 /// of course we must know the printer which execute the job
444 VclPtr<SfxPrinter> m_pPrinter;
445 /// this describes the target location for the printed temp file
446 OUString m_sTargetURL;
447 /// it holds the temp file alive, till the print job will finish and remove it from disk automatically if the object die
448 ::utl::TempFileNamed* m_pTempFile;
450 public:
451 /* initialize this watcher but don't start it */
452 ImplUCBPrintWatcher( SfxPrinter* pPrinter, ::utl::TempFileNamed* pTempFile, OUString sTargetURL )
453 : m_pPrinter ( pPrinter )
454 , m_sTargetURL(std::move( sTargetURL ))
455 , m_pTempFile ( pTempFile )
458 /* waits for finishing of the print job and moves the temp file afterwards
459 Note: Starting of the job is done outside this thread!
460 But we have to free some of the given resources on heap!
462 void SAL_CALL run() override
464 osl_setThreadName("ImplUCBPrintWatcher");
466 /* SAFE { */
468 SolarMutexGuard aGuard;
469 while( m_pPrinter->IsPrinting() && !Application::IsQuit())
470 Application::Yield();
471 m_pPrinter.clear(); // don't delete it! It's borrowed only :-)
473 /* } SAFE */
475 // lock for further using of our member isn't necessary - because
476 // we run alone by definition. Nobody join for us nor use us...
477 moveAndDeleteTemp(&m_pTempFile,m_sTargetURL);
479 // finishing of this run() method will call onTerminate() automatically
480 // kill this thread there!
483 /* nobody wait for this thread. We must kill ourself ...
485 void SAL_CALL onTerminated() override
487 delete this;
490 /* static helper to move the temp. file to the target location by using the ucb
491 It's static to be usable from outside too. So it's not really necessary to start
492 the thread, if finishing of the job was detected outside this thread.
493 But it must be called without using a corresponding thread for the given parameter!
495 static void moveAndDeleteTemp( ::utl::TempFileNamed** ppTempFile, std::u16string_view sTargetURL )
497 // move the file
500 INetURLObject aSplitter(sTargetURL);
501 OUString sFileName = aSplitter.getName(
502 INetURLObject::LAST_SEGMENT,
503 true,
504 INetURLObject::DecodeMechanism::WithCharset);
505 if (aSplitter.removeSegment() && !sFileName.isEmpty())
507 ::ucbhelper::Content aSource(
508 (*ppTempFile)->GetURL(),
509 css::uno::Reference< css::ucb::XCommandEnvironment >(),
510 comphelper::getProcessComponentContext());
512 ::ucbhelper::Content aTarget(
513 aSplitter.GetMainURL(INetURLObject::DecodeMechanism::NONE),
514 css::uno::Reference< css::ucb::XCommandEnvironment >(),
515 comphelper::getProcessComponentContext());
517 aTarget.transferContent(
518 aSource,
519 ::ucbhelper::InsertOperation::Copy,
520 sFileName,
521 css::ucb::NameClash::OVERWRITE);
524 catch (const css::uno::Exception&)
526 TOOLS_WARN_EXCEPTION( "sfx.doc", "");
529 // kill the temp file!
530 delete *ppTempFile;
531 *ppTempFile = nullptr;
537 // XPrintable
539 void SAL_CALL SfxPrintHelper::print(const uno::Sequence< beans::PropertyValue >& rOptions)
541 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
542 return;
544 // object already disposed?
545 // object already disposed?
546 SolarMutexGuard aGuard;
548 // get view for sfx printing capabilities
549 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ?
550 SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr;
551 if ( !pViewFrm )
552 return;
553 SfxViewShell* pView = pViewFrm->GetViewShell();
554 if ( !pView )
555 return;
556 bool bMonitor = false;
557 // We need this information at the end of this method, if we start the vcl printer
558 // by executing the slot. Because if it is a ucb relevant URL we must wait for
559 // finishing the print job and move the temporary local file by using the ucb
560 // to the right location. But in case of no file name is given or it is already
561 // a local one we can suppress this special handling. Because then vcl makes all
562 // right for us.
563 OUString sUcbUrl;
564 ::utl::TempFileNamed* pUCBPrintTempFile = nullptr;
566 uno::Sequence < beans::PropertyValue > aCheckedArgs( rOptions.getLength() );
567 auto pCheckedArgs = aCheckedArgs.getArray();
568 sal_Int32 nProps = 0;
569 bool bWaitUntilEnd = false;
570 sal_Int16 nDuplexMode = css::view::DuplexMode::UNKNOWN;
571 for ( const beans::PropertyValue &rProp : rOptions )
573 // get Property-Value from options
574 // FileName-Property?
575 if ( rProp.Name == "FileName" )
577 // unpack th URL and check for a valid and well known protocol
578 OUString sTemp;
579 if (
580 ( rProp.Value.getValueType()!=cppu::UnoType<OUString>::get()) ||
581 (!(rProp.Value>>=sTemp))
584 throw css::lang::IllegalArgumentException();
587 OUString sPath;
588 OUString sURL (sTemp);
589 INetURLObject aCheck(sURL );
590 if (aCheck.GetProtocol()==INetProtocol::NotValid)
592 // OK - it's not a valid URL. But may it's a simple
593 // system path directly. It will be supported for historical
594 // reasons. Otherwise we break too much external code...
595 // We try to convert it to a file URL. If it's possible
596 // we put the system path to the item set and let vcl work with it.
597 // No ucb or thread will be necessary then. In case it couldn't be
598 // converted it's not a URL nor a system path. Then we can't accept
599 // this parameter and have to throw an exception.
600 const OUString& sSystemPath(sTemp);
601 OUString sFileURL;
602 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath,sFileURL)!=::osl::FileBase::E_None)
603 throw css::lang::IllegalArgumentException();
604 pCheckedArgs[nProps].Name = rProp.Name;
605 pCheckedArgs[nProps++].Value <<= sFileURL;
606 // and append the local filename
607 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
608 pCheckedArgs = aCheckedArgs.getArray();
609 pCheckedArgs[nProps].Name = "LocalFileName";
610 pCheckedArgs[nProps++].Value <<= sTemp;
612 else
613 // It's a valid URL. but now we must know, if it is a local one or not.
614 // It's a question of using ucb or not!
615 if (osl::FileBase::getSystemPathFromFileURL(sURL, sPath) == osl::FileBase::E_None)
617 // it's a local file, we can use vcl without special handling
618 // And we have to use the system notation of the incoming URL.
619 // But it into the descriptor and let the slot be executed at
620 // the end of this method.
621 pCheckedArgs[nProps].Name = rProp.Name;
622 pCheckedArgs[nProps++].Value <<= sTemp;
623 // and append the local filename
624 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
625 pCheckedArgs = aCheckedArgs.getArray();
626 pCheckedArgs[nProps].Name = "LocalFileName";
627 pCheckedArgs[nProps++].Value <<= sPath;
629 else
631 // it's a ucb target. So we must use a temp. file for vcl
632 // and move it after printing by using the ucb.
633 // Create a temp file on the heap (because it must delete the
634 // real file on disk automatically if it die - bt we have to share it with
635 // some other sources ... e.g. the ImplUCBPrintWatcher).
636 // And we put the name of this temp file to the descriptor instead
637 // of the URL. The URL we save for later using separately.
638 // Execution of the print job will be done later by executing
639 // a slot ...
640 if(!pUCBPrintTempFile)
641 pUCBPrintTempFile = new ::utl::TempFileNamed();
642 pUCBPrintTempFile->EnableKillingFile();
644 //FIXME: does it work?
645 pCheckedArgs[nProps].Name = "LocalFileName";
646 pCheckedArgs[nProps++].Value <<= pUCBPrintTempFile->GetFileName();
647 sUcbUrl = sURL;
651 // CopyCount-Property
652 else if ( rProp.Name == "CopyCount" )
654 sal_Int32 nCopies = 0;
655 if ( !( rProp.Value >>= nCopies ) )
656 throw css::lang::IllegalArgumentException();
657 pCheckedArgs[nProps].Name = rProp.Name;
658 pCheckedArgs[nProps++].Value <<= nCopies;
661 // Collate-Property
662 // Sort-Property (deprecated)
663 else if ( rProp.Name == "Collate" || rProp.Name == "Sort" )
665 bool bTemp;
666 if ( !(rProp.Value >>= bTemp) )
667 throw css::lang::IllegalArgumentException();
668 pCheckedArgs[nProps].Name = "Collate";
669 pCheckedArgs[nProps++].Value <<= bTemp;
672 else if ( rProp.Name == "SinglePrintJobs" )
674 bool bTemp;
675 if ( !(rProp.Value >>= bTemp) )
676 throw css::lang::IllegalArgumentException();
677 pCheckedArgs[nProps].Name = "SinglePrintJobs";
678 pCheckedArgs[nProps++].Value <<= bTemp;
681 else if ( rProp.Name == "JobName" )
683 OUString sTemp;
684 if( !(rProp.Value >>= sTemp) )
685 throw css::lang::IllegalArgumentException();
686 pCheckedArgs[nProps].Name = rProp.Name;
687 pCheckedArgs[nProps++].Value <<= sTemp;
690 // Pages-Property
691 else if ( rProp.Name == "Pages" )
693 OUString sTemp;
694 if( !(rProp.Value >>= sTemp) )
695 throw css::lang::IllegalArgumentException();
696 pCheckedArgs[nProps].Name = rProp.Name;
697 pCheckedArgs[nProps++].Value <<= sTemp;
700 // MonitorVisible
701 else if ( rProp.Name == "MonitorVisible" )
703 if( !(rProp.Value >>= bMonitor) )
704 throw css::lang::IllegalArgumentException();
705 pCheckedArgs[nProps].Name = rProp.Name;
706 pCheckedArgs[nProps++].Value <<= bMonitor;
709 // Wait
710 else if ( rProp.Name == "Wait" )
712 if ( !(rProp.Value >>= bWaitUntilEnd) )
713 throw css::lang::IllegalArgumentException();
714 pCheckedArgs[nProps].Name = rProp.Name;
715 pCheckedArgs[nProps++].Value <<= bWaitUntilEnd;
718 else if ( rProp.Name == "DuplexMode" )
720 if ( !(rProp.Value >>= nDuplexMode ) )
721 throw css::lang::IllegalArgumentException();
722 pCheckedArgs[nProps].Name = rProp.Name;
723 pCheckedArgs[nProps++].Value <<= nDuplexMode;
727 if ( nProps != aCheckedArgs.getLength() )
728 aCheckedArgs.realloc(nProps);
730 // Execute the print request every time.
731 // It doesn't matter if it is a real printer used or we print to a local file
732 // nor if we print to a temp file and move it afterwards by using the ucb.
733 // That will be handled later. see pUCBPrintFile below!
734 pView->ExecPrint( aCheckedArgs, true, false );
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 necessary) via UCB to its right location.
739 // Cases:
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 necessary things by itself.
743 if (!pUCBPrintTempFile)
744 return;
746 // a)
747 SfxPrinter* pPrinter = pView->GetPrinter();
748 if ( ! pPrinter->IsPrinting() )
749 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl);
750 // b)
751 else
753 // Note: we create(d) some resource on the heap (thread and temp file).
754 // They will be deleted by the thread automatically if it finishes its run() method.
755 ImplUCBPrintWatcher* pWatcher = new ImplUCBPrintWatcher( pPrinter, pUCBPrintTempFile, sUcbUrl );
756 pWatcher->create();
760 void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
762 if (rHint.GetId() != SfxHintId::ThisIsAnSfxEventHint)
763 return;
764 const SfxEventHint& rEventHint = static_cast<const SfxEventHint&>(rHint);
765 if (rEventHint.GetEventId() != SfxEventHintId::PrintDoc)
766 return;
767 const SfxPrintingHint* pPrintHint = static_cast<const SfxPrintingHint*>(&rHint);
768 if ( &rBC != m_pObjectShell.get()
769 || pPrintHint->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB )
770 return;
772 if ( pPrintHint->GetWhich() == css::view::PrintableState_JOB_STARTED )
774 if ( !m_xPrintJob.is() )
775 m_xPrintJob = new SfxPrintJob_Impl( this );
776 m_aPrintOptions = pPrintHint->GetOptions();
779 std::unique_lock aGuard(m_aMutex);
780 if (!m_aJobListeners.getLength(aGuard))
781 return;
782 view::PrintJobEvent aEvent;
783 aEvent.Source = getXWeak(m_xPrintJob.get());
784 aEvent.State = pPrintHint->GetWhich();
786 comphelper::OInterfaceIteratorHelper4 pIterator(aGuard, m_aJobListeners);
787 aGuard.unlock();
788 while (pIterator.hasMoreElements())
789 pIterator.next()->printJobEvent( aEvent );
792 void SAL_CALL SfxPrintHelper::addPrintJobListener( const css::uno::Reference< css::view::XPrintJobListener >& xListener )
794 std::unique_lock aGuard(m_pData->m_aMutex);
795 m_pData->m_aJobListeners.addInterface( aGuard, xListener );
798 void SAL_CALL SfxPrintHelper::removePrintJobListener( const css::uno::Reference< css::view::XPrintJobListener >& xListener )
800 std::unique_lock aGuard(m_pData->m_aMutex);
801 m_pData->m_aJobListeners.removeInterface( aGuard, xListener );
805 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */