bump product version to 5.0.4.1
[LibreOffice.git] / sfx2 / source / view / viewprn.cxx
blob13a0aede92e6835b10d4f782c5e7ffe346dce386
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 .
20 #include <com/sun/star/document/XDocumentProperties.hpp>
21 #include <com/sun/star/view/XRenderable.hpp>
23 #include <svl/itempool.hxx>
24 #include <vcl/layout.hxx>
25 #include <svtools/prnsetup.hxx>
26 #include <svl/flagitem.hxx>
27 #include <svl/stritem.hxx>
28 #include <svl/intitem.hxx>
29 #include <svl/eitem.hxx>
30 #include <sfx2/app.hxx>
31 #include <unotools/useroptions.hxx>
32 #include <unotools/printwarningoptions.hxx>
33 #include <tools/datetime.hxx>
34 #include <sfx2/bindings.hxx>
35 #include <sfx2/objface.hxx>
36 #include <sfx2/viewsh.hxx>
37 #include "viewimp.hxx"
38 #include <sfx2/viewfrm.hxx>
39 #include <sfx2/prnmon.hxx>
40 #include <sfx2/sfxresid.hxx>
41 #include <sfx2/request.hxx>
42 #include <sfx2/objsh.hxx>
43 #include "sfxtypes.hxx"
44 #include <sfx2/event.hxx>
45 #include <sfx2/docfile.hxx>
46 #include <sfx2/docfilt.hxx>
48 #include <toolkit/awt/vclxdevice.hxx>
49 #include <boost/scoped_ptr.hpp>
51 #include "view.hrc"
52 #include "helpid.hrc"
54 using namespace com::sun::star;
55 using namespace com::sun::star::uno;
57 class SfxPrinterController : public vcl::PrinterController, public SfxListener
59 Any maCompleteSelection;
60 Any maSelection;
61 Reference< view::XRenderable > mxRenderable;
62 mutable VclPtr<Printer> mpLastPrinter;
63 mutable Reference<awt::XDevice> mxDevice;
64 SfxViewShell* mpViewShell;
65 SfxObjectShell* mpObjectShell;
66 bool m_bOrigStatus;
67 bool m_bNeedsChange;
68 bool m_bApi;
69 bool m_bTempPrinter;
70 util::DateTime m_aLastPrinted;
71 OUString m_aLastPrintedBy;
73 Sequence< beans::PropertyValue > getMergedOptions() const;
74 const Any& getSelectionObject() const;
76 public:
77 SfxPrinterController( const VclPtr<Printer>& i_rPrinter,
78 const Any& i_rComplete,
79 const Any& i_rSelection,
80 const Any& i_rViewProp,
81 const Reference< view::XRenderable >& i_xRender,
82 bool i_bApi, bool i_bDirect,
83 SfxViewShell* pView,
84 const uno::Sequence< beans::PropertyValue >& rProps
87 virtual ~SfxPrinterController();
88 virtual void Notify( SfxBroadcaster&, const SfxHint& ) SAL_OVERRIDE;
90 virtual int getPageCount() const SAL_OVERRIDE;
91 virtual Sequence< beans::PropertyValue > getPageParameters( int i_nPage ) const SAL_OVERRIDE;
92 virtual void printPage( int i_nPage ) const SAL_OVERRIDE;
93 virtual void jobStarted() SAL_OVERRIDE;
94 virtual void jobFinished( com::sun::star::view::PrintableState ) SAL_OVERRIDE;
97 SfxPrinterController::SfxPrinterController( const VclPtr<Printer>& i_rPrinter,
98 const Any& i_rComplete,
99 const Any& i_rSelection,
100 const Any& i_rViewProp,
101 const Reference< view::XRenderable >& i_xRender,
102 bool i_bApi, bool i_bDirect,
103 SfxViewShell* pView,
104 const uno::Sequence< beans::PropertyValue >& rProps
106 : PrinterController( i_rPrinter)
107 , maCompleteSelection( i_rComplete )
108 , maSelection( i_rSelection )
109 , mxRenderable( i_xRender )
110 , mpLastPrinter( NULL )
111 , mpViewShell( pView )
112 , mpObjectShell(0)
113 , m_bOrigStatus( false )
114 , m_bNeedsChange( false )
115 , m_bApi(i_bApi)
116 , m_bTempPrinter( i_rPrinter.get() != NULL )
118 if ( mpViewShell )
120 StartListening( *mpViewShell );
121 mpObjectShell = mpViewShell->GetObjectShell();
122 StartListening( *mpObjectShell );
125 // initialize extra ui options
126 if( mxRenderable.is() )
128 for (sal_Int32 nProp=0; nProp < rProps.getLength(); ++nProp)
129 setValue( rProps[nProp].Name, rProps[nProp].Value );
131 Sequence< beans::PropertyValue > aRenderOptions( 3 );
132 aRenderOptions[0].Name = "ExtraPrintUIOptions";
133 aRenderOptions[1].Name = "View" ;
134 aRenderOptions[1].Value = i_rViewProp;
135 aRenderOptions[2].Name = "IsPrinter";
136 aRenderOptions[2].Value <<= sal_True;
139 Sequence< beans::PropertyValue > aRenderParms( mxRenderable->getRenderer( 0 , getSelectionObject(), aRenderOptions ) );
140 int nProps = aRenderParms.getLength();
141 for( int i = 0; i < nProps; i++ )
143 if ( aRenderParms[i].Name == "ExtraPrintUIOptions" )
145 Sequence< beans::PropertyValue > aUIProps;
146 aRenderParms[i].Value >>= aUIProps;
147 setUIOptions( aUIProps );
149 else if( aRenderParms[i].Name == "NUp" )
151 setValue( aRenderParms[i].Name, aRenderParms[i].Value );
155 catch( lang::IllegalArgumentException& )
157 // the first renderer should always be available for the UI options,
158 // but catch the exception to be safe
162 // set some job parameters
163 setValue( OUString( "IsApi" ), makeAny( i_bApi ) );
164 setValue( OUString( "IsDirect" ), makeAny( i_bDirect ) );
165 setValue( OUString( "IsPrinter" ), makeAny( sal_True ) );
166 setValue( OUString( "View" ), i_rViewProp );
169 void SfxPrinterController::Notify( SfxBroadcaster& , const SfxHint& rHint )
171 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
172 if ( pSimpleHint )
174 if ( pSimpleHint->GetId() == SFX_HINT_DYING )
176 EndListening(*mpViewShell);
177 EndListening(*mpObjectShell);
178 mpViewShell = 0;
179 mpObjectShell = 0;
184 SfxPrinterController::~SfxPrinterController()
188 const Any& SfxPrinterController::getSelectionObject() const
190 const beans::PropertyValue* pVal = getValue( OUString( "PrintSelectionOnly" ) );
191 if( pVal )
193 bool bSel = false;
194 pVal->Value >>= bSel;
195 return bSel ? maSelection : maCompleteSelection;
198 sal_Int32 nChoice = 0;
199 pVal = getValue( OUString( "PrintContent" ) );
200 if( pVal )
201 pVal->Value >>= nChoice;
202 return (nChoice > 1) ? maSelection : maCompleteSelection;
205 Sequence< beans::PropertyValue > SfxPrinterController::getMergedOptions() const
207 VclPtr<Printer> xPrinter( getPrinter() );
208 if( xPrinter.get() != mpLastPrinter )
210 mpLastPrinter = xPrinter.get();
211 VCLXDevice* pXDevice = new VCLXDevice();
212 pXDevice->SetOutputDevice( mpLastPrinter );
213 mxDevice = Reference< awt::XDevice >( pXDevice );
216 Sequence< beans::PropertyValue > aRenderOptions( 1 );
217 aRenderOptions[ 0 ].Name = "RenderDevice";
218 aRenderOptions[ 0 ].Value <<= mxDevice;
220 aRenderOptions = getJobProperties( aRenderOptions );
221 return aRenderOptions;
224 int SfxPrinterController::getPageCount() const
226 int nPages = 0;
227 VclPtr<Printer> xPrinter( getPrinter() );
228 if( mxRenderable.is() && xPrinter )
230 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
233 nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions );
235 catch (lang::DisposedException &)
237 OSL_TRACE("SfxPrinterController: document disposed while printing");
238 const_cast<SfxPrinterController*>(this)->setJobState(
239 view::PrintableState_JOB_ABORTED);
242 return nPages;
245 Sequence< beans::PropertyValue > SfxPrinterController::getPageParameters( int i_nPage ) const
247 VclPtr<Printer> xPrinter( getPrinter() );
248 Sequence< beans::PropertyValue > aResult;
250 if (mxRenderable.is() && xPrinter)
252 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
255 aResult = mxRenderable->getRenderer( i_nPage, getSelectionObject(), aJobOptions );
257 catch( lang::IllegalArgumentException& )
260 catch (lang::DisposedException &)
262 OSL_TRACE("SfxPrinterController: document disposed while printing");
263 const_cast<SfxPrinterController*>(this)->setJobState(
264 view::PrintableState_JOB_ABORTED);
267 return aResult;
270 void SfxPrinterController::printPage( int i_nPage ) const
272 VclPtr<Printer> xPrinter( getPrinter() );
273 if( mxRenderable.is() && xPrinter )
275 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
278 mxRenderable->render( i_nPage, getSelectionObject(), aJobOptions );
280 catch( lang::IllegalArgumentException& )
282 // don't care enough about nonexistant page here
283 // to provoke a crash
285 catch (lang::DisposedException &)
287 OSL_TRACE("SfxPrinterController: document disposed while printing");
288 const_cast<SfxPrinterController*>(this)->setJobState(
289 view::PrintableState_JOB_ABORTED);
294 void SfxPrinterController::jobStarted()
296 if ( mpObjectShell )
298 m_bOrigStatus = mpObjectShell->IsEnableSetModified();
300 // check configuration: shall update of printing information in DocInfo set the document to "modified"?
301 if ( m_bOrigStatus && !SvtPrintWarningOptions().IsModifyDocumentOnPrintingAllowed() )
303 mpObjectShell->EnableSetModified( false );
304 m_bNeedsChange = true;
307 // refresh document info
308 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
309 m_aLastPrintedBy = xDocProps->getPrintedBy();
310 m_aLastPrinted = xDocProps->getPrintDate();
312 xDocProps->setPrintedBy( mpObjectShell->IsUseUserData()
313 ? OUString( SvtUserOptions().GetFullName() )
314 : OUString() );
315 ::DateTime now( ::DateTime::SYSTEM );
317 xDocProps->setPrintDate( now.GetUNODateTime() );
319 SfxGetpApp()->NotifyEvent( SfxEventHint(SFX_EVENT_PRINTDOC, GlobalEventConfig::GetEventName( GlobalEventId::PRINTDOC ), mpObjectShell ) );
320 uno::Sequence < beans::PropertyValue > aOpts;
321 aOpts = getJobProperties( aOpts );
323 uno::Reference< frame::XController2 > xController;
324 if ( mpViewShell )
325 xController.set( mpViewShell->GetController(), uno::UNO_QUERY );
327 mpObjectShell->Broadcast( SfxPrintingHint(
328 view::PrintableState_JOB_STARTED, aOpts, mpObjectShell, xController ) );
332 void SfxPrinterController::jobFinished( com::sun::star::view::PrintableState nState )
334 if ( mpObjectShell )
336 bool bCopyJobSetup = false;
337 mpObjectShell->Broadcast( SfxPrintingHint( nState ) );
338 switch ( nState )
340 case view::PrintableState_JOB_SPOOLING_FAILED :
341 case view::PrintableState_JOB_FAILED :
343 // "real" problem (not simply printing cancelled by user)
344 OUString aMsg( SfxResId(STR_NOSTARTPRINTER).toString() );
345 if ( !m_bApi )
346 ScopedVclPtrInstance<MessageDialog>::Create(mpViewShell->GetWindow(), aMsg)->Execute();
347 // intentionally no break
349 case view::PrintableState_JOB_ABORTED :
351 // printing not successful, reset DocInfo
352 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
353 xDocProps->setPrintedBy(m_aLastPrintedBy);
354 xDocProps->setPrintDate(m_aLastPrinted);
355 break;
358 case view::PrintableState_JOB_SPOOLED :
359 case view::PrintableState_JOB_COMPLETED :
361 SfxBindings& rBind = mpViewShell->GetViewFrame()->GetBindings();
362 rBind.Invalidate( SID_PRINTDOC );
363 rBind.Invalidate( SID_PRINTDOCDIRECT );
364 rBind.Invalidate( SID_SETUPPRINTER );
365 bCopyJobSetup = ! m_bTempPrinter;
366 break;
369 default:
370 break;
373 if( bCopyJobSetup && mpViewShell )
375 // #i114306#
376 // Note: this possibly creates a printer that gets immediately replaced
377 // by a new one. The reason for this is that otherwise we would not get
378 // the printer's SfxItemSet here to copy. Awkward, but at the moment there is no
379 // other way here to get the item set.
380 SfxPrinter* pDocPrt = mpViewShell->GetPrinter(true);
381 if( pDocPrt )
383 if( pDocPrt->GetName() == getPrinter()->GetName() )
384 pDocPrt->SetJobSetup( getPrinter()->GetJobSetup() );
385 else
387 VclPtr<SfxPrinter> pNewPrt = VclPtr<SfxPrinter>::Create( pDocPrt->GetOptions().Clone(), getPrinter()->GetName() );
388 pNewPrt->SetJobSetup( getPrinter()->GetJobSetup() );
389 mpViewShell->SetPrinter( pNewPrt, SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP );
394 if ( m_bNeedsChange )
395 mpObjectShell->EnableSetModified( m_bOrigStatus );
397 if ( mpViewShell )
399 mpViewShell->pImp->m_xPrinterController.reset();
405 An instance of this class is created for the life span of the
406 printer dialogue, to create in its click handler for the additions by the
407 virtual method of the derived SfxViewShell generated print options dialogue
408 and to cache the options set there as SfxItemSet.
410 class SfxDialogExecutor_Impl
412 private:
413 SfxViewShell* _pViewSh;
414 VclPtr<PrinterSetupDialog> _pSetupParent;
415 SfxItemSet* _pOptions;
416 bool _bHelpDisabled;
418 DECL_LINK( Execute, void * );
420 public:
421 SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog* pParent );
422 ~SfxDialogExecutor_Impl() { delete _pOptions; }
424 Link<> GetLink() const { return LINK(const_cast<SfxDialogExecutor_Impl*>(this), SfxDialogExecutor_Impl, Execute); }
425 const SfxItemSet* GetOptions() const { return _pOptions; }
426 void DisableHelp() { _bHelpDisabled = true; }
429 SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog* pParent ) :
431 _pViewSh ( pViewSh ),
432 _pSetupParent ( pParent ),
433 _pOptions ( NULL ),
434 _bHelpDisabled ( false )
439 IMPL_LINK_NOARG(SfxDialogExecutor_Impl, Execute)
441 // Options noted locally
442 if ( !_pOptions )
444 DBG_ASSERT( _pSetupParent, "no dialog parent" );
445 if( _pSetupParent )
446 _pOptions = static_cast<SfxPrinter*>( _pSetupParent->GetPrinter() )->GetOptions().Clone();
449 assert(_pOptions);
450 if (!_pOptions)
451 return 0;
453 // Create Dialog
454 VclPtrInstance<SfxPrintOptionsDialog> pDlg( static_cast<vcl::Window*>(_pSetupParent),
455 _pViewSh, _pOptions );
456 if ( _bHelpDisabled )
457 pDlg->DisableHelp();
458 if ( pDlg->Execute() == RET_OK )
460 delete _pOptions;
461 _pOptions = pDlg->GetOptions().Clone();
465 return 0;
469 Internal method for setting the differences between 'pNewPrinter' to the
470 current printer. pNewPrinter is either taken over or deleted.
472 SfxPrinter* SfxViewShell::SetPrinter_Impl( VclPtr<SfxPrinter>& pNewPrinter )
474 // get current Printer
475 SfxPrinter *pDocPrinter = GetPrinter();
477 // Evaluate Printer Options
478 sal_uInt16 nWhich = GetPool().GetWhich(SID_PRINTER_CHANGESTODOC);
479 const SfxFlagItem *pFlagItem = 0;
480 pDocPrinter->GetOptions().GetItemState( nWhich, false, reinterpret_cast<const SfxPoolItem**>(&pFlagItem) );
481 bool bOriToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION);
482 bool bSizeToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE);
484 // Determine the previous format and size
485 Orientation eOldOri = pDocPrinter->GetOrientation();
486 Size aOldPgSz = pDocPrinter->GetPaperSizePixel();
488 // Determine the new format and size
489 Orientation eNewOri = pNewPrinter->GetOrientation();
490 Size aNewPgSz = pNewPrinter->GetPaperSizePixel();
492 // Determine the changes in page format
493 bool bOriChg = (eOldOri != eNewOri) && bOriToDoc;
494 bool bPgSzChg = ( aOldPgSz.Height() !=
495 ( bOriChg ? aNewPgSz.Width() : aNewPgSz.Height() ) ||
496 aOldPgSz.Width() !=
497 ( bOriChg ? aNewPgSz.Height() : aNewPgSz.Width() ) ) &&
498 bSizeToDoc;
500 // Message and Flags for page format, summaries changes
501 OUString aMsg;
502 SfxPrinterChangeFlags nNewOpt = SfxPrinterChangeFlags::NONE;
503 if( bOriChg && bPgSzChg )
505 aMsg = SfxResId(STR_PRINT_NEWORISIZE).toString();
506 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION | SfxPrinterChangeFlags::CHG_SIZE;
508 else if (bOriChg )
510 aMsg = SfxResId(STR_PRINT_NEWORI).toString();
511 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION;
513 else if (bPgSzChg)
515 aMsg = SfxResId(STR_PRINT_NEWSIZE).toString();
516 nNewOpt = SfxPrinterChangeFlags::CHG_SIZE;
519 // Summaries in this variable what has been changed.
520 SfxPrinterChangeFlags nChangedFlags = SfxPrinterChangeFlags::NONE;
522 // Ask if possible, if page format should be taken over from printer.
523 if ( ( bOriChg || bPgSzChg ) &&
524 RET_YES == ScopedVclPtrInstance<MessageDialog>::Create(nullptr, aMsg, VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO)->Execute() )
526 // Flags with changes for <SetPrinter(SfxPrinter*)> are maintained
527 nChangedFlags |= nNewOpt;
530 // For the MAC to have its "temporary of class String" in next if()
531 OUString aTempPrtName = pNewPrinter->GetName();
532 OUString aDocPrtName = pDocPrinter->GetName();
534 // Was the printer selection changed from Default to Specific
535 // or the other way around?
536 if ( (aTempPrtName != aDocPrtName) || (pDocPrinter->IsDefPrinter() != pNewPrinter->IsDefPrinter()) )
538 nChangedFlags |= SfxPrinterChangeFlags::PRINTER|SfxPrinterChangeFlags::JOBSETUP;
539 pDocPrinter = pNewPrinter;
541 else
543 // Compare extra options
544 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
546 // Option have changed
547 pDocPrinter->SetOptions( pNewPrinter->GetOptions() );
548 nChangedFlags |= SfxPrinterChangeFlags::OPTIONS;
551 // Compare JobSetups
552 JobSetup aNewJobSetup = pNewPrinter->GetJobSetup();
553 JobSetup aOldJobSetup = pDocPrinter->GetJobSetup();
554 if ( aNewJobSetup != aOldJobSetup )
556 nChangedFlags |= SfxPrinterChangeFlags::JOBSETUP;
559 // Keep old changed Printer.
560 pDocPrinter->SetPrinterProps( pNewPrinter );
561 pNewPrinter.disposeAndClear();
564 if ( SfxPrinterChangeFlags::NONE != nChangedFlags )
565 // SetPrinter will delete the old printer if it changes
566 SetPrinter( pDocPrinter, nChangedFlags );
567 return pDocPrinter;
570 void SfxViewShell::StartPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
572 assert( pImp->m_xPrinterController.get() == NULL );
574 // get the current selection; our controller should know it
575 Reference< frame::XController > xController( GetController() );
576 Reference< view::XSelectionSupplier > xSupplier( xController, UNO_QUERY );
578 Any aSelection;
579 if( xSupplier.is() )
580 aSelection = xSupplier->getSelection();
581 else
582 aSelection <<= GetObjectShell()->GetModel();
583 Any aComplete( makeAny( GetObjectShell()->GetModel() ) );
584 Any aViewProp( makeAny( xController ) );
585 VclPtr<Printer> aPrt;
587 const beans::PropertyValue* pVal = rProps.getConstArray();
588 for( sal_Int32 i = 0; i < rProps.getLength(); i++ )
590 if ( pVal[i].Name == "PrinterName" )
592 OUString aPrinterName;
593 pVal[i].Value >>= aPrinterName;
594 aPrt.reset( VclPtr<Printer>::Create( aPrinterName ) );
595 break;
599 std::shared_ptr<vcl::PrinterController> xNewController(std::make_shared<SfxPrinterController>(
600 aPrt,
601 aComplete,
602 aSelection,
603 aViewProp,
604 GetRenderable(),
605 bIsAPI,
606 bIsDirect,
607 this,
608 rProps
610 pImp->m_xPrinterController = xNewController;
612 SfxObjectShell *pObjShell = GetObjectShell();
613 xNewController->setValue( OUString( "JobName" ),
614 makeAny( OUString( pObjShell->GetTitle(0) ) ) );
615 xNewController->setPrinterModified( mbPrinterSettingsModified );
618 void SfxViewShell::ExecPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
620 StartPrint( rProps, bIsAPI, bIsDirect );
621 // FIXME: job setup
622 SfxPrinter* pDocPrt = GetPrinter(false);
623 JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : GetJobSetup();
624 Printer::PrintJob( GetPrinterController(), aJobSetup );
627 std::shared_ptr< vcl::PrinterController > SfxViewShell::GetPrinterController() const
629 return pImp->m_xPrinterController;
632 Printer* SfxViewShell::GetActivePrinter() const
634 return (pImp->m_xPrinterController)
635 ? pImp->m_xPrinterController->getPrinter().get() : 0;
638 void SfxViewShell::ExecPrint_Impl( SfxRequest &rReq )
640 sal_uInt16 nDialogRet = RET_CANCEL;
641 VclPtr<SfxPrinter> pPrinter;
642 bool bSilent = false;
644 // does the function have been called by the user interface or by an API call
645 bool bIsAPI = rReq.GetArgs() && rReq.GetArgs()->Count();
646 if ( bIsAPI )
648 // the function have been called by the API
650 // Should it be visible on the user interface,
651 // should it launch popup dialogue ?
652 SFX_REQUEST_ARG(rReq, pSilentItem, SfxBoolItem, SID_SILENT, false);
653 bSilent = pSilentItem && pSilentItem->GetValue();
656 // no help button in dialogs if called from the help window
657 // (pressing help button would exchange the current page inside the help
658 // document that is going to be printed!)
659 OUString aHelpFilterName( "writer_web_HTML_help" );
660 SfxMedium* pMedium = GetViewFrame()->GetObjectShell()->GetMedium();
661 const SfxFilter* pFilter = pMedium ? pMedium->GetFilter() : NULL;
662 bool bPrintOnHelp = ( pFilter && pFilter->GetFilterName() == aHelpFilterName );
664 const sal_uInt16 nId = rReq.GetSlot();
665 switch( nId )
667 case SID_PRINTDOC: // display the printer selection and properties dialogue : File > Print...
668 case SID_PRINTDOCDIRECT: // Print the document directly, without displaying the dialogue
670 SfxObjectShell* pDoc = GetObjectShell();
672 // derived class may decide to abort this
673 if( pDoc == NULL || !pDoc->QuerySlotExecutable( nId ) )
675 rReq.SetReturnValue( SfxBoolItem( 0, false ) );
676 return;
679 if ( !bSilent && pDoc->QueryHiddenInformation( HiddenWarningFact::WhenPrinting, NULL ) != RET_YES )
680 return;
682 // should we print only the selection or the whole document
683 SFX_REQUEST_ARG(rReq, pSelectItem, SfxBoolItem, SID_SELECTION, false);
684 bool bSelection = ( pSelectItem != NULL && pSelectItem->GetValue() );
685 // detect non api call from writer ( that adds SID_SELECTION ) and reset bIsAPI
686 if ( pSelectItem && rReq.GetArgs()->Count() == 1 )
687 bIsAPI = false;
689 uno::Sequence < beans::PropertyValue > aProps;
690 if ( bIsAPI )
692 // supported properties:
693 // String PrinterName
694 // String FileName
695 // Int16 From
696 // Int16 To
697 // In16 Copies
698 // String RangeText
699 // bool Selection
700 // bool Asynchron
701 // bool Collate
702 // bool Silent
704 // the TransformItems function overwrite aProps
705 TransformItems( nId, *rReq.GetArgs(), aProps, GetInterface()->GetSlot(nId) );
707 for ( sal_Int32 nProp=0; nProp < aProps.getLength(); ++nProp )
709 if ( aProps[nProp].Name == "Copies" )
711 aProps[nProp]. Name = "CopyCount";
713 else if ( aProps[nProp].Name == "RangeText" )
715 aProps[nProp]. Name = "Pages";
717 else if ( aProps[nProp].Name == "Asynchron" )
719 aProps[nProp]. Name = "Wait";
720 bool bAsynchron = false;
721 aProps[nProp].Value >>= bAsynchron;
722 aProps[nProp].Value <<= (!bAsynchron);
724 else if ( aProps[nProp].Name == "Silent" )
726 aProps[nProp]. Name = "MonitorVisible";
727 bool bPrintSilent = false;
728 aProps[nProp].Value >>= bPrintSilent;
729 aProps[nProp].Value <<= (!bPrintSilent);
734 // we will add the "PrintSelectionOnly" or "HideHelpButton" properties
735 // we have to increase the capacity of aProps
736 sal_Int32 nLen = aProps.getLength();
737 aProps.realloc( nLen + 1 );
739 // HACK: writer sets the SID_SELECTION item when printing directly and expects
740 // to get only the selection document in that case (see getSelectionObject)
741 // however it also reacts to the PrintContent property. We need this distinction here, too,
742 // else one of the combinations print / print direct and selection / all will not work.
743 // it would be better if writer handled this internally
744 if( nId == SID_PRINTDOCDIRECT )
746 aProps[nLen].Name = "PrintSelectionOnly";
747 aProps[nLen].Value = makeAny( bSelection );
749 else // if nId == SID_PRINTDOC ; nothing to do with the previous HACK
751 // should the printer selection and properties dialogue display an help button
752 aProps[nLen].Name = "HideHelpButton";
753 aProps[nLen].Value = makeAny( bPrintOnHelp );
756 ExecPrint( aProps, bIsAPI, (nId == SID_PRINTDOCDIRECT) );
758 // FIXME: Recording
759 rReq.Done();
760 break;
763 case SID_SETUPPRINTER : // display the printer settings dialogue : File > Printer Settings...
764 case SID_PRINTER_NAME : // only for recorded macros
766 // get printer and printer settings from the document
767 SfxPrinter *pDocPrinter = GetPrinter(true);
769 // look for printer in parameters
770 SFX_REQUEST_ARG( rReq, pPrinterItem, SfxStringItem, SID_PRINTER_NAME, false );
771 if ( pPrinterItem )
773 // use PrinterName parameter to create a printer
774 pPrinter = VclPtr<SfxPrinter>::Create( pDocPrinter->GetOptions().Clone(), pPrinterItem->GetValue() );
776 // if printer is unknown, it can't be used - now printer from document will be used
777 if ( !pPrinter->IsKnown() )
778 pPrinter.disposeAndClear();
781 if ( SID_PRINTER_NAME == nId )
783 // just set a recorded printer name
784 if ( pPrinter )
785 SetPrinter( pPrinter, SfxPrinterChangeFlags::PRINTER );
786 return;
789 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
790 if ( !pPrinter )
791 // use default printer from document
792 pPrinter = pDocPrinter;
794 if( !pPrinter || !pPrinter->IsValid() )
796 // no valid printer either in ItemSet or at the document
797 if ( !bSilent )
798 ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SfxResId(STR_NODEFPRINTER))->Execute();
800 rReq.SetReturnValue(SfxBoolItem(0,false));
802 break;
805 // FIXME: printer isn't used for printing anymore!
806 if( pPrinter->IsPrinting() )
808 // if printer is busy, abort configuration
809 if ( !bSilent )
810 ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SfxResId(STR_ERROR_PRINTER_BUSY), VCL_MESSAGE_INFO)->Execute();
811 rReq.SetReturnValue(SfxBoolItem(0,false));
813 return;
816 // if no arguments are given, retrieve them from a dialog
817 if ( !bIsAPI )
819 // PrinterDialog needs a temporary printer
820 VclPtr<SfxPrinter> pDlgPrinter = pPrinter->Clone();
821 nDialogRet = 0;
823 // execute PrinterSetupDialog
824 VclPtrInstance<PrinterSetupDialog> pPrintSetupDlg( GetWindow() );
825 SfxDialogExecutor_Impl* pExecutor = 0;
827 if (pImp->m_bHasPrintOptions && HasPrintOptionsPage())
829 // additional controls for dialog
830 pExecutor = new SfxDialogExecutor_Impl( this, pPrintSetupDlg );
831 if ( bPrintOnHelp )
832 pExecutor->DisableHelp();
833 pPrintSetupDlg->SetOptionsHdl( pExecutor->GetLink() );
836 pPrintSetupDlg->SetPrinter( pDlgPrinter );
837 nDialogRet = pPrintSetupDlg->Execute();
839 if ( pExecutor && pExecutor->GetOptions() )
841 if ( nDialogRet == RET_OK )
842 // remark: have to be recorded if possible!
843 pDlgPrinter->SetOptions( *pExecutor->GetOptions() );
844 else
846 pPrinter->SetOptions( *pExecutor->GetOptions() );
847 SetPrinter( pPrinter, SfxPrinterChangeFlags::OPTIONS );
851 pPrintSetupDlg.disposeAndClear();
852 delete pExecutor;
854 // no recording of PrinterSetup except printer name (is printer dependent)
855 rReq.Ignore();
857 if ( nDialogRet == RET_OK )
859 if ( pPrinter->GetName() != pDlgPrinter->GetName() )
861 // user has changed the printer -> macro recording
862 SfxRequest aReq( GetViewFrame(), SID_PRINTER_NAME );
863 aReq.AppendItem( SfxStringItem( SID_PRINTER_NAME, pDlgPrinter->GetName() ) );
864 aReq.Done();
867 // take the changes made in the dialog
868 SetPrinter_Impl( pDlgPrinter );
870 // forget new printer, it was taken over (as pPrinter) or deleted
871 pDlgPrinter = NULL;
872 mbPrinterSettingsModified = true;
874 else
876 // PrinterDialog is used to transfer information on printing,
877 // so it will only be deleted here if dialog was cancelled
878 pDlgPrinter.disposeAndClear();
879 rReq.Ignore();
886 SfxPrinter* SfxViewShell::GetPrinter( bool /*bCreate*/ )
888 return 0;
891 sal_uInt16 SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, SfxPrinterChangeFlags /*nDiffFlags*/, bool )
893 return 0;
896 VclPtr<SfxTabPage> SfxViewShell::CreatePrintOptionsPage
898 vcl::Window* /*pParent*/,
899 const SfxItemSet& /*rOptions*/
902 return VclPtr<SfxTabPage>();
905 bool SfxViewShell::HasPrintOptionsPage() const
907 return false;
910 JobSetup SfxViewShell::GetJobSetup()
912 return JobSetup();
915 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */