LibreOffice Module sfx2 (master) 1
printhelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include "printhelper.hxx"
22
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>
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>
40#include <ucbhelper/content.hxx>
43#include <utility>
44#include <vcl/settings.hxx>
45#include <vcl/svapp.hxx>
46
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>
52
53#define SFX_PRINTABLESTATE_CANCELJOB css::view::PrintableState(-2)
54
55using namespace ::com::sun::star;
56using namespace ::com::sun::star::uno;
57
59{
61 std::mutex m_aMutex;
63 uno::Reference< css::view::XPrintJob> m_xPrintJob;
64 css::uno::Sequence< css::beans::PropertyValue > m_aPrintOptions;
65
67 {
68 }
69
70
71 void Notify( SfxBroadcaster& aBC ,
72 const SfxHint& aHint ) override ;
73};
74
75static awt::Size impl_Size_Object2Struct( const Size& aSize )
76{
77 awt::Size aReturnValue;
78 aReturnValue.Width = aSize.Width() ;
79 aReturnValue.Height = aSize.Height() ;
80 return aReturnValue ;
81}
82
83static Size impl_Size_Struct2Object( const awt::Size& aSize )
84{
85 Size aReturnValue;
86 aReturnValue.setWidth( aSize.Width ) ;
87 aReturnValue.setHeight( aSize.Height ) ;
88 return aReturnValue ;
89}
90
91namespace {
92
93class SfxPrintJob_Impl : public cppu::WeakImplHelper
94<
95 css::view::XPrintJob
96>
97{
99
100public:
101 explicit SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData );
102 virtual Sequence< css::beans::PropertyValue > SAL_CALL getPrintOptions( ) override;
103 virtual Sequence< css::beans::PropertyValue > SAL_CALL getPrinter( ) override;
104 virtual Reference< css::view::XPrintable > SAL_CALL getPrintable( ) override;
105 virtual void SAL_CALL cancelJob() override;
106};
107
108}
109
110SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData )
111 : m_pData( pData )
112{
113}
114
115Sequence< css::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrintOptions()
116{
117 return m_pData->m_aPrintOptions;
118}
119
120Sequence< css::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrinter()
121{
122 if( m_pData->m_pObjectShell.is() )
123 {
124 Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell->GetModel(), UNO_QUERY );
125 if ( xPrintable.is() )
126 return xPrintable->getPrinter();
127 }
128 return Sequence< css::beans::PropertyValue >();
129}
130
131Reference< css::view::XPrintable > SAL_CALL SfxPrintJob_Impl::getPrintable()
132{
133 Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell.is() ? m_pData->m_pObjectShell->GetModel() : nullptr, UNO_QUERY );
134 return xPrintable;
135}
136
137void SAL_CALL SfxPrintJob_Impl::cancelJob()
138{
139 // FIXME: how to cancel PrintJob via API?!
140 if( m_pData->m_pObjectShell.is() )
141 m_pData->m_pObjectShell->Broadcast( SfxPrintingHint( SFX_PRINTABLESTATE_CANCELJOB ) );
142}
143
145{
147}
148
149void SAL_CALL SfxPrintHelper::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
150{
151 if ( !aArguments.hasElements() )
152 return;
153
154 css::uno::Reference < css::frame::XModel > xModel;
155 aArguments[0] >>= xModel;
157 if (m_pData->m_pObjectShell)
158 m_pData->StartListening(*m_pData->m_pObjectShell);
159}
160
162{
163}
164
165namespace
166{
167 view::PaperFormat convertToPaperFormat(Paper eFormat)
168 {
169 view::PaperFormat eRet;
170 switch (eFormat)
171 {
172 case PAPER_A3:
173 eRet = view::PaperFormat_A3;
174 break;
175 case PAPER_A4:
176 eRet = view::PaperFormat_A4;
177 break;
178 case PAPER_A5:
179 eRet = view::PaperFormat_A5;
180 break;
181 case PAPER_B4_ISO:
182 eRet = view::PaperFormat_B4;
183 break;
184 case PAPER_B5_ISO:
185 eRet = view::PaperFormat_B5;
186 break;
187 case PAPER_LETTER:
188 eRet = view::PaperFormat_LETTER;
189 break;
190 case PAPER_LEGAL:
191 eRet = view::PaperFormat_LEGAL;
192 break;
193 case PAPER_TABLOID:
194 eRet = view::PaperFormat_TABLOID;
195 break;
196 case PAPER_USER:
197 default:
198 eRet = view::PaperFormat_USER;
199 break;
200 }
201 return eRet;
202 }
203
204 Paper convertToPaper(view::PaperFormat eFormat)
205 {
206 Paper eRet(PAPER_USER);
207 switch (eFormat)
208 {
209 case view::PaperFormat_A3:
210 eRet = PAPER_A3;
211 break;
212 case view::PaperFormat_A4:
213 eRet = PAPER_A4;
214 break;
215 case view::PaperFormat_A5:
216 eRet = PAPER_A5;
217 break;
218 case view::PaperFormat_B4:
219 eRet = PAPER_B4_ISO;
220 break;
221 case view::PaperFormat_B5:
222 eRet = PAPER_B5_ISO;
223 break;
224 case view::PaperFormat_LETTER:
225 eRet = PAPER_LETTER;
226 break;
227 case view::PaperFormat_LEGAL:
228 eRet = PAPER_LEGAL;
229 break;
230 case view::PaperFormat_TABLOID:
231 eRet = PAPER_TABLOID;
232 break;
233 case view::PaperFormat_USER:
234 eRet = PAPER_USER;
235 break;
236 case view::PaperFormat::PaperFormat_MAKE_FIXED_SIZE:
237 break;
238 //deliberate no default to force warn on a new papersize
239 }
240 return eRet;
241 }
242}
243
244
245// XPrintable
246
247
248uno::Sequence< beans::PropertyValue > SAL_CALL SfxPrintHelper::getPrinter()
249{
250 // object already disposed?
251 SolarMutexGuard aGuard;
252
253 // search for any view of this document that is currently printing
254 const Printer *pPrinter = nullptr;
255 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ? SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr;
256 SfxViewFrame* pFirst = pViewFrm;
257 while ( pViewFrm && !pPrinter )
258 {
259 pPrinter = pViewFrm->GetViewShell()->GetActivePrinter();
260 pViewFrm = SfxViewFrame::GetNext( *pViewFrm, m_pData->m_pObjectShell.get(), false );
261 }
262
263 // if no view is printing currently, use the permanent SfxPrinter instance
264 if ( !pPrinter && pFirst )
265 pPrinter = pFirst->GetViewShell()->GetPrinter(true);
266
267 if ( !pPrinter )
268 return uno::Sequence< beans::PropertyValue >();
269
270 return
271 {
272 comphelper::makePropertyValue("Name", pPrinter->GetName()),
273 comphelper::makePropertyValue("PaperOrientation", static_cast<view::PaperOrientation>(pPrinter->GetOrientation())),
274 comphelper::makePropertyValue("PaperFormat", convertToPaperFormat(pPrinter->GetPaper())),
276 comphelper::makePropertyValue("IsBusy", pPrinter->IsPrinting()),
277 comphelper::makePropertyValue("CanSetPaperOrientation", pPrinter->HasSupport( PrinterSupport::SetOrientation )),
278 comphelper::makePropertyValue("CanSetPaperFormat", pPrinter->HasSupport( PrinterSupport::SetPaper )),
279 comphelper::makePropertyValue("CanSetPaperSize", pPrinter->HasSupport( PrinterSupport::SetPaperSize ))
280 };
281}
282
283
284// XPrintable
285
286
287void SfxPrintHelper::impl_setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter,
288 VclPtr<SfxPrinter>& pPrinter,
289 SfxPrinterChangeFlags& nChangeFlags,
290 SfxViewShell*& pViewSh)
291
292{
293 // Get old Printer
294 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ?
295 SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr;
296 if ( !pViewFrm )
297 return;
298
299 pViewSh = pViewFrm->GetViewShell();
300 pPrinter = pViewSh->GetPrinter(true);
301 if ( !pPrinter )
302 return;
303
304 // new Printer-Name available?
305 nChangeFlags = SfxPrinterChangeFlags::NONE;
306 sal_Int32 lDummy = 0;
307 auto pProp = std::find_if(rPrinter.begin(), rPrinter.end(),
308 [](const beans::PropertyValue &rProp) { return rProp.Name == "Name"; });
309 if (pProp != rPrinter.end())
310 {
311 OUString aPrinterName;
312 if ( ! ( pProp->Value >>= aPrinterName ) )
313 throw css::lang::IllegalArgumentException();
314
315 if ( aPrinterName != pPrinter->GetName() )
316 {
317 pPrinter = VclPtr<SfxPrinter>::Create( pPrinter->GetOptions().Clone(), aPrinterName );
318 nChangeFlags = SfxPrinterChangeFlags::PRINTER;
319 }
320 }
321
322 Size aSetPaperSize( 0, 0);
323 view::PaperFormat nPaperFormat = view::PaperFormat_USER;
324
325 // other properties
326 for ( const beans::PropertyValue &rProp : rPrinter )
327 {
328 // get Property-Value from printer description
329 // PaperOrientation-Property?
330 if ( rProp.Name == "PaperOrientation" )
331 {
332 view::PaperOrientation eOrient;
333 if ( !( rProp.Value >>= eOrient ) )
334 {
335 if ( !( rProp.Value >>= lDummy ) )
336 throw css::lang::IllegalArgumentException();
337 eOrient = static_cast<view::PaperOrientation>(lDummy);
338 }
339
340 if ( static_cast<Orientation>(eOrient) != pPrinter->GetOrientation() )
341 {
342 pPrinter->SetOrientation( static_cast<Orientation>(eOrient) );
344 }
345 }
346
347 // PaperFormat-Property?
348 else if ( rProp.Name == "PaperFormat" )
349 {
350 if ( !( rProp.Value >>= nPaperFormat ) )
351 {
352 if ( !( rProp.Value >>= lDummy ) )
353 throw css::lang::IllegalArgumentException();
354 nPaperFormat = static_cast<view::PaperFormat>(lDummy);
355 }
356
357 if ( convertToPaper(nPaperFormat) != pPrinter->GetPaper() )
358 {
359 pPrinter->SetPaper( convertToPaper(nPaperFormat) );
360 nChangeFlags |= SfxPrinterChangeFlags::CHG_SIZE;
361 }
362 }
363
364 // PaperSize-Property?
365 else if ( rProp.Name == "PaperSize" )
366 {
367 awt::Size aTempSize ;
368 if ( !( rProp.Value >>= aTempSize ) )
369 {
370 throw css::lang::IllegalArgumentException();
371 }
372 aSetPaperSize = impl_Size_Struct2Object(aTempSize);
373 }
374
375 // PrinterTray-Property
376 else if ( rProp.Name == "PrinterPaperTray" )
377 {
378 OUString aTmp;
379 if ( !( rProp.Value >>= aTmp ) )
380 throw css::lang::IllegalArgumentException();
381 const sal_uInt16 nCount = pPrinter->GetPaperBinCount();
382 for (sal_uInt16 nBin=0; nBin<nCount; nBin++)
383 {
384 OUString aName( pPrinter->GetPaperBinName(nBin) );
385 if ( aName == aTmp )
386 {
387 pPrinter->SetPaperBin(nBin);
388 break;
389 }
390 }
391 }
392 }
393
394 // The PaperSize may be set only when actually PAPER_USER
395 // applies, otherwise the driver could choose an invalid format.
396 if(nPaperFormat == view::PaperFormat_USER && aSetPaperSize.Width())
397 {
398 // Bug 56929 - MapMode of 100mm which recalculated when
399 // the device is set. Additionally only set if they were really changed.
400 aSetPaperSize = pPrinter->LogicToPixel(aSetPaperSize, MapMode(MapUnit::Map100thMM));
401 if( aSetPaperSize != pPrinter->GetPaperSizePixel() )
402 {
403 pPrinter->SetPaperSizeUser( pPrinter->PixelToLogic( aSetPaperSize ) );
404 nChangeFlags |= SfxPrinterChangeFlags::CHG_SIZE;
405 }
406 }
407
408 //wait until printing is done
409 SfxPrinter* pDocPrinter = pViewSh->GetPrinter();
410 while ( pDocPrinter->IsPrinting() && !Application::IsQuit())
412}
413
414void SAL_CALL SfxPrintHelper::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter)
415{
416 // object already disposed?
417 SolarMutexGuard aGuard;
418
419 SfxViewShell* pViewSh = nullptr;
420 VclPtr<SfxPrinter> pPrinter;
422 impl_setPrinter(rPrinter,pPrinter,nChangeFlags,pViewSh);
423 // set new printer
424 if ( pViewSh && pPrinter )
425 pViewSh->SetPrinter( pPrinter, nChangeFlags );
426}
427
428
429// ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
430
431namespace {
432
433/* This implements a thread which will be started to wait for asynchronous
434 print jobs to temp. locally files. If they finish we move the temp. files
435 to their right locations by using the ucb.
436 */
437class ImplUCBPrintWatcher : public ::osl::Thread
438{
439 private:
441 VclPtr<SfxPrinter> m_pPrinter;
443 OUString m_sTargetURL;
445 ::utl::TempFileNamed* m_pTempFile;
446
447 public:
448 /* initialize this watcher but don't start it */
449 ImplUCBPrintWatcher( SfxPrinter* pPrinter, ::utl::TempFileNamed* pTempFile, OUString sTargetURL )
450 : m_pPrinter ( pPrinter )
451 , m_sTargetURL(std::move( sTargetURL ))
452 , m_pTempFile ( pTempFile )
453 {}
454
455 /* waits for finishing of the print job and moves the temp file afterwards
456 Note: Starting of the job is done outside this thread!
457 But we have to free some of the given resources on heap!
458 */
459 void SAL_CALL run() override
460 {
461 osl_setThreadName("ImplUCBPrintWatcher");
462
463 /* SAFE { */
464 {
465 SolarMutexGuard aGuard;
466 while( m_pPrinter->IsPrinting() && !Application::IsQuit())
468 m_pPrinter.clear(); // don't delete it! It's borrowed only :-)
469 }
470 /* } SAFE */
471
472 // lock for further using of our member isn't necessary - because
473 // we run alone by definition. Nobody join for us nor use us...
474 moveAndDeleteTemp(&m_pTempFile,m_sTargetURL);
475
476 // finishing of this run() method will call onTerminate() automatically
477 // kill this thread there!
478 }
479
480 /* nobody wait for this thread. We must kill ourself ...
481 */
482 void SAL_CALL onTerminated() override
483 {
484 delete this;
485 }
486
487 /* static helper to move the temp. file to the target location by using the ucb
488 It's static to be usable from outside too. So it's not really necessary to start
489 the thread, if finishing of the job was detected outside this thread.
490 But it must be called without using a corresponding thread for the given parameter!
491 */
492 static void moveAndDeleteTemp( ::utl::TempFileNamed** ppTempFile, std::u16string_view sTargetURL )
493 {
494 // move the file
495 try
496 {
497 INetURLObject aSplitter(sTargetURL);
498 OUString sFileName = aSplitter.getName(
500 true,
502 if (aSplitter.removeSegment() && !sFileName.isEmpty())
503 {
504 ::ucbhelper::Content aSource(
505 (*ppTempFile)->GetURL(),
506 css::uno::Reference< css::ucb::XCommandEnvironment >(),
508
509 ::ucbhelper::Content aTarget(
510 aSplitter.GetMainURL(INetURLObject::DecodeMechanism::NONE),
511 css::uno::Reference< css::ucb::XCommandEnvironment >(),
513
514 aTarget.transferContent(
515 aSource,
517 sFileName,
518 css::ucb::NameClash::OVERWRITE);
519 }
520 }
521 catch (const css::uno::Exception&)
522 {
523 TOOLS_WARN_EXCEPTION( "sfx.doc", "");
524 }
525
526 // kill the temp file!
527 delete *ppTempFile;
528 *ppTempFile = nullptr;
529 }
530};
531
532}
533
534// XPrintable
535
536void SAL_CALL SfxPrintHelper::print(const uno::Sequence< beans::PropertyValue >& rOptions)
537{
538 if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
539 return;
540
541 // object already disposed?
542 // object already disposed?
543 SolarMutexGuard aGuard;
544
545 // get view for sfx printing capabilities
546 SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ?
547 SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr;
548 if ( !pViewFrm )
549 return;
550 SfxViewShell* pView = pViewFrm->GetViewShell();
551 if ( !pView )
552 return;
553 bool bMonitor = false;
554 // We need this information at the end of this method, if we start the vcl printer
555 // by executing the slot. Because if it is a ucb relevant URL we must wait for
556 // finishing the print job and move the temporary local file by using the ucb
557 // to the right location. But in case of no file name is given or it is already
558 // a local one we can suppress this special handling. Because then vcl makes all
559 // right for us.
560 OUString sUcbUrl;
561 ::utl::TempFileNamed* pUCBPrintTempFile = nullptr;
562
563 uno::Sequence < beans::PropertyValue > aCheckedArgs( rOptions.getLength() );
564 auto pCheckedArgs = aCheckedArgs.getArray();
565 sal_Int32 nProps = 0;
566 bool bWaitUntilEnd = false;
567 sal_Int16 nDuplexMode = css::view::DuplexMode::UNKNOWN;
568 for ( const beans::PropertyValue &rProp : rOptions )
569 {
570 // get Property-Value from options
571 // FileName-Property?
572 if ( rProp.Name == "FileName" )
573 {
574 // unpack th URL and check for a valid and well known protocol
575 OUString sTemp;
576 if (
577 ( rProp.Value.getValueType()!=cppu::UnoType<OUString>::get()) ||
578 (!(rProp.Value>>=sTemp))
579 )
580 {
581 throw css::lang::IllegalArgumentException();
582 }
583
584 OUString sPath;
585 OUString sURL (sTemp);
586 INetURLObject aCheck(sURL );
587 if (aCheck.GetProtocol()==INetProtocol::NotValid)
588 {
589 // OK - it's not a valid URL. But may it's a simple
590 // system path directly. It will be supported for historical
591 // reasons. Otherwise we break too much external code...
592 // We try to convert it to a file URL. If it's possible
593 // we put the system path to the item set and let vcl work with it.
594 // No ucb or thread will be necessary then. In case it couldn't be
595 // converted it's not a URL nor a system path. Then we can't accept
596 // this parameter and have to throw an exception.
597 const OUString& sSystemPath(sTemp);
598 OUString sFileURL;
599 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath,sFileURL)!=::osl::FileBase::E_None)
600 throw css::lang::IllegalArgumentException();
601 pCheckedArgs[nProps].Name = rProp.Name;
602 pCheckedArgs[nProps++].Value <<= sFileURL;
603 // and append the local filename
604 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
605 pCheckedArgs = aCheckedArgs.getArray();
606 pCheckedArgs[nProps].Name = "LocalFileName";
607 pCheckedArgs[nProps++].Value <<= sTemp;
608 }
609 else
610 // It's a valid URL. but now we must know, if it is a local one or not.
611 // It's a question of using ucb or not!
612 if (osl::FileBase::getSystemPathFromFileURL(sURL, sPath) == osl::FileBase::E_None)
613 {
614 // it's a local file, we can use vcl without special handling
615 // And we have to use the system notation of the incoming URL.
616 // But it into the descriptor and let the slot be executed at
617 // the end of this method.
618 pCheckedArgs[nProps].Name = rProp.Name;
619 pCheckedArgs[nProps++].Value <<= sTemp;
620 // and append the local filename
621 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
622 pCheckedArgs = aCheckedArgs.getArray();
623 pCheckedArgs[nProps].Name = "LocalFileName";
624 pCheckedArgs[nProps++].Value <<= sPath;
625 }
626 else
627 {
628 // it's a ucb target. So we must use a temp. file for vcl
629 // and move it after printing by using the ucb.
630 // Create a temp file on the heap (because it must delete the
631 // real file on disk automatically if it die - bt we have to share it with
632 // some other sources ... e.g. the ImplUCBPrintWatcher).
633 // And we put the name of this temp file to the descriptor instead
634 // of the URL. The URL we save for later using separately.
635 // Execution of the print job will be done later by executing
636 // a slot ...
637 if(!pUCBPrintTempFile)
638 pUCBPrintTempFile = new ::utl::TempFileNamed();
639 pUCBPrintTempFile->EnableKillingFile();
640
641 //FIXME: does it work?
642 pCheckedArgs[nProps].Name = "LocalFileName";
643 pCheckedArgs[nProps++].Value <<= pUCBPrintTempFile->GetFileName();
644 sUcbUrl = sURL;
645 }
646 }
647
648 // CopyCount-Property
649 else if ( rProp.Name == "CopyCount" )
650 {
651 sal_Int32 nCopies = 0;
652 if ( !( rProp.Value >>= nCopies ) )
653 throw css::lang::IllegalArgumentException();
654 pCheckedArgs[nProps].Name = rProp.Name;
655 pCheckedArgs[nProps++].Value <<= nCopies;
656 }
657
658 // Collate-Property
659 // Sort-Property (deprecated)
660 else if ( rProp.Name == "Collate" || rProp.Name == "Sort" )
661 {
662 bool bTemp;
663 if ( !(rProp.Value >>= bTemp) )
664 throw css::lang::IllegalArgumentException();
665 pCheckedArgs[nProps].Name = "Collate";
666 pCheckedArgs[nProps++].Value <<= bTemp;
667 }
668
669 else if ( rProp.Name == "SinglePrintJobs" )
670 {
671 bool bTemp;
672 if ( !(rProp.Value >>= bTemp) )
673 throw css::lang::IllegalArgumentException();
674 pCheckedArgs[nProps].Name = "SinglePrintJobs";
675 pCheckedArgs[nProps++].Value <<= bTemp;
676 }
677
678 else if ( rProp.Name == "JobName" )
679 {
680 OUString sTemp;
681 if( !(rProp.Value >>= sTemp) )
682 throw css::lang::IllegalArgumentException();
683 pCheckedArgs[nProps].Name = rProp.Name;
684 pCheckedArgs[nProps++].Value <<= sTemp;
685 }
686
687 // Pages-Property
688 else if ( rProp.Name == "Pages" )
689 {
690 OUString sTemp;
691 if( !(rProp.Value >>= sTemp) )
692 throw css::lang::IllegalArgumentException();
693 pCheckedArgs[nProps].Name = rProp.Name;
694 pCheckedArgs[nProps++].Value <<= sTemp;
695 }
696
697 // MonitorVisible
698 else if ( rProp.Name == "MonitorVisible" )
699 {
700 if( !(rProp.Value >>= bMonitor) )
701 throw css::lang::IllegalArgumentException();
702 pCheckedArgs[nProps].Name = rProp.Name;
703 pCheckedArgs[nProps++].Value <<= bMonitor;
704 }
705
706 // Wait
707 else if ( rProp.Name == "Wait" )
708 {
709 if ( !(rProp.Value >>= bWaitUntilEnd) )
710 throw css::lang::IllegalArgumentException();
711 pCheckedArgs[nProps].Name = rProp.Name;
712 pCheckedArgs[nProps++].Value <<= bWaitUntilEnd;
713 }
714
715 else if ( rProp.Name == "DuplexMode" )
716 {
717 if ( !(rProp.Value >>= nDuplexMode ) )
718 throw css::lang::IllegalArgumentException();
719 pCheckedArgs[nProps].Name = rProp.Name;
720 pCheckedArgs[nProps++].Value <<= nDuplexMode;
721 }
722 }
723
724 if ( nProps != aCheckedArgs.getLength() )
725 aCheckedArgs.realloc(nProps);
726
727 // Execute the print request every time.
728 // It doesn't matter if it is a real printer used or we print to a local file
729 // nor if we print to a temp file and move it afterwards by using the ucb.
730 // That will be handled later. see pUCBPrintFile below!
731 pView->ExecPrint( aCheckedArgs, true, false );
732
733 // Ok - may be execution before has finished (or started!) printing.
734 // And may it was a printing to a file.
735 // Now we have to check if we can move the file (if necessary) via UCB to its right location.
736 // Cases:
737 // a) printing finished => move the file directly and forget the watcher thread
738 // b) printing is asynchron and runs currently => start watcher thread and exit this method
739 // This thread make all necessary things by itself.
740 if (!pUCBPrintTempFile)
741 return;
742
743 // a)
744 SfxPrinter* pPrinter = pView->GetPrinter();
745 if ( ! pPrinter->IsPrinting() )
746 ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl);
747 // b)
748 else
749 {
750 // Note: we create(d) some resource on the heap (thread and temp file).
751 // They will be deleted by the thread automatically if it finishes its run() method.
752 ImplUCBPrintWatcher* pWatcher = new ImplUCBPrintWatcher( pPrinter, pUCBPrintTempFile, sUcbUrl );
753 pWatcher->create();
754 }
755}
756
758{
759 const SfxPrintingHint* pPrintHint = dynamic_cast<const SfxPrintingHint*>(&rHint);
760 if ( &rBC != m_pObjectShell.get()
761 || !pPrintHint
762 || pPrintHint->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB )
763 return;
764
765 if ( pPrintHint->GetWhich() == css::view::PrintableState_JOB_STARTED )
766 {
767 if ( !m_xPrintJob.is() )
768 m_xPrintJob = new SfxPrintJob_Impl( this );
769 m_aPrintOptions = pPrintHint->GetOptions();
770 }
771
772 std::unique_lock aGuard(m_aMutex);
773 if (!m_aJobListeners.getLength(aGuard))
774 return;
775 view::PrintJobEvent aEvent;
776 aEvent.Source = m_xPrintJob;
777 aEvent.State = pPrintHint->GetWhich();
778
780 aGuard.unlock();
781 while (pIterator.hasMoreElements())
782 pIterator.next()->printJobEvent( aEvent );
783}
784
785void SAL_CALL SfxPrintHelper::addPrintJobListener( const css::uno::Reference< css::view::XPrintJobListener >& xListener )
786{
787 std::unique_lock aGuard(m_pData->m_aMutex);
788 m_pData->m_aJobListeners.addInterface( aGuard, xListener );
789}
790
791void SAL_CALL SfxPrintHelper::removePrintJobListener( const css::uno::Reference< css::view::XPrintJobListener >& xListener )
792{
793 std::unique_lock aGuard(m_pData->m_aMutex);
794 m_pData->m_aJobListeners.removeInterface( aGuard, xListener );
795}
796
797
798/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
static void Yield()
static const AllSettings & GetSettings()
static bool IsQuit()
INetProtocol GetProtocol() const
bool HasSupport(PrinterSupport eFeature) const
Size GetPaperSize() const
bool IsPrinting() const
const OUString & GetName() const
Orientation GetOrientation() const
Paper GetPaper() const
static SfxObjectShell * GetShellFromComponent(const css::uno::Reference< css::uno::XInterface > &xComp)
Definition: objxtor.cxx:1039
std::unique_ptr< IMPL_PrintListener_DataContainer > m_pData
Definition: printhelper.hxx:59
void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
virtual void SAL_CALL print(const css::uno::Sequence< css::beans::PropertyValue > &seqOptions) override
void impl_setPrinter(const css::uno::Sequence< css::beans::PropertyValue > &rPrinter, VclPtr< SfxPrinter > &pPrinter, SfxPrinterChangeFlags &nChangeFlags, SfxViewShell *&pViewSh)
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getPrinter() override
virtual void SAL_CALL addPrintJobListener(const css::uno::Reference< css::view::XPrintJobListener > &xListener) override
virtual void SAL_CALL removePrintJobListener(const css::uno::Reference< css::view::XPrintJobListener > &xListener) override
virtual ~SfxPrintHelper() override
virtual void SAL_CALL setPrinter(const css::uno::Sequence< css::beans::PropertyValue > &seqPrinter) override
css::view::PrintableState GetWhich() const
Definition: event.hxx:263
const css::uno::Sequence< css::beans::PropertyValue > & GetOptions() const
Definition: event.hxx:264
SfxViewShell * GetViewShell() const
Returns the SfxViewShell in which they are located in the subshells.
Definition: shell.cxx:129
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetNext(const SfxViewFrame &rPrev, const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:2006
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:1983
One SfxViewShell more or less represents one edit window for a document, there can be multiple ones f...
Definition: viewsh.hxx:165
virtual SfxPrinter * GetPrinter(bool bCreate=false)
Definition: viewprn.cxx:904
virtual sal_uInt16 SetPrinter(SfxPrinter *pNewPrinter, SfxPrinterChangeFlags nDiffFlags=SFX_PRINTER_ALL)
Definition: viewprn.cxx:909
void ExecPrint(const css::uno::Sequence< css::beans::PropertyValue > &, bool, bool)
Definition: viewprn.cxx:620
Printer * GetActivePrinter() const
Definition: viewprn.cxx:634
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
void clear()
static VclPtr< reference_type > Create(Arg &&... arg)
sal_Int32 getLength(std::unique_lock< std::mutex > &rGuard) const
css::uno::Reference< ListenerT > const & next()
T * get() const
void EnableKillingFile(bool bEnable=true)
OUString GetFileName() const
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
FmFilterData * m_pData
Sequence< PropertyValue > aArguments
OUString aName
std::unique_ptr< sal_Int32[]> pData
def run(arg=None, arg2=-1)
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
Paper
PAPER_LETTER
PAPER_A5
PAPER_A4
PAPER_USER
PAPER_B5_ISO
PAPER_A3
PAPER_LEGAL
PAPER_TABLOID
PAPER_B4_ISO
static Size impl_Size_Struct2Object(const awt::Size &aSize)
Definition: printhelper.cxx:83
#define SFX_PRINTABLESTATE_CANCELJOB
Definition: printhelper.cxx:53
static awt::Size impl_Size_Object2Struct(const Size &aSize)
Definition: printhelper.cxx:75
Orientation
uno::Reference< css::view::XPrintJob > m_xPrintJob
Definition: printhelper.cxx:63
comphelper::OInterfaceContainerHelper4< view::XPrintJobListener > m_aJobListeners
Definition: printhelper.cxx:62
SfxObjectShellRef m_pObjectShell
Definition: printhelper.cxx:60
css::uno::Sequence< css::beans::PropertyValue > m_aPrintOptions
Definition: printhelper.cxx:64
void Notify(SfxBroadcaster &aBC, const SfxHint &aHint) override
Reference< XModel > xModel
SfxPrinterChangeFlags
Definition: viewsh.hxx:80