tdf#42949 Fix IWYU warnings in sfx2/source/[s-v]*/*cxx and sfx2/qa
[LibreOffice.git] / sfx2 / source / view / viewprn.cxx
blob339766ef53ab1512913540eff29dc7177b244817
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>
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 <unotools/printwarningoptions.hxx>
37 #include <tools/datetime.hxx>
38 #include <sfx2/bindings.hxx>
39 #include <sfx2/objface.hxx>
40 #include <sfx2/viewsh.hxx>
41 #include "viewimp.hxx"
42 #include <sfx2/viewfrm.hxx>
43 #include <sfx2/printer.hxx>
44 #include <sfx2/prnmon.hxx>
45 #include <sfx2/sfxresid.hxx>
46 #include <sfx2/request.hxx>
47 #include <sfx2/objsh.hxx>
48 #include <sfx2/event.hxx>
49 #include <sfx2/docfile.hxx>
50 #include <sfx2/docfilt.hxx>
51 #include <sfx2/sfxsids.hrc>
52 #include <sfx2/strings.hrc>
53 #include <sfx2/sfxuno.hxx>
54 #include <sfx2/tabdlg.hxx>
56 #include <toolkit/awt/vclxdevice.hxx>
58 using namespace com::sun::star;
59 using namespace com::sun::star::uno;
61 class SfxPrinterController : public vcl::PrinterController, public SfxListener
63 Any const maCompleteSelection;
64 Any const 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 const m_bApi;
73 bool const 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.get() != nullptr )
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 mpViewShell = nullptr;
178 mpObjectShell = nullptr;
182 const Any& SfxPrinterController::getSelectionObject() const
184 const beans::PropertyValue* pVal = getValue( OUString( "PrintSelectionOnly" ) );
185 if( pVal )
187 bool bSel = false;
188 pVal->Value >>= bSel;
189 return bSel ? maSelection : maCompleteSelection;
192 bool bIsCalc = false;
193 pVal = getValue( OUString( "PrintRange" ) );
194 if ( pVal )
195 bIsCalc = true;
197 sal_Int32 nChoice = 0;
198 pVal = getValue( OUString( "PrintContent" ) );
199 if( pVal )
200 pVal->Value >>= nChoice;
202 if ( bIsCalc )
203 return (nChoice > 1) ? maSelection : maCompleteSelection;
204 else
205 return (nChoice > 3) ? maSelection : maCompleteSelection;
208 Sequence< beans::PropertyValue > SfxPrinterController::getMergedOptions() const
210 VclPtr<Printer> xPrinter( getPrinter() );
211 if( xPrinter.get() != mpLastPrinter )
213 mpLastPrinter = xPrinter.get();
214 VCLXDevice* pXDevice = new VCLXDevice();
215 pXDevice->SetOutputDevice( mpLastPrinter );
216 mxDevice.set( pXDevice );
219 Sequence< beans::PropertyValue > aRenderOptions( 1 );
220 aRenderOptions[ 0 ].Name = "RenderDevice";
221 aRenderOptions[ 0 ].Value <<= mxDevice;
223 aRenderOptions = getJobProperties( aRenderOptions );
224 return aRenderOptions;
227 int SfxPrinterController::getPageCount() const
229 int nPages = 0;
230 VclPtr<Printer> xPrinter( getPrinter() );
231 if( mxRenderable.is() && xPrinter )
233 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
236 nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions );
238 catch (lang::DisposedException &)
240 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing");
241 const_cast<SfxPrinterController*>(this)->setJobState(
242 view::PrintableState_JOB_ABORTED);
245 return nPages;
248 Sequence< beans::PropertyValue > SfxPrinterController::getPageParameters( int i_nPage ) const
250 VclPtr<Printer> xPrinter( getPrinter() );
251 Sequence< beans::PropertyValue > aResult;
253 if (mxRenderable.is() && xPrinter)
255 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
258 aResult = mxRenderable->getRenderer( i_nPage, getSelectionObject(), aJobOptions );
260 catch( lang::IllegalArgumentException& )
263 catch (lang::DisposedException &)
265 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing");
266 const_cast<SfxPrinterController*>(this)->setJobState(
267 view::PrintableState_JOB_ABORTED);
270 return aResult;
273 void SfxPrinterController::printPage( int i_nPage ) const
275 VclPtr<Printer> xPrinter( getPrinter() );
276 if( !mxRenderable.is() || !xPrinter )
277 return;
279 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
282 mxRenderable->render( i_nPage, getSelectionObject(), aJobOptions );
284 catch( lang::IllegalArgumentException& )
286 // don't care enough about nonexistent page here
287 // to provoke a crash
289 catch (lang::DisposedException &)
291 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing");
292 const_cast<SfxPrinterController*>(this)->setJobState(
293 view::PrintableState_JOB_ABORTED);
297 void SfxPrinterController::jobStarted()
299 if ( !mpObjectShell )
300 return;
302 m_bOrigStatus = mpObjectShell->IsEnableSetModified();
304 // check configuration: shall update of printing information in DocInfo set the document to "modified"?
305 if ( m_bOrigStatus && !SvtPrintWarningOptions().IsModifyDocumentOnPrintingAllowed() )
307 mpObjectShell->EnableSetModified( false );
308 m_bNeedsChange = true;
311 // refresh document info
312 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
313 m_aLastPrintedBy = xDocProps->getPrintedBy();
314 m_aLastPrinted = xDocProps->getPrintDate();
316 xDocProps->setPrintedBy( mpObjectShell->IsUseUserData()
317 ? SvtUserOptions().GetFullName()
318 : OUString() );
319 ::DateTime now( ::DateTime::SYSTEM );
321 xDocProps->setPrintDate( now.GetUNODateTime() );
323 SfxGetpApp()->NotifyEvent( SfxEventHint(SfxEventHintId::PrintDoc, GlobalEventConfig::GetEventName( GlobalEventId::PRINTDOC ), mpObjectShell ) );
324 uno::Sequence < beans::PropertyValue > aOpts;
325 aOpts = getJobProperties( aOpts );
327 uno::Reference< frame::XController2 > xController;
328 if ( mpViewShell )
329 xController.set( mpViewShell->GetController(), uno::UNO_QUERY );
331 mpObjectShell->Broadcast( SfxPrintingHint(
332 view::PrintableState_JOB_STARTED, aOpts, mpObjectShell, xController ) );
335 void SfxPrinterController::jobFinished( css::view::PrintableState nState )
337 if ( !mpObjectShell )
338 return;
340 bool bCopyJobSetup = false;
341 mpObjectShell->Broadcast( SfxPrintingHint( nState ) );
342 switch ( nState )
344 case view::PrintableState_JOB_SPOOLING_FAILED :
345 case view::PrintableState_JOB_FAILED :
347 // "real" problem (not simply printing cancelled by user)
348 OUString aMsg( SfxResId(STR_NOSTARTPRINTER) );
349 if ( !m_bApi )
351 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(mpViewShell->GetFrameWeld(),
352 VclMessageType::Warning, VclButtonsType::Ok,
353 aMsg));
354 xBox->run();
356 [[fallthrough]];
358 case view::PrintableState_JOB_ABORTED :
360 // printing not successful, reset DocInfo
361 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
362 xDocProps->setPrintedBy(m_aLastPrintedBy);
363 xDocProps->setPrintDate(m_aLastPrinted);
364 break;
367 case view::PrintableState_JOB_SPOOLED :
368 case view::PrintableState_JOB_COMPLETED :
370 SfxBindings& rBind = mpViewShell->GetViewFrame()->GetBindings();
371 rBind.Invalidate( SID_PRINTDOC );
372 rBind.Invalidate( SID_PRINTDOCDIRECT );
373 rBind.Invalidate( SID_SETUPPRINTER );
374 bCopyJobSetup = ! m_bTempPrinter;
375 break;
378 default:
379 break;
382 if( bCopyJobSetup && mpViewShell )
384 // #i114306#
385 // Note: this possibly creates a printer that gets immediately replaced
386 // by a new one. The reason for this is that otherwise we would not get
387 // the printer's SfxItemSet here to copy. Awkward, but at the moment there is no
388 // other way here to get the item set.
389 SfxPrinter* pDocPrt = mpViewShell->GetPrinter(true);
390 if( pDocPrt )
392 if( pDocPrt->GetName() == getPrinter()->GetName() )
393 pDocPrt->SetJobSetup( getPrinter()->GetJobSetup() );
394 else
396 VclPtr<SfxPrinter> pNewPrt = VclPtr<SfxPrinter>::Create( pDocPrt->GetOptions().Clone(), getPrinter()->GetName() );
397 pNewPrt->SetJobSetup( getPrinter()->GetJobSetup() );
398 mpViewShell->SetPrinter( pNewPrt, SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP );
403 if ( m_bNeedsChange )
404 mpObjectShell->EnableSetModified( m_bOrigStatus );
406 if ( mpViewShell )
408 mpViewShell->pImpl->m_xPrinterController.reset();
412 namespace {
415 An instance of this class is created for the life span of the
416 printer dialogue, to create in its click handler for the additions by the
417 virtual method of the derived SfxViewShell generated print options dialogue
418 and to cache the options set there as SfxItemSet.
420 class SfxDialogExecutor_Impl
422 private:
423 SfxViewShell* const _pViewSh;
424 PrinterSetupDialog& _rSetupParent;
425 std::unique_ptr<SfxItemSet> _pOptions;
426 bool _bHelpDisabled;
428 DECL_LINK( Execute, weld::Button&, void );
430 public:
431 SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent );
433 Link<weld::Button&, void> GetLink() const { return LINK(const_cast<SfxDialogExecutor_Impl*>(this), SfxDialogExecutor_Impl, Execute); }
434 const SfxItemSet* GetOptions() const { return _pOptions.get(); }
435 void DisableHelp() { _bHelpDisabled = true; }
440 SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent ) :
442 _pViewSh ( pViewSh ),
443 _rSetupParent ( rParent ),
444 _bHelpDisabled ( false )
449 IMPL_LINK_NOARG(SfxDialogExecutor_Impl, Execute, weld::Button&, void)
451 // Options noted locally
452 if ( !_pOptions )
454 _pOptions = static_cast<SfxPrinter*>( _rSetupParent.GetPrinter() )->GetOptions().Clone();
457 assert(_pOptions);
458 if (!_pOptions)
459 return;
461 // Create Dialog
462 SfxPrintOptionsDialog aDlg(_rSetupParent.GetFrameWeld(), _pViewSh, _pOptions.get() );
463 if (_bHelpDisabled)
464 aDlg.DisableHelp();
465 if (aDlg.run() == RET_OK)
467 _pOptions = aDlg.GetOptions().Clone();
472 Internal method for setting the differences between 'pNewPrinter' to the
473 current printer. pNewPrinter is either taken over or deleted.
475 void SfxViewShell::SetPrinter_Impl( VclPtr<SfxPrinter>& pNewPrinter )
477 // get current Printer
478 SfxPrinter *pDocPrinter = GetPrinter();
480 // Evaluate Printer Options
481 sal_uInt16 nWhich = GetPool().GetWhich(SID_PRINTER_CHANGESTODOC);
482 const SfxFlagItem *pFlagItem = nullptr;
483 pDocPrinter->GetOptions().GetItemState( nWhich, false, reinterpret_cast<const SfxPoolItem**>(&pFlagItem) );
484 bool bOriToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION);
485 bool bSizeToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE);
487 // Determine the previous format and size
488 Orientation eOldOri = pDocPrinter->GetOrientation();
489 Size aOldPgSz = pDocPrinter->GetPaperSizePixel();
491 // Determine the new format and size
492 Orientation eNewOri = pNewPrinter->GetOrientation();
493 Size aNewPgSz = pNewPrinter->GetPaperSizePixel();
495 // Determine the changes in page format
496 bool bOriChg = (eOldOri != eNewOri) && bOriToDoc;
497 bool bPgSzChg = ( aOldPgSz.Height() !=
498 ( bOriChg ? aNewPgSz.Width() : aNewPgSz.Height() ) ||
499 aOldPgSz.Width() !=
500 ( bOriChg ? aNewPgSz.Height() : aNewPgSz.Width() ) ) &&
501 bSizeToDoc;
503 // Message and Flags for page format, summaries changes
504 OUString aMsg;
505 SfxPrinterChangeFlags nNewOpt = SfxPrinterChangeFlags::NONE;
506 if( bOriChg && bPgSzChg )
508 aMsg = SfxResId(STR_PRINT_NEWORISIZE);
509 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION | SfxPrinterChangeFlags::CHG_SIZE;
511 else if (bOriChg )
513 aMsg = SfxResId(STR_PRINT_NEWORI);
514 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION;
516 else if (bPgSzChg)
518 aMsg = SfxResId(STR_PRINT_NEWSIZE);
519 nNewOpt = SfxPrinterChangeFlags::CHG_SIZE;
522 // Summaries in this variable what has been changed.
523 SfxPrinterChangeFlags nChangedFlags = SfxPrinterChangeFlags::NONE;
525 // Ask if possible, if page format should be taken over from printer.
526 if (bOriChg || bPgSzChg)
528 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
529 VclMessageType::Question, VclButtonsType::YesNo,
530 aMsg));
531 if (RET_YES == xBox->run())
533 // Flags with changes for <SetPrinter(SfxPrinter*)> are maintained
534 nChangedFlags |= nNewOpt;
538 // For the MAC to have its "temporary of class String" in next if()
539 OUString aTempPrtName = pNewPrinter->GetName();
540 OUString aDocPrtName = pDocPrinter->GetName();
542 // Was the printer selection changed from Default to Specific
543 // or the other way around?
544 if ( (aTempPrtName != aDocPrtName) || (pDocPrinter->IsDefPrinter() != pNewPrinter->IsDefPrinter()) )
546 nChangedFlags |= SfxPrinterChangeFlags::PRINTER|SfxPrinterChangeFlags::JOBSETUP;
547 pDocPrinter = pNewPrinter;
549 else
551 // Compare extra options
552 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
554 // Option have changed
555 pDocPrinter->SetOptions( pNewPrinter->GetOptions() );
556 nChangedFlags |= SfxPrinterChangeFlags::OPTIONS;
559 // Compare JobSetups
560 JobSetup aNewJobSetup = pNewPrinter->GetJobSetup();
561 JobSetup aOldJobSetup = pDocPrinter->GetJobSetup();
562 if ( aNewJobSetup != aOldJobSetup )
564 nChangedFlags |= SfxPrinterChangeFlags::JOBSETUP;
567 // Keep old changed Printer.
568 pDocPrinter->SetPrinterProps( pNewPrinter );
569 pNewPrinter.disposeAndClear();
572 if ( SfxPrinterChangeFlags::NONE != nChangedFlags )
573 // SetPrinter will delete the old printer if it changes
574 SetPrinter( pDocPrinter, nChangedFlags );
577 void SfxViewShell::StartPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
579 assert( pImpl->m_xPrinterController.get() == nullptr );
581 // get the current selection; our controller should know it
582 Reference< frame::XController > xController( GetController() );
583 Reference< view::XSelectionSupplier > xSupplier( xController, UNO_QUERY );
585 Any aSelection;
586 if( xSupplier.is() )
587 aSelection = xSupplier->getSelection();
588 else
589 aSelection <<= GetObjectShell()->GetModel();
590 Any aComplete( makeAny( GetObjectShell()->GetModel() ) );
591 Any aViewProp( makeAny( xController ) );
592 VclPtr<Printer> aPrt;
594 const beans::PropertyValue* pVal = std::find_if(rProps.begin(), rProps.end(),
595 [](const beans::PropertyValue& rVal) { return rVal.Name == "PrinterName"; });
596 if (pVal != rProps.end())
598 OUString aPrinterName;
599 pVal->Value >>= aPrinterName;
600 aPrt.reset( VclPtr<Printer>::Create( aPrinterName ) );
603 std::shared_ptr<vcl::PrinterController> xNewController(std::make_shared<SfxPrinterController>(
604 aPrt,
605 aComplete,
606 aSelection,
607 aViewProp,
608 GetRenderable(),
609 bIsAPI,
610 bIsDirect,
611 this,
612 rProps
614 pImpl->m_xPrinterController = xNewController;
616 SfxObjectShell *pObjShell = GetObjectShell();
617 xNewController->setValue( "JobName",
618 makeAny( pObjShell->GetTitle(1) ) );
619 xNewController->setPrinterModified( mbPrinterSettingsModified );
622 void SfxViewShell::ExecPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
624 StartPrint( rProps, bIsAPI, bIsDirect );
625 // FIXME: job setup
626 SfxPrinter* pDocPrt = GetPrinter();
627 JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : JobSetup();
628 Printer::PrintJob( GetPrinterController(), aJobSetup );
631 const std::shared_ptr< vcl::PrinterController >& SfxViewShell::GetPrinterController() const
633 return pImpl->m_xPrinterController;
636 Printer* SfxViewShell::GetActivePrinter() const
638 return pImpl->m_xPrinterController
639 ? pImpl->m_xPrinterController->getPrinter().get() : nullptr;
642 void SfxViewShell::ExecPrint_Impl( SfxRequest &rReq )
644 sal_uInt16 nDialogRet = RET_CANCEL;
645 VclPtr<SfxPrinter> pPrinter;
646 bool bSilent = false;
648 // does the function have been called by the user interface or by an API call
649 bool bIsAPI = rReq.GetArgs() && rReq.GetArgs()->Count();
650 if ( bIsAPI )
652 // the function have been called by the API
654 // Should it be visible on the user interface,
655 // should it launch popup dialogue ?
656 const SfxBoolItem* pSilentItem = rReq.GetArg<SfxBoolItem>(SID_SILENT);
657 bSilent = pSilentItem && pSilentItem->GetValue();
660 // no help button in dialogs if called from the help window
661 // (pressing help button would exchange the current page inside the help
662 // document that is going to be printed!)
663 SfxMedium* pMedium = GetViewFrame()->GetObjectShell()->GetMedium();
664 std::shared_ptr<const SfxFilter> pFilter = pMedium ? pMedium->GetFilter() : nullptr;
665 bool bPrintOnHelp = ( pFilter && pFilter->GetFilterName() == "writer_web_HTML_help" );
667 const sal_uInt16 nId = rReq.GetSlot();
668 switch( nId )
670 case SID_PRINTDOC: // display the printer selection and properties dialogue : File > Print...
671 case SID_PRINTDOCDIRECT: // Print the document directly, without displaying the dialogue
673 SfxObjectShell* pDoc = GetObjectShell();
675 // derived class may decide to abort this
676 if( pDoc == nullptr || !pDoc->QuerySlotExecutable( nId ) )
678 rReq.SetReturnValue( SfxBoolItem( 0, false ) );
679 return;
682 if ( !bSilent && pDoc->QueryHiddenInformation( HiddenWarningFact::WhenPrinting, nullptr ) != RET_YES )
683 return;
685 // should we print only the selection or the whole document
686 const SfxBoolItem* pSelectItem = rReq.GetArg<SfxBoolItem>(SID_SELECTION);
687 bool bSelection = ( pSelectItem != nullptr && pSelectItem->GetValue() );
688 // detect non api call from writer ( that adds SID_SELECTION ) and reset bIsAPI
689 if ( pSelectItem && rReq.GetArgs()->Count() == 1 )
690 bIsAPI = false;
692 uno::Sequence < beans::PropertyValue > aProps;
693 if ( bIsAPI )
695 // supported properties:
696 // String PrinterName
697 // String FileName
698 // Int16 From
699 // Int16 To
700 // In16 Copies
701 // String RangeText
702 // bool Selection
703 // bool Asynchron
704 // bool Collate
705 // bool Silent
707 // the TransformItems function overwrite aProps
708 TransformItems( nId, *rReq.GetArgs(), aProps, GetInterface()->GetSlot(nId) );
710 for ( auto& rProp : aProps )
712 if ( rProp.Name == "Copies" )
714 rProp.Name = "CopyCount";
716 else if ( rProp.Name == "RangeText" )
718 rProp.Name = "Pages";
720 else if ( rProp.Name == "Asynchron" )
722 rProp.Name = "Wait";
723 bool bAsynchron = false;
724 rProp.Value >>= bAsynchron;
725 rProp.Value <<= !bAsynchron;
727 else if ( rProp.Name == "Silent" )
729 rProp.Name = "MonitorVisible";
730 bool bPrintSilent = false;
731 rProp.Value >>= bPrintSilent;
732 rProp.Value <<= !bPrintSilent;
737 // we will add the "PrintSelectionOnly" or "HideHelpButton" properties
738 // we have to increase the capacity of aProps
739 sal_Int32 nLen = aProps.getLength();
740 aProps.realloc( nLen + 1 );
742 // HACK: writer sets the SID_SELECTION item when printing directly and expects
743 // to get only the selection document in that case (see getSelectionObject)
744 // however it also reacts to the PrintContent property. We need this distinction here, too,
745 // else one of the combinations print / print direct and selection / all will not work.
746 // it would be better if writer handled this internally
747 if( nId == SID_PRINTDOCDIRECT )
749 aProps[nLen].Name = "PrintSelectionOnly";
750 aProps[nLen].Value <<= bSelection;
752 else // if nId == SID_PRINTDOC ; nothing to do with the previous HACK
754 // should the printer selection and properties dialogue display an help button
755 aProps[nLen].Name = "HideHelpButton";
756 aProps[nLen].Value <<= bPrintOnHelp;
759 ExecPrint( aProps, bIsAPI, (nId == SID_PRINTDOCDIRECT) );
761 // FIXME: Recording
762 rReq.Done();
763 break;
766 case SID_SETUPPRINTER : // display the printer settings dialogue : File > Printer Settings...
767 case SID_PRINTER_NAME : // only for recorded macros
769 // get printer and printer settings from the document
770 SfxPrinter *pDocPrinter = GetPrinter(true);
772 // look for printer in parameters
773 const SfxStringItem* pPrinterItem = rReq.GetArg<SfxStringItem>(SID_PRINTER_NAME);
774 if ( pPrinterItem )
776 // use PrinterName parameter to create a printer
777 pPrinter = VclPtr<SfxPrinter>::Create( pDocPrinter->GetOptions().Clone(), pPrinterItem->GetValue() );
779 // if printer is unknown, it can't be used - now printer from document will be used
780 if ( !pPrinter->IsKnown() )
781 pPrinter.disposeAndClear();
784 if ( SID_PRINTER_NAME == nId )
786 // just set a recorded printer name
787 if ( pPrinter )
788 SetPrinter( pPrinter, SfxPrinterChangeFlags::PRINTER );
789 return;
792 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
793 if ( !pPrinter )
794 // use default printer from document
795 pPrinter = pDocPrinter;
797 if( !pPrinter || !pPrinter->IsValid() )
799 // no valid printer either in ItemSet or at the document
800 if ( !bSilent )
802 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
803 VclMessageType::Warning, VclButtonsType::Ok,
804 SfxResId(STR_NODEFPRINTER)));
805 xBox->run();
808 rReq.SetReturnValue(SfxBoolItem(0,false));
810 break;
813 // FIXME: printer isn't used for printing anymore!
814 if( pPrinter->IsPrinting() )
816 // if printer is busy, abort configuration
817 if ( !bSilent )
819 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
820 VclMessageType::Info, VclButtonsType::Ok,
821 SfxResId(STR_ERROR_PRINTER_BUSY)));
822 xBox->run();
824 rReq.SetReturnValue(SfxBoolItem(0,false));
826 return;
829 // if no arguments are given, retrieve them from a dialog
830 if ( !bIsAPI )
832 // PrinterDialog needs a temporary printer
833 VclPtr<SfxPrinter> pDlgPrinter = pPrinter->Clone();
835 // execute PrinterSetupDialog
836 PrinterSetupDialog aPrintSetupDlg(GetFrameWeld());
837 std::unique_ptr<SfxDialogExecutor_Impl> pExecutor;
839 if (pImpl->m_bHasPrintOptions && HasPrintOptionsPage())
841 // additional controls for dialog
842 pExecutor.reset( new SfxDialogExecutor_Impl( this, aPrintSetupDlg ) );
843 if ( bPrintOnHelp )
844 pExecutor->DisableHelp();
845 aPrintSetupDlg.SetOptionsHdl( pExecutor->GetLink() );
848 aPrintSetupDlg.SetPrinter( pDlgPrinter );
849 nDialogRet = aPrintSetupDlg.run();
851 if ( pExecutor && pExecutor->GetOptions() )
853 if ( nDialogRet == RET_OK )
854 // remark: have to be recorded if possible!
855 pDlgPrinter->SetOptions( *pExecutor->GetOptions() );
856 else
858 pPrinter->SetOptions( *pExecutor->GetOptions() );
859 SetPrinter( pPrinter, SfxPrinterChangeFlags::OPTIONS );
863 // no recording of PrinterSetup except printer name (is printer dependent)
864 rReq.Ignore();
866 if ( nDialogRet == RET_OK )
868 if ( pPrinter->GetName() != pDlgPrinter->GetName() )
870 // user has changed the printer -> macro recording
871 SfxRequest aReq( GetViewFrame(), SID_PRINTER_NAME );
872 aReq.AppendItem( SfxStringItem( SID_PRINTER_NAME, pDlgPrinter->GetName() ) );
873 aReq.Done();
876 // take the changes made in the dialog
877 SetPrinter_Impl( pDlgPrinter );
879 // forget new printer, it was taken over (as pPrinter) or deleted
880 pDlgPrinter = nullptr;
881 mbPrinterSettingsModified = true;
883 else
885 // PrinterDialog is used to transfer information on printing,
886 // so it will only be deleted here if dialog was cancelled
887 pDlgPrinter.disposeAndClear();
888 rReq.Ignore();
895 SfxPrinter* SfxViewShell::GetPrinter( bool /*bCreate*/ )
897 return nullptr;
900 sal_uInt16 SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, SfxPrinterChangeFlags /*nDiffFlags*/ )
902 return 0;
905 std::unique_ptr<SfxTabPage> SfxViewShell::CreatePrintOptionsPage(weld::Container*, weld::DialogController*, const SfxItemSet&)
907 return nullptr;
910 bool SfxViewShell::HasPrintOptionsPage() const
912 return false;
915 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */