Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / sfx2 / source / view / viewprn.cxx
blob7ec660c7aff664f7b26dcd190ae310170d582f54
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 <memory>
22 #include <com/sun/star/document/XDocumentProperties.hpp>
23 #include <com/sun/star/view/XRenderable.hpp>
24 #include <com/sun/star/view/XSelectionSupplier.hpp>
25 #include <officecfg/Office/Common.hxx>
26 #include <sal/log.hxx>
27 #include <svl/itempool.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/weld.hxx>
30 #include <svtools/prnsetup.hxx>
31 #include <svl/flagitem.hxx>
32 #include <svl/stritem.hxx>
33 #include <svl/eitem.hxx>
34 #include <sfx2/app.hxx>
35 #include <unotools/useroptions.hxx>
36 #include <tools/datetime.hxx>
37 #include <sfx2/bindings.hxx>
38 #include <sfx2/objface.hxx>
39 #include <sfx2/viewsh.hxx>
40 #include "viewimp.hxx"
41 #include <sfx2/viewfrm.hxx>
42 #include <sfx2/printer.hxx>
43 #include <sfx2/sfxresid.hxx>
44 #include <sfx2/request.hxx>
45 #include <sfx2/objsh.hxx>
46 #include <sfx2/event.hxx>
47 #include <sfx2/docfile.hxx>
48 #include <sfx2/docfilt.hxx>
49 #include <sfx2/sfxsids.hrc>
50 #include <sfx2/strings.hrc>
51 #include <sfx2/sfxuno.hxx>
52 #include <sfx2/tabdlg.hxx>
54 #include <toolkit/awt/vclxdevice.hxx>
56 #include "prnmon.hxx"
58 using namespace com::sun::star;
59 using namespace com::sun::star::uno;
61 class SfxPrinterController : public vcl::PrinterController, public SfxListener
63 Any maCompleteSelection;
64 Any maSelection;
65 Reference< view::XRenderable > mxRenderable;
66 mutable VclPtr<Printer> mpLastPrinter;
67 mutable Reference<awt::XDevice> mxDevice;
68 SfxViewShell* mpViewShell;
69 SfxObjectShell* mpObjectShell;
70 bool m_bOrigStatus;
71 bool m_bNeedsChange;
72 bool m_bApi;
73 bool m_bTempPrinter;
74 util::DateTime m_aLastPrinted;
75 OUString m_aLastPrintedBy;
77 Sequence< beans::PropertyValue > getMergedOptions() const;
78 const Any& getSelectionObject() const;
80 public:
81 SfxPrinterController( const VclPtr<Printer>& i_rPrinter,
82 const Any& i_rComplete,
83 const Any& i_rSelection,
84 const Any& i_rViewProp,
85 const Reference< view::XRenderable >& i_xRender,
86 bool i_bApi, bool i_bDirect,
87 SfxViewShell* pView,
88 const uno::Sequence< beans::PropertyValue >& rProps
91 virtual void Notify( SfxBroadcaster&, const SfxHint& ) override;
93 virtual int getPageCount() const override;
94 virtual Sequence< beans::PropertyValue > getPageParameters( int i_nPage ) const override;
95 virtual void printPage( int i_nPage ) const override;
96 virtual void jobStarted() override;
97 virtual void jobFinished( css::view::PrintableState ) override;
100 SfxPrinterController::SfxPrinterController( const VclPtr<Printer>& i_rPrinter,
101 const Any& i_rComplete,
102 const Any& i_rSelection,
103 const Any& i_rViewProp,
104 const Reference< view::XRenderable >& i_xRender,
105 bool i_bApi, bool i_bDirect,
106 SfxViewShell* pView,
107 const uno::Sequence< beans::PropertyValue >& rProps
109 : PrinterController(i_rPrinter, pView ? pView->GetFrameWeld() : nullptr)
110 , maCompleteSelection( i_rComplete )
111 , maSelection( i_rSelection )
112 , mxRenderable( i_xRender )
113 , mpLastPrinter( nullptr )
114 , mpViewShell( pView )
115 , mpObjectShell(nullptr)
116 , m_bOrigStatus( false )
117 , m_bNeedsChange( false )
118 , m_bApi(i_bApi)
119 , m_bTempPrinter( i_rPrinter )
121 if ( mpViewShell )
123 StartListening( *mpViewShell );
124 mpObjectShell = mpViewShell->GetObjectShell();
125 StartListening( *mpObjectShell );
128 // initialize extra ui options
129 if( mxRenderable.is() )
131 for (const auto& rProp : rProps)
132 setValue( rProp.Name, rProp.Value );
134 Sequence< beans::PropertyValue > aRenderOptions( 3 );
135 aRenderOptions[0].Name = "ExtraPrintUIOptions";
136 aRenderOptions[1].Name = "View" ;
137 aRenderOptions[1].Value = i_rViewProp;
138 aRenderOptions[2].Name = "IsPrinter";
139 aRenderOptions[2].Value <<= true;
142 const Sequence< beans::PropertyValue > aRenderParms( mxRenderable->getRenderer( 0 , getSelectionObject(), aRenderOptions ) );
143 for( const auto& rRenderParm : aRenderParms )
145 if ( rRenderParm.Name == "ExtraPrintUIOptions" )
147 Sequence< beans::PropertyValue > aUIProps;
148 rRenderParm.Value >>= aUIProps;
149 setUIOptions( aUIProps );
151 else if( rRenderParm.Name == "NUp" )
153 setValue( rRenderParm.Name, rRenderParm.Value );
157 catch( lang::IllegalArgumentException& )
159 // the first renderer should always be available for the UI options,
160 // but catch the exception to be safe
164 // set some job parameters
165 setValue( "IsApi", makeAny( i_bApi ) );
166 setValue( "IsDirect", makeAny( i_bDirect ) );
167 setValue( "IsPrinter", makeAny( true ) );
168 setValue( "View", i_rViewProp );
171 void SfxPrinterController::Notify( SfxBroadcaster& , const SfxHint& rHint )
173 if ( rHint.GetId() == SfxHintId::Dying )
175 EndListening(*mpViewShell);
176 EndListening(*mpObjectShell);
177 dialogsParentClosing();
178 mpViewShell = nullptr;
179 mpObjectShell = nullptr;
183 const Any& SfxPrinterController::getSelectionObject() const
185 const beans::PropertyValue* pVal = getValue( OUString( "PrintSelectionOnly" ) );
186 if( pVal )
188 bool bSel = false;
189 pVal->Value >>= bSel;
190 return bSel ? maSelection : maCompleteSelection;
193 sal_Int32 nChoice = 0;
194 pVal = getValue( OUString( "PrintContent" ) );
195 if( pVal )
196 pVal->Value >>= nChoice;
198 return (nChoice > 1) ? maSelection : maCompleteSelection;
201 Sequence< beans::PropertyValue > SfxPrinterController::getMergedOptions() const
203 VclPtr<Printer> xPrinter( getPrinter() );
204 if( xPrinter.get() != mpLastPrinter )
206 mpLastPrinter = xPrinter.get();
207 VCLXDevice* pXDevice = new VCLXDevice();
208 pXDevice->SetOutputDevice( mpLastPrinter );
209 mxDevice.set( pXDevice );
212 Sequence< beans::PropertyValue > aRenderOptions( 1 );
213 aRenderOptions[ 0 ].Name = "RenderDevice";
214 aRenderOptions[ 0 ].Value <<= mxDevice;
216 aRenderOptions = getJobProperties( aRenderOptions );
217 return aRenderOptions;
220 int SfxPrinterController::getPageCount() const
222 int nPages = 0;
223 VclPtr<Printer> xPrinter( getPrinter() );
224 if( mxRenderable.is() && xPrinter )
226 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
229 nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions );
231 catch (lang::DisposedException &)
233 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing");
234 const_cast<SfxPrinterController*>(this)->setJobState(
235 view::PrintableState_JOB_ABORTED);
238 return nPages;
241 Sequence< beans::PropertyValue > SfxPrinterController::getPageParameters( int i_nPage ) const
243 VclPtr<Printer> xPrinter( getPrinter() );
244 Sequence< beans::PropertyValue > aResult;
246 if (mxRenderable.is() && xPrinter)
248 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
251 aResult = mxRenderable->getRenderer( i_nPage, getSelectionObject(), aJobOptions );
253 catch( lang::IllegalArgumentException& )
256 catch (lang::DisposedException &)
258 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing");
259 const_cast<SfxPrinterController*>(this)->setJobState(
260 view::PrintableState_JOB_ABORTED);
263 return aResult;
266 void SfxPrinterController::printPage( int i_nPage ) const
268 VclPtr<Printer> xPrinter( getPrinter() );
269 if( !mxRenderable.is() || !xPrinter )
270 return;
272 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
275 mxRenderable->render( i_nPage, getSelectionObject(), aJobOptions );
277 catch( lang::IllegalArgumentException& )
279 // don't care enough about nonexistent page here
280 // to provoke a crash
282 catch (lang::DisposedException &)
284 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing");
285 const_cast<SfxPrinterController*>(this)->setJobState(
286 view::PrintableState_JOB_ABORTED);
290 void SfxPrinterController::jobStarted()
292 if ( !mpObjectShell )
293 return;
295 m_bOrigStatus = mpObjectShell->IsEnableSetModified();
297 // check configuration: shall update of printing information in DocInfo set the document to "modified"?
298 if (m_bOrigStatus && !officecfg::Office::Common::Print::PrintingModifiesDocument::get())
300 mpObjectShell->EnableSetModified( false );
301 m_bNeedsChange = true;
304 // refresh document info
305 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
306 m_aLastPrintedBy = xDocProps->getPrintedBy();
307 m_aLastPrinted = xDocProps->getPrintDate();
309 xDocProps->setPrintedBy( mpObjectShell->IsUseUserData()
310 ? SvtUserOptions().GetFullName()
311 : OUString() );
312 ::DateTime now( ::DateTime::SYSTEM );
314 xDocProps->setPrintDate( now.GetUNODateTime() );
316 SfxGetpApp()->NotifyEvent( SfxEventHint(SfxEventHintId::PrintDoc, GlobalEventConfig::GetEventName( GlobalEventId::PRINTDOC ), mpObjectShell ) );
317 uno::Sequence < beans::PropertyValue > aOpts;
318 aOpts = getJobProperties( aOpts );
320 uno::Reference< frame::XController2 > xController;
321 if ( mpViewShell )
322 xController.set( mpViewShell->GetController(), uno::UNO_QUERY );
324 mpObjectShell->Broadcast( SfxPrintingHint(
325 view::PrintableState_JOB_STARTED, aOpts, mpObjectShell, xController ) );
328 void SfxPrinterController::jobFinished( css::view::PrintableState nState )
330 if ( !mpObjectShell )
331 return;
333 bool bCopyJobSetup = false;
334 mpObjectShell->Broadcast( SfxPrintingHint( nState ) );
335 switch ( nState )
337 case view::PrintableState_JOB_SPOOLING_FAILED :
338 case view::PrintableState_JOB_FAILED :
340 // "real" problem (not simply printing cancelled by user)
341 OUString aMsg( SfxResId(STR_NOSTARTPRINTER) );
342 if ( !m_bApi )
344 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(mpViewShell->GetFrameWeld(),
345 VclMessageType::Warning, VclButtonsType::Ok,
346 aMsg));
347 xBox->run();
349 [[fallthrough]];
351 case view::PrintableState_JOB_ABORTED :
353 // printing not successful, reset DocInfo
354 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
355 xDocProps->setPrintedBy(m_aLastPrintedBy);
356 xDocProps->setPrintDate(m_aLastPrinted);
357 break;
360 case view::PrintableState_JOB_SPOOLED :
361 case view::PrintableState_JOB_COMPLETED :
363 SfxBindings& rBind = mpViewShell->GetViewFrame()->GetBindings();
364 rBind.Invalidate( SID_PRINTDOC );
365 rBind.Invalidate( SID_PRINTDOCDIRECT );
366 rBind.Invalidate( SID_SETUPPRINTER );
367 bCopyJobSetup = ! m_bTempPrinter;
368 break;
371 default:
372 break;
375 if( bCopyJobSetup && mpViewShell )
377 // #i114306#
378 // Note: this possibly creates a printer that gets immediately replaced
379 // by a new one. The reason for this is that otherwise we would not get
380 // the printer's SfxItemSet here to copy. Awkward, but at the moment there is no
381 // other way here to get the item set.
382 SfxPrinter* pDocPrt = mpViewShell->GetPrinter(true);
383 if( pDocPrt )
385 if( pDocPrt->GetName() == getPrinter()->GetName() )
386 pDocPrt->SetJobSetup( getPrinter()->GetJobSetup() );
387 else
389 VclPtr<SfxPrinter> pNewPrt = VclPtr<SfxPrinter>::Create( pDocPrt->GetOptions().Clone(), getPrinter()->GetName() );
390 pNewPrt->SetJobSetup( getPrinter()->GetJobSetup() );
391 mpViewShell->SetPrinter( pNewPrt, SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP );
396 if ( m_bNeedsChange )
397 mpObjectShell->EnableSetModified( m_bOrigStatus );
399 if ( mpViewShell )
401 mpViewShell->pImpl->m_xPrinterController.reset();
405 namespace {
408 An instance of this class is created for the life span of the
409 printer dialogue, to create in its click handler for the additions by the
410 virtual method of the derived SfxViewShell generated print options dialogue
411 and to cache the options set there as SfxItemSet.
413 class SfxDialogExecutor_Impl
415 private:
416 SfxViewShell* _pViewSh;
417 PrinterSetupDialog& _rSetupParent;
418 std::unique_ptr<SfxItemSet> _pOptions;
419 bool _bHelpDisabled;
421 DECL_LINK( Execute, weld::Button&, void );
423 public:
424 SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent );
426 Link<weld::Button&, void> GetLink() const { return LINK(const_cast<SfxDialogExecutor_Impl*>(this), SfxDialogExecutor_Impl, Execute); }
427 const SfxItemSet* GetOptions() const { return _pOptions.get(); }
428 void DisableHelp() { _bHelpDisabled = true; }
433 SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent ) :
435 _pViewSh ( pViewSh ),
436 _rSetupParent ( rParent ),
437 _bHelpDisabled ( false )
442 IMPL_LINK_NOARG(SfxDialogExecutor_Impl, Execute, weld::Button&, void)
444 // Options noted locally
445 if ( !_pOptions )
447 _pOptions = static_cast<SfxPrinter*>( _rSetupParent.GetPrinter() )->GetOptions().Clone();
450 assert(_pOptions);
451 if (!_pOptions)
452 return;
454 // Create Dialog
455 SfxPrintOptionsDialog aDlg(_rSetupParent.GetFrameWeld(), _pViewSh, _pOptions.get() );
456 if (_bHelpDisabled)
457 aDlg.DisableHelp();
458 if (aDlg.run() == RET_OK)
460 _pOptions = aDlg.GetOptions().Clone();
465 Internal method for setting the differences between 'pNewPrinter' to the
466 current printer. pNewPrinter is either taken over or deleted.
468 void SfxViewShell::SetPrinter_Impl( VclPtr<SfxPrinter>& pNewPrinter )
470 // get current Printer
471 SfxPrinter *pDocPrinter = GetPrinter();
473 // Evaluate Printer Options
474 sal_uInt16 nWhich = GetPool().GetWhich(SID_PRINTER_CHANGESTODOC);
475 const SfxFlagItem *pFlagItem = nullptr;
476 pDocPrinter->GetOptions().GetItemState( nWhich, false, reinterpret_cast<const SfxPoolItem**>(&pFlagItem) );
477 bool bOriToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION);
478 bool bSizeToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE);
480 // Determine the previous format and size
481 Orientation eOldOri = pDocPrinter->GetOrientation();
482 Size aOldPgSz = pDocPrinter->GetPaperSizePixel();
484 // Determine the new format and size
485 Orientation eNewOri = pNewPrinter->GetOrientation();
486 Size aNewPgSz = pNewPrinter->GetPaperSizePixel();
488 // Determine the changes in page format
489 bool bOriChg = (eOldOri != eNewOri) && bOriToDoc;
490 bool bPgSzChg = ( aOldPgSz.Height() !=
491 ( bOriChg ? aNewPgSz.Width() : aNewPgSz.Height() ) ||
492 aOldPgSz.Width() !=
493 ( bOriChg ? aNewPgSz.Height() : aNewPgSz.Width() ) ) &&
494 bSizeToDoc;
496 // Message and Flags for page format changes
497 OUString aMsg;
498 SfxPrinterChangeFlags nNewOpt = SfxPrinterChangeFlags::NONE;
499 if( bOriChg && bPgSzChg )
501 aMsg = SfxResId(STR_PRINT_NEWORISIZE);
502 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION | SfxPrinterChangeFlags::CHG_SIZE;
504 else if (bOriChg )
506 aMsg = SfxResId(STR_PRINT_NEWORI);
507 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION;
509 else if (bPgSzChg)
511 aMsg = SfxResId(STR_PRINT_NEWSIZE);
512 nNewOpt = SfxPrinterChangeFlags::CHG_SIZE;
515 // Summarize in this variable what has been changed.
516 SfxPrinterChangeFlags nChangedFlags = SfxPrinterChangeFlags::NONE;
518 // Ask if possible, if page format should be taken over from printer.
519 if (bOriChg || bPgSzChg)
521 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
522 VclMessageType::Question, VclButtonsType::YesNo,
523 aMsg));
524 if (RET_YES == xBox->run())
526 // Flags with changes for <SetPrinter(SfxPrinter*)> are maintained
527 nChangedFlags |= nNewOpt;
531 // Was the printer selection changed from Default to Specific
532 // or the other way around?
533 if ( (pNewPrinter->GetName() != pDocPrinter->GetName())
534 || (pDocPrinter->IsDefPrinter() != pNewPrinter->IsDefPrinter()) )
536 nChangedFlags |= SfxPrinterChangeFlags::PRINTER|SfxPrinterChangeFlags::JOBSETUP;
537 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
539 nChangedFlags |= SfxPrinterChangeFlags::OPTIONS;
542 pDocPrinter = pNewPrinter;
544 else
546 // Compare extra options
547 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
549 // Option have changed
550 pDocPrinter->SetOptions( pNewPrinter->GetOptions() );
551 nChangedFlags |= SfxPrinterChangeFlags::OPTIONS;
554 // Compare JobSetups
555 JobSetup aNewJobSetup = pNewPrinter->GetJobSetup();
556 JobSetup aOldJobSetup = pDocPrinter->GetJobSetup();
557 if ( aNewJobSetup != aOldJobSetup )
559 nChangedFlags |= SfxPrinterChangeFlags::JOBSETUP;
562 // Keep old changed Printer.
563 pDocPrinter->SetPrinterProps( pNewPrinter );
564 pNewPrinter.disposeAndClear();
567 if ( SfxPrinterChangeFlags::NONE != nChangedFlags )
568 // SetPrinter will delete the old printer if it changes
569 SetPrinter( pDocPrinter, nChangedFlags );
572 void SfxViewShell::StartPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
574 assert( !pImpl->m_xPrinterController );
576 // get the current selection; our controller should know it
577 Reference< frame::XController > xController( GetController() );
578 Reference< view::XSelectionSupplier > xSupplier( xController, UNO_QUERY );
580 Any aSelection;
581 if( xSupplier.is() )
582 aSelection = xSupplier->getSelection();
583 else
584 aSelection <<= GetObjectShell()->GetModel();
585 Any aComplete( makeAny( GetObjectShell()->GetModel() ) );
586 Any aViewProp( makeAny( xController ) );
587 VclPtr<Printer> aPrt;
589 const beans::PropertyValue* pVal = std::find_if(rProps.begin(), rProps.end(),
590 [](const beans::PropertyValue& rVal) { return rVal.Name == "PrinterName"; });
591 if (pVal != rProps.end())
593 OUString aPrinterName;
594 pVal->Value >>= aPrinterName;
595 aPrt.reset( VclPtr<Printer>::Create( aPrinterName ) );
598 std::shared_ptr<vcl::PrinterController> xNewController(std::make_shared<SfxPrinterController>(
599 aPrt,
600 aComplete,
601 aSelection,
602 aViewProp,
603 GetRenderable(),
604 bIsAPI,
605 bIsDirect,
606 this,
607 rProps
609 pImpl->m_xPrinterController = xNewController;
611 SfxObjectShell *pObjShell = GetObjectShell();
612 xNewController->setValue( "JobName",
613 makeAny( pObjShell->GetTitle(1) ) );
614 xNewController->setPrinterModified( mbPrinterSettingsModified );
617 void SfxViewShell::ExecPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
619 StartPrint( rProps, bIsAPI, bIsDirect );
620 // FIXME: job setup
621 SfxPrinter* pDocPrt = GetPrinter();
622 JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : JobSetup();
623 Printer::PrintJob( GetPrinterController(), aJobSetup );
626 const std::shared_ptr< vcl::PrinterController >& SfxViewShell::GetPrinterController() const
628 return pImpl->m_xPrinterController;
631 Printer* SfxViewShell::GetActivePrinter() const
633 return pImpl->m_xPrinterController
634 ? pImpl->m_xPrinterController->getPrinter().get() : nullptr;
637 void SfxViewShell::ExecPrint_Impl( SfxRequest &rReq )
639 sal_uInt16 nDialogRet = RET_CANCEL;
640 VclPtr<SfxPrinter> pPrinter;
641 bool bSilent = false;
643 // does the function have been called by the user interface or by an API call
644 bool bIsAPI = rReq.GetArgs() && rReq.GetArgs()->Count();
645 if ( bIsAPI )
647 // the function have been called by the API
649 // Should it be visible on the user interface,
650 // should it launch popup dialogue ?
651 const SfxBoolItem* pSilentItem = rReq.GetArg<SfxBoolItem>(SID_SILENT);
652 bSilent = pSilentItem && pSilentItem->GetValue();
655 // no help button in dialogs if called from the help window
656 // (pressing help button would exchange the current page inside the help
657 // document that is going to be printed!)
658 SfxMedium* pMedium = GetViewFrame()->GetObjectShell()->GetMedium();
659 std::shared_ptr<const SfxFilter> pFilter = pMedium ? pMedium->GetFilter() : nullptr;
660 bool bPrintOnHelp = ( pFilter && pFilter->GetFilterName() == "writer_web_HTML_help" );
662 const sal_uInt16 nId = rReq.GetSlot();
663 switch( nId )
665 case SID_PRINTDOC: // display the printer selection and properties dialogue : File > Print...
666 case SID_PRINTDOCDIRECT: // Print the document directly, without displaying the dialogue
668 SfxObjectShell* pDoc = GetObjectShell();
670 // derived class may decide to abort this
671 if( pDoc == nullptr || !pDoc->QuerySlotExecutable( nId ) )
673 rReq.SetReturnValue( SfxBoolItem( 0, false ) );
674 return;
677 if ( !bSilent && pDoc->QueryHiddenInformation( HiddenWarningFact::WhenPrinting, nullptr ) != RET_YES )
678 return;
680 // should we print only the selection or the whole document
681 const SfxBoolItem* pSelectItem = rReq.GetArg<SfxBoolItem>(SID_SELECTION);
682 bool bSelection = ( pSelectItem != nullptr && pSelectItem->GetValue() );
683 // detect non api call from writer ( that adds SID_SELECTION ) and reset bIsAPI
684 if ( pSelectItem && rReq.GetArgs()->Count() == 1 )
685 bIsAPI = false;
687 uno::Sequence < beans::PropertyValue > aProps;
688 if ( bIsAPI )
690 // supported properties:
691 // String PrinterName
692 // String FileName
693 // Int16 From
694 // Int16 To
695 // In16 Copies
696 // String RangeText
697 // bool Selection
698 // bool Asynchron
699 // bool Collate
700 // bool Silent
702 // the TransformItems function overwrite aProps
703 TransformItems( nId, *rReq.GetArgs(), aProps, GetInterface()->GetSlot(nId) );
705 for ( auto& rProp : aProps )
707 if ( rProp.Name == "Copies" )
709 rProp.Name = "CopyCount";
711 else if ( rProp.Name == "RangeText" )
713 rProp.Name = "Pages";
715 else if ( rProp.Name == "Asynchron" )
717 rProp.Name = "Wait";
718 bool bAsynchron = false;
719 rProp.Value >>= bAsynchron;
720 rProp.Value <<= !bAsynchron;
722 else if ( rProp.Name == "Silent" )
724 rProp.Name = "MonitorVisible";
725 bool bPrintSilent = false;
726 rProp.Value >>= bPrintSilent;
727 rProp.Value <<= !bPrintSilent;
732 // we will add the "PrintSelectionOnly" or "HideHelpButton" properties
733 // we have to increase the capacity of aProps
734 sal_Int32 nLen = aProps.getLength();
735 aProps.realloc( nLen + 1 );
737 // HACK: writer sets the SID_SELECTION item when printing directly and expects
738 // to get only the selection document in that case (see getSelectionObject)
739 // however it also reacts to the PrintContent property. We need this distinction here, too,
740 // else one of the combinations print / print direct and selection / all will not work.
741 // it would be better if writer handled this internally
742 if( nId == SID_PRINTDOCDIRECT )
744 aProps[nLen].Name = "PrintSelectionOnly";
745 aProps[nLen].Value <<= bSelection;
747 else // if nId == SID_PRINTDOC ; nothing to do with the previous HACK
749 // should the printer selection and properties dialogue display an help button
750 aProps[nLen].Name = "HideHelpButton";
751 aProps[nLen].Value <<= bPrintOnHelp;
754 ExecPrint( aProps, bIsAPI, (nId == SID_PRINTDOCDIRECT) );
756 // FIXME: Recording
757 rReq.Done();
758 break;
761 case SID_SETUPPRINTER : // display the printer settings dialogue : File > Printer Settings...
762 case SID_PRINTER_NAME : // only for recorded macros
764 // get printer and printer settings from the document
765 SfxPrinter *pDocPrinter = GetPrinter(true);
767 // look for printer in parameters
768 const SfxStringItem* pPrinterItem = rReq.GetArg<SfxStringItem>(SID_PRINTER_NAME);
769 if ( pPrinterItem )
771 // use PrinterName parameter to create a printer
772 pPrinter = VclPtr<SfxPrinter>::Create( pDocPrinter->GetOptions().Clone(), pPrinterItem->GetValue() );
774 // if printer is unknown, it can't be used - now printer from document will be used
775 if ( !pPrinter->IsKnown() )
776 pPrinter.disposeAndClear();
779 if ( SID_PRINTER_NAME == nId )
781 // just set a recorded printer name
782 if ( pPrinter )
783 SetPrinter( pPrinter, SfxPrinterChangeFlags::PRINTER );
784 return;
787 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
788 if ( !pPrinter )
789 // use default printer from document
790 pPrinter = pDocPrinter;
792 if( !pPrinter || !pPrinter->IsValid() )
794 // no valid printer either in ItemSet or at the document
795 if ( !bSilent )
797 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
798 VclMessageType::Warning, VclButtonsType::Ok,
799 SfxResId(STR_NODEFPRINTER)));
800 xBox->run();
803 rReq.SetReturnValue(SfxBoolItem(0,false));
805 break;
808 // FIXME: printer isn't used for printing anymore!
809 if( pPrinter->IsPrinting() )
811 // if printer is busy, abort configuration
812 if ( !bSilent )
814 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
815 VclMessageType::Info, VclButtonsType::Ok,
816 SfxResId(STR_ERROR_PRINTER_BUSY)));
817 xBox->run();
819 rReq.SetReturnValue(SfxBoolItem(0,false));
821 return;
824 // Open Printer Setup dialog
825 if ( nId == SID_SETUPPRINTER )
827 // PrinterDialog needs a temporary printer
828 VclPtr<SfxPrinter> pDlgPrinter = pPrinter->Clone();
830 // execute PrinterSetupDialog
831 PrinterSetupDialog aPrintSetupDlg(GetFrameWeld());
832 std::unique_ptr<SfxDialogExecutor_Impl> pExecutor;
834 if (pImpl->m_bHasPrintOptions && HasPrintOptionsPage())
836 // additional controls for dialog
837 pExecutor.reset( new SfxDialogExecutor_Impl( this, aPrintSetupDlg ) );
838 if ( bPrintOnHelp )
839 pExecutor->DisableHelp();
840 aPrintSetupDlg.SetOptionsHdl( pExecutor->GetLink() );
843 aPrintSetupDlg.SetPrinter( pDlgPrinter );
844 nDialogRet = aPrintSetupDlg.run();
846 if ( pExecutor && pExecutor->GetOptions() )
848 if ( nDialogRet == RET_OK )
849 // remark: have to be recorded if possible!
850 pDlgPrinter->SetOptions( *pExecutor->GetOptions() );
851 else
853 pPrinter->SetOptions( *pExecutor->GetOptions() );
854 SetPrinter( pPrinter, SfxPrinterChangeFlags::OPTIONS );
858 // no recording of PrinterSetup except printer name (is printer dependent)
859 rReq.Ignore();
861 if ( nDialogRet == RET_OK )
863 if ( pPrinter->GetName() != pDlgPrinter->GetName() )
865 // user has changed the printer -> macro recording
866 SfxRequest aReq( GetViewFrame(), SID_PRINTER_NAME );
867 aReq.AppendItem( SfxStringItem( SID_PRINTER_NAME, pDlgPrinter->GetName() ) );
868 aReq.Done();
871 // take the changes made in the dialog
872 SetPrinter_Impl( pDlgPrinter );
874 // forget new printer, it was taken over (as pPrinter) or deleted
875 pDlgPrinter = nullptr;
876 mbPrinterSettingsModified = true;
878 else
880 // PrinterDialog is used to transfer information on printing,
881 // so it will only be deleted here if dialog was cancelled
882 pDlgPrinter.disposeAndClear();
883 rReq.Ignore();
890 SfxPrinter* SfxViewShell::GetPrinter( bool /*bCreate*/ )
892 return nullptr;
895 sal_uInt16 SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, SfxPrinterChangeFlags /*nDiffFlags*/ )
897 return 0;
900 std::unique_ptr<SfxTabPage> SfxViewShell::CreatePrintOptionsPage(weld::Container*, weld::DialogController*, const SfxItemSet&)
902 return nullptr;
905 bool SfxViewShell::HasPrintOptionsPage() const
907 return false;
910 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */