LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sfx2 / source / view / viewprn.cxx
blobf6cd8936ee841c5d238b61f419dced02c9c4e775
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 <comphelper/propertyvalue.hxx>
27 #include <officecfg/Office/Common.hxx>
28 #include <sal/log.hxx>
29 #include <svl/itempool.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/weld.hxx>
32 #include <svtools/prnsetup.hxx>
33 #include <svl/flagitem.hxx>
34 #include <svl/stritem.hxx>
35 #include <svl/eitem.hxx>
36 #include <sfx2/app.hxx>
37 #include <unotools/useroptions.hxx>
38 #include <tools/datetime.hxx>
39 #include <sfx2/bindings.hxx>
40 #include <sfx2/objface.hxx>
41 #include <sfx2/viewsh.hxx>
42 #include "viewimp.hxx"
43 #include <sfx2/viewfrm.hxx>
44 #include <sfx2/printer.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 #include "prnmon.hxx"
60 using namespace com::sun::star;
61 using namespace com::sun::star::uno;
63 class SfxPrinterController : public vcl::PrinterController, public SfxListener
65 Any maCompleteSelection;
66 Any maSelection;
67 Reference< view::XRenderable > mxRenderable;
68 mutable VclPtr<Printer> mpLastPrinter;
69 mutable Reference<awt::XDevice> mxDevice;
70 SfxViewShell* mpViewShell;
71 SfxObjectShell* mpObjectShell;
72 bool m_bOrigStatus;
73 bool m_bNeedsChange;
74 bool m_bApi;
75 bool m_bTempPrinter;
76 util::DateTime m_aLastPrinted;
77 OUString m_aLastPrintedBy;
79 Sequence< beans::PropertyValue > getMergedOptions() const;
80 const Any& getSelectionObject() const;
82 public:
83 SfxPrinterController( const VclPtr<Printer>& i_rPrinter,
84 const Any& i_rComplete,
85 const Any& i_rSelection,
86 const Any& i_rViewProp,
87 const Reference< view::XRenderable >& i_xRender,
88 bool i_bApi, bool i_bDirect,
89 SfxViewShell* pView,
90 const uno::Sequence< beans::PropertyValue >& rProps
93 virtual void Notify( SfxBroadcaster&, const SfxHint& ) override;
95 virtual int getPageCount() const override;
96 virtual Sequence< beans::PropertyValue > getPageParameters( int i_nPage ) const override;
97 virtual void printPage( int i_nPage ) const override;
98 virtual void jobStarted() override;
99 virtual void jobFinished( css::view::PrintableState ) override;
102 SfxPrinterController::SfxPrinterController( const VclPtr<Printer>& i_rPrinter,
103 const Any& i_rComplete,
104 const Any& i_rSelection,
105 const Any& i_rViewProp,
106 const Reference< view::XRenderable >& i_xRender,
107 bool i_bApi, bool i_bDirect,
108 SfxViewShell* pView,
109 const uno::Sequence< beans::PropertyValue >& rProps
111 : PrinterController(i_rPrinter, pView ? pView->GetFrameWeld() : nullptr)
112 , maCompleteSelection( i_rComplete )
113 , maSelection( i_rSelection )
114 , mxRenderable( i_xRender )
115 , mpLastPrinter( nullptr )
116 , mpViewShell( pView )
117 , mpObjectShell(nullptr)
118 , m_bOrigStatus( false )
119 , m_bNeedsChange( false )
120 , m_bApi(i_bApi)
121 , m_bTempPrinter( i_rPrinter )
123 if ( mpViewShell )
125 StartListening( *mpViewShell );
126 mpObjectShell = mpViewShell->GetObjectShell();
127 StartListening( *mpObjectShell );
130 // initialize extra ui options
131 if( mxRenderable.is() )
133 for (const auto& rProp : rProps)
134 setValue( rProp.Name, rProp.Value );
136 Sequence< beans::PropertyValue > aRenderOptions{
137 comphelper::makePropertyValue("ExtraPrintUIOptions", Any{}),
138 comphelper::makePropertyValue("View", i_rViewProp),
139 comphelper::makePropertyValue("IsPrinter", true)
143 const Sequence< beans::PropertyValue > aRenderParms( mxRenderable->getRenderer( 0 , getSelectionObject(), aRenderOptions ) );
144 for( const auto& rRenderParm : aRenderParms )
146 if ( rRenderParm.Name == "ExtraPrintUIOptions" )
148 Sequence< beans::PropertyValue > aUIProps;
149 rRenderParm.Value >>= aUIProps;
150 setUIOptions( aUIProps );
152 else if( rRenderParm.Name == "NUp" )
154 setValue( rRenderParm.Name, rRenderParm.Value );
158 catch( lang::IllegalArgumentException& )
160 // the first renderer should always be available for the UI options,
161 // but catch the exception to be safe
165 // set some job parameters
166 setValue( "IsApi", makeAny( i_bApi ) );
167 setValue( "IsDirect", makeAny( i_bDirect ) );
168 setValue( "IsPrinter", makeAny( true ) );
169 setValue( "View", i_rViewProp );
172 void SfxPrinterController::Notify( SfxBroadcaster& , const SfxHint& rHint )
174 if ( rHint.GetId() == SfxHintId::Dying )
176 EndListening(*mpViewShell);
177 EndListening(*mpObjectShell);
178 dialogsParentClosing();
179 mpViewShell = nullptr;
180 mpObjectShell = nullptr;
184 const Any& SfxPrinterController::getSelectionObject() const
186 const beans::PropertyValue* pVal = getValue( OUString( "PrintSelectionOnly" ) );
187 if( pVal )
189 bool bSel = false;
190 pVal->Value >>= bSel;
191 return bSel ? maSelection : maCompleteSelection;
194 sal_Int32 nChoice = 0;
195 pVal = getValue( OUString( "PrintContent" ) );
196 if( pVal )
197 pVal->Value >>= nChoice;
199 return (nChoice > 1) ? maSelection : maCompleteSelection;
202 Sequence< beans::PropertyValue > SfxPrinterController::getMergedOptions() const
204 VclPtr<Printer> xPrinter( getPrinter() );
205 if( xPrinter.get() != mpLastPrinter )
207 mpLastPrinter = xPrinter.get();
208 rtl::Reference<VCLXDevice> pXDevice = new VCLXDevice();
209 pXDevice->SetOutputDevice( mpLastPrinter );
210 mxDevice.set( pXDevice );
213 Sequence< beans::PropertyValue > aRenderOptions{ comphelper::makePropertyValue(
214 "RenderDevice", 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 uno::Sequence < beans::PropertyValue > aOpts;
317 aOpts = getJobProperties( aOpts );
319 uno::Reference< frame::XController2 > xController;
320 if ( mpViewShell )
321 xController.set( mpViewShell->GetController(), uno::UNO_QUERY );
323 mpObjectShell->Broadcast( SfxPrintingHint(
324 view::PrintableState_JOB_STARTED, aOpts, mpObjectShell, xController ) );
327 void SfxPrinterController::jobFinished( css::view::PrintableState nState )
329 if ( !mpObjectShell )
330 return;
332 bool bCopyJobSetup = false;
333 mpObjectShell->Broadcast( SfxPrintingHint( nState ) );
334 switch ( nState )
336 case view::PrintableState_JOB_SPOOLING_FAILED :
337 case view::PrintableState_JOB_FAILED :
339 // "real" problem (not simply printing cancelled by user)
340 OUString aMsg( SfxResId(STR_NOSTARTPRINTER) );
341 if ( !m_bApi )
343 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(mpViewShell->GetFrameWeld(),
344 VclMessageType::Warning, VclButtonsType::Ok,
345 aMsg));
346 xBox->run();
348 [[fallthrough]];
350 case view::PrintableState_JOB_ABORTED :
352 // printing not successful, reset DocInfo
353 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
354 xDocProps->setPrintedBy(m_aLastPrintedBy);
355 xDocProps->setPrintDate(m_aLastPrinted);
356 break;
359 case view::PrintableState_JOB_SPOOLED :
360 case view::PrintableState_JOB_COMPLETED :
362 SfxBindings& rBind = mpViewShell->GetViewFrame()->GetBindings();
363 rBind.Invalidate( SID_PRINTDOC );
364 rBind.Invalidate( SID_PRINTDOCDIRECT );
365 rBind.Invalidate( SID_SETUPPRINTER );
366 bCopyJobSetup = ! m_bTempPrinter;
367 break;
370 default:
371 break;
374 if( bCopyJobSetup && mpViewShell )
376 // #i114306#
377 // Note: this possibly creates a printer that gets immediately replaced
378 // by a new one. The reason for this is that otherwise we would not get
379 // the printer's SfxItemSet here to copy. Awkward, but at the moment there is no
380 // other way here to get the item set.
381 SfxPrinter* pDocPrt = mpViewShell->GetPrinter(true);
382 if( pDocPrt )
384 if( pDocPrt->GetName() == getPrinter()->GetName() )
385 pDocPrt->SetJobSetup( getPrinter()->GetJobSetup() );
386 else
388 VclPtr<SfxPrinter> pNewPrt = VclPtr<SfxPrinter>::Create( pDocPrt->GetOptions().Clone(), getPrinter()->GetName() );
389 pNewPrt->SetJobSetup( getPrinter()->GetJobSetup() );
390 mpViewShell->SetPrinter( pNewPrt, SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP );
395 if ( m_bNeedsChange )
396 mpObjectShell->EnableSetModified( m_bOrigStatus );
398 if ( mpViewShell )
400 mpViewShell->pImpl->m_xPrinterController.reset();
404 namespace {
407 An instance of this class is created for the life span of the
408 printer dialogue, to create in its click handler for the additions by the
409 virtual method of the derived SfxViewShell generated print options dialogue
410 and to cache the options set there as SfxItemSet.
412 class SfxDialogExecutor_Impl
414 private:
415 SfxViewShell* _pViewSh;
416 PrinterSetupDialog& _rSetupParent;
417 std::unique_ptr<SfxItemSet> _pOptions;
418 bool _bHelpDisabled;
420 DECL_LINK( Execute, weld::Button&, void );
422 public:
423 SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent );
425 Link<weld::Button&, void> GetLink() const { return LINK(const_cast<SfxDialogExecutor_Impl*>(this), SfxDialogExecutor_Impl, Execute); }
426 const SfxItemSet* GetOptions() const { return _pOptions.get(); }
427 void DisableHelp() { _bHelpDisabled = true; }
432 SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent ) :
434 _pViewSh ( pViewSh ),
435 _rSetupParent ( rParent ),
436 _bHelpDisabled ( false )
441 IMPL_LINK_NOARG(SfxDialogExecutor_Impl, Execute, weld::Button&, void)
443 // Options noted locally
444 if ( !_pOptions )
446 _pOptions = static_cast<SfxPrinter*>( _rSetupParent.GetPrinter() )->GetOptions().Clone();
449 assert(_pOptions);
450 if (!_pOptions)
451 return;
453 // Create Dialog
454 SfxPrintOptionsDialog aDlg(_rSetupParent.GetFrameWeld(), _pViewSh, _pOptions.get() );
455 if (_bHelpDisabled)
456 aDlg.DisableHelp();
457 if (aDlg.run() == RET_OK)
459 _pOptions = aDlg.GetOptions().Clone();
464 Internal method for setting the differences between 'pNewPrinter' to the
465 current printer. pNewPrinter is either taken over or deleted.
467 void SfxViewShell::SetPrinter_Impl( VclPtr<SfxPrinter>& pNewPrinter )
469 // get current Printer
470 SfxPrinter *pDocPrinter = GetPrinter();
472 // Evaluate Printer Options
473 sal_uInt16 nWhich = GetPool().GetWhich(SID_PRINTER_CHANGESTODOC);
474 const SfxFlagItem *pFlagItem = nullptr;
475 pDocPrinter->GetOptions().GetItemState( nWhich, false, reinterpret_cast<const SfxPoolItem**>(&pFlagItem) );
476 bool bOriToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION);
477 bool bSizeToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE);
479 // Determine the previous format and size
480 Orientation eOldOri = pDocPrinter->GetOrientation();
481 Size aOldPgSz = pDocPrinter->GetPaperSizePixel();
483 // Determine the new format and size
484 Orientation eNewOri = pNewPrinter->GetOrientation();
485 Size aNewPgSz = pNewPrinter->GetPaperSizePixel();
487 // Determine the changes in page format
488 bool bOriChg = (eOldOri != eNewOri) && bOriToDoc;
489 bool bPgSzChg = ( aOldPgSz.Height() !=
490 ( bOriChg ? aNewPgSz.Width() : aNewPgSz.Height() ) ||
491 aOldPgSz.Width() !=
492 ( bOriChg ? aNewPgSz.Height() : aNewPgSz.Width() ) ) &&
493 bSizeToDoc;
495 // Message and Flags for page format changes
496 OUString aMsg;
497 SfxPrinterChangeFlags nNewOpt = SfxPrinterChangeFlags::NONE;
498 if( bOriChg && bPgSzChg )
500 aMsg = SfxResId(STR_PRINT_NEWORISIZE);
501 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION | SfxPrinterChangeFlags::CHG_SIZE;
503 else if (bOriChg )
505 aMsg = SfxResId(STR_PRINT_NEWORI);
506 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION;
508 else if (bPgSzChg)
510 aMsg = SfxResId(STR_PRINT_NEWSIZE);
511 nNewOpt = SfxPrinterChangeFlags::CHG_SIZE;
514 // Summarize in this variable what has been changed.
515 SfxPrinterChangeFlags nChangedFlags = SfxPrinterChangeFlags::NONE;
517 // Ask if possible, if page format should be taken over from printer.
518 if (bOriChg || bPgSzChg)
520 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
521 VclMessageType::Question, VclButtonsType::YesNo,
522 aMsg));
523 if (RET_YES == xBox->run())
525 // Flags with changes for <SetPrinter(SfxPrinter*)> are maintained
526 nChangedFlags |= nNewOpt;
530 // Was the printer selection changed from Default to Specific
531 // or the other way around?
532 if ( (pNewPrinter->GetName() != pDocPrinter->GetName())
533 || (pDocPrinter->IsDefPrinter() != pNewPrinter->IsDefPrinter()) )
535 nChangedFlags |= SfxPrinterChangeFlags::PRINTER|SfxPrinterChangeFlags::JOBSETUP;
536 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
538 nChangedFlags |= SfxPrinterChangeFlags::OPTIONS;
541 pDocPrinter = pNewPrinter;
543 else
545 // Compare extra options
546 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
548 // Option have changed
549 pDocPrinter->SetOptions( pNewPrinter->GetOptions() );
550 nChangedFlags |= SfxPrinterChangeFlags::OPTIONS;
553 // Compare JobSetups
554 JobSetup aNewJobSetup = pNewPrinter->GetJobSetup();
555 JobSetup aOldJobSetup = pDocPrinter->GetJobSetup();
556 if ( aNewJobSetup != aOldJobSetup )
558 nChangedFlags |= SfxPrinterChangeFlags::JOBSETUP;
561 // Keep old changed Printer.
562 pDocPrinter->SetPrinterProps( pNewPrinter );
563 pNewPrinter.disposeAndClear();
566 if ( SfxPrinterChangeFlags::NONE != nChangedFlags )
567 // SetPrinter will delete the old printer if it changes
568 SetPrinter( pDocPrinter, nChangedFlags );
571 void SfxViewShell::StartPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
573 assert( !pImpl->m_xPrinterController );
575 // get the current selection; our controller should know it
576 Reference< frame::XController > xController( GetController() );
577 Reference< view::XSelectionSupplier > xSupplier( xController, UNO_QUERY );
579 Any aSelection;
580 if( xSupplier.is() )
581 aSelection = xSupplier->getSelection();
582 else
583 aSelection <<= GetObjectShell()->GetModel();
584 Any aComplete( makeAny( GetObjectShell()->GetModel() ) );
585 Any aViewProp( makeAny( xController ) );
586 VclPtr<Printer> aPrt;
588 const beans::PropertyValue* pVal = std::find_if(rProps.begin(), rProps.end(),
589 [](const beans::PropertyValue& rVal) { return rVal.Name == "PrinterName"; });
590 if (pVal != rProps.end())
592 OUString aPrinterName;
593 pVal->Value >>= aPrinterName;
594 aPrt.reset( VclPtr<Printer>::Create( aPrinterName ) );
597 std::shared_ptr<vcl::PrinterController> xNewController(std::make_shared<SfxPrinterController>(
598 aPrt,
599 aComplete,
600 aSelection,
601 aViewProp,
602 GetRenderable(),
603 bIsAPI,
604 bIsDirect,
605 this,
606 rProps
608 pImpl->m_xPrinterController = xNewController;
610 SfxObjectShell *pObjShell = GetObjectShell();
611 xNewController->setValue( "JobName",
612 makeAny( pObjShell->GetTitle(1) ) );
613 xNewController->setPrinterModified( mbPrinterSettingsModified );
616 void SfxViewShell::ExecPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
618 StartPrint( rProps, bIsAPI, bIsDirect );
619 // FIXME: job setup
620 SfxPrinter* pDocPrt = GetPrinter();
621 JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : JobSetup();
622 Printer::PrintJob( GetPrinterController(), aJobSetup );
625 const std::shared_ptr< vcl::PrinterController >& SfxViewShell::GetPrinterController() const
627 return pImpl->m_xPrinterController;
630 Printer* SfxViewShell::GetActivePrinter() const
632 return pImpl->m_xPrinterController
633 ? pImpl->m_xPrinterController->getPrinter().get() : nullptr;
636 void SfxViewShell::ExecPrint_Impl( SfxRequest &rReq )
638 sal_uInt16 nDialogRet = RET_CANCEL;
639 VclPtr<SfxPrinter> pPrinter;
640 bool bSilent = false;
642 // does the function have been called by the user interface or by an API call
643 bool bIsAPI = rReq.GetArgs() && rReq.GetArgs()->Count();
644 if ( bIsAPI )
646 // the function have been called by the API
648 // Should it be visible on the user interface,
649 // should it launch popup dialogue ?
650 const SfxBoolItem* pSilentItem = rReq.GetArg<SfxBoolItem>(SID_SILENT);
651 bSilent = pSilentItem && pSilentItem->GetValue();
654 // no help button in dialogs if called from the help window
655 // (pressing help button would exchange the current page inside the help
656 // document that is going to be printed!)
657 SfxMedium* pMedium = GetViewFrame()->GetObjectShell()->GetMedium();
658 std::shared_ptr<const SfxFilter> pFilter = pMedium ? pMedium->GetFilter() : nullptr;
659 bool bPrintOnHelp = ( pFilter && pFilter->GetFilterName() == "writer_web_HTML_help" );
661 const sal_uInt16 nId = rReq.GetSlot();
662 switch( nId )
664 case SID_PRINTDOC: // display the printer selection and properties dialogue : File > Print...
665 case SID_PRINTDOCDIRECT: // Print the document directly, without displaying the dialogue
667 SfxObjectShell* pDoc = GetObjectShell();
669 // derived class may decide to abort this
670 if( pDoc == nullptr || !pDoc->QuerySlotExecutable( nId ) )
672 rReq.SetReturnValue( SfxBoolItem( 0, false ) );
673 return;
676 if ( !bSilent && pDoc->QueryHiddenInformation( HiddenWarningFact::WhenPrinting, nullptr ) != RET_YES )
677 return;
679 // should we print only the selection or the whole document
680 const SfxBoolItem* pSelectItem = rReq.GetArg<SfxBoolItem>(SID_SELECTION);
681 bool bSelection = ( pSelectItem != nullptr && pSelectItem->GetValue() );
682 // detect non api call from writer ( that adds SID_SELECTION ) and reset bIsAPI
683 if ( pSelectItem && rReq.GetArgs()->Count() == 1 )
684 bIsAPI = false;
686 uno::Sequence < beans::PropertyValue > aProps;
687 if ( bIsAPI )
689 // supported properties:
690 // String PrinterName
691 // String FileName
692 // Int16 From
693 // Int16 To
694 // In16 Copies
695 // String RangeText
696 // bool Selection
697 // bool Asynchron
698 // bool Collate
699 // bool Silent
701 // the TransformItems function overwrite aProps
702 TransformItems( nId, *rReq.GetArgs(), aProps, GetInterface()->GetSlot(nId) );
704 for ( auto& rProp : asNonConstRange(aProps) )
706 if ( rProp.Name == "Copies" )
708 rProp.Name = "CopyCount";
710 else if ( rProp.Name == "RangeText" )
712 rProp.Name = "Pages";
714 else if ( rProp.Name == "Asynchron" )
716 rProp.Name = "Wait";
717 bool bAsynchron = false;
718 rProp.Value >>= bAsynchron;
719 rProp.Value <<= !bAsynchron;
721 else if ( rProp.Name == "Silent" )
723 rProp.Name = "MonitorVisible";
724 bool bPrintSilent = false;
725 rProp.Value >>= bPrintSilent;
726 rProp.Value <<= !bPrintSilent;
731 // we will add the "PrintSelectionOnly" or "HideHelpButton" properties
732 // we have to increase the capacity of aProps
733 sal_Int32 nLen = aProps.getLength();
734 aProps.realloc( nLen + 1 );
735 auto pProps = aProps.getArray();
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 pProps[nLen].Name = "PrintSelectionOnly";
745 pProps[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 pProps[nLen].Name = "HideHelpButton";
751 pProps[nLen].Value <<= bPrintOnHelp;
754 ExecPrint( aProps, bIsAPI, (nId == SID_PRINTDOCDIRECT) );
756 // FIXME: Recording
757 rReq.Done();
758 break;
761 case SID_PRINTER_NAME: // for recorded macros
763 // get printer and printer settings from the document
764 SfxPrinter* pDocPrinter = GetPrinter(true);
765 const SfxStringItem* pPrinterItem = rReq.GetArg<SfxStringItem>(SID_PRINTER_NAME);
766 if (!pPrinterItem)
768 rReq.Ignore();
769 break;
771 // use PrinterName parameter to create a printer
772 pPrinter = VclPtr<SfxPrinter>::Create(pDocPrinter->GetOptions().Clone(),
773 pPrinterItem->GetValue());
775 if (!pPrinter->IsKnown())
777 pPrinter.disposeAndClear();
778 rReq.Ignore();
779 break;
781 SetPrinter(pPrinter, SfxPrinterChangeFlags::PRINTER);
782 rReq.Done();
783 break;
785 case SID_SETUPPRINTER : // display the printer settings dialog : File > Printer Settings...
787 // get printer and printer settings from the document
788 SfxPrinter *pDocPrinter = GetPrinter(true);
790 // look for printer in parameters
791 const SfxStringItem* pPrinterItem = rReq.GetArg<SfxStringItem>(SID_PRINTER_NAME);
792 if ( pPrinterItem )
794 // use PrinterName parameter to create a printer
795 pPrinter = VclPtr<SfxPrinter>::Create( pDocPrinter->GetOptions().Clone(), pPrinterItem->GetValue() );
797 // if printer is unknown, it can't be used - now printer from document will be used
798 if ( !pPrinter->IsKnown() )
799 pPrinter.disposeAndClear();
802 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
803 if ( !pPrinter )
804 // use default printer from document
805 pPrinter = pDocPrinter;
807 if( !pPrinter || !pPrinter->IsValid() )
809 // no valid printer either in ItemSet or at the document
810 if ( !bSilent )
812 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
813 VclMessageType::Warning, VclButtonsType::Ok,
814 SfxResId(STR_NODEFPRINTER)));
815 xBox->run();
818 rReq.SetReturnValue(SfxBoolItem(0,false));
820 break;
823 // FIXME: printer isn't used for printing anymore!
824 if( pPrinter->IsPrinting() )
826 // if printer is busy, abort configuration
827 if ( !bSilent )
829 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
830 VclMessageType::Info, VclButtonsType::Ok,
831 SfxResId(STR_ERROR_PRINTER_BUSY)));
832 xBox->run();
834 rReq.SetReturnValue(SfxBoolItem(0,false));
836 return;
839 // Open Printer Setup dialog (needs a temporary printer)
840 VclPtr<SfxPrinter> pDlgPrinter = pPrinter->Clone();
841 PrinterSetupDialog aPrintSetupDlg(GetFrameWeld());
842 std::unique_ptr<SfxDialogExecutor_Impl> pExecutor;
844 if (pImpl->m_bHasPrintOptions && HasPrintOptionsPage())
846 // additional controls for dialog
847 pExecutor.reset(new SfxDialogExecutor_Impl(this, aPrintSetupDlg));
848 if (bPrintOnHelp)
849 pExecutor->DisableHelp();
850 aPrintSetupDlg.SetOptionsHdl(pExecutor->GetLink());
853 aPrintSetupDlg.SetPrinter(pDlgPrinter);
854 nDialogRet = aPrintSetupDlg.run();
856 if (pExecutor && pExecutor->GetOptions())
858 if (nDialogRet == RET_OK)
859 // remark: have to be recorded if possible!
860 pDlgPrinter->SetOptions(*pExecutor->GetOptions());
861 else
863 pPrinter->SetOptions(*pExecutor->GetOptions());
864 SetPrinter(pPrinter, SfxPrinterChangeFlags::OPTIONS);
868 // no recording of PrinterSetup except printer name (is printer dependent)
869 rReq.Ignore();
871 if (nDialogRet == RET_OK)
873 if (pPrinter->GetName() != pDlgPrinter->GetName())
875 // user has changed the printer -> macro recording
876 SfxRequest aReq(GetViewFrame(), SID_PRINTER_NAME);
877 aReq.AppendItem(SfxStringItem(SID_PRINTER_NAME, pDlgPrinter->GetName()));
878 aReq.Done();
881 // take the changes made in the dialog
882 SetPrinter_Impl(pDlgPrinter);
884 // forget new printer, it was taken over (as pPrinter) or deleted
885 pDlgPrinter = nullptr;
886 mbPrinterSettingsModified = true;
888 else
890 // PrinterDialog is used to transfer information on printing,
891 // so it will only be deleted here if dialog was cancelled
892 pDlgPrinter.disposeAndClear();
893 rReq.Ignore();
895 break;
900 SfxPrinter* SfxViewShell::GetPrinter( bool /*bCreate*/ )
902 return nullptr;
905 sal_uInt16 SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, SfxPrinterChangeFlags /*nDiffFlags*/ )
907 return 0;
910 std::unique_ptr<SfxTabPage> SfxViewShell::CreatePrintOptionsPage(weld::Container*, weld::DialogController*, const SfxItemSet&)
912 return nullptr;
915 bool SfxViewShell::HasPrintOptionsPage() const
917 return false;
920 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */