1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
;
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;
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
,
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
,
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 )
119 , m_bTempPrinter( i_rPrinter
.get() != nullptr )
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" ) );
188 pVal
->Value
>>= bSel
;
189 return bSel
? maSelection
: maCompleteSelection
;
192 bool bIsCalc
= false;
193 pVal
= getValue( OUString( "PrintRange" ) );
197 sal_Int32 nChoice
= 0;
198 pVal
= getValue( OUString( "PrintContent" ) );
200 pVal
->Value
>>= nChoice
;
203 return (nChoice
> 1) ? maSelection
: maCompleteSelection
;
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
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
);
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
);
273 void SfxPrinterController::printPage( int i_nPage
) const
275 VclPtr
<Printer
> xPrinter( getPrinter() );
276 if( !mxRenderable
.is() || !xPrinter
)
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
)
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()
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
;
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
)
340 bool bCopyJobSetup
= false;
341 mpObjectShell
->Broadcast( SfxPrintingHint( 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
) );
351 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(mpViewShell
->GetFrameWeld(),
352 VclMessageType::Warning
, VclButtonsType::Ok
,
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
);
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
;
382 if( bCopyJobSetup
&& mpViewShell
)
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);
392 if( pDocPrt
->GetName() == getPrinter()->GetName() )
393 pDocPrt
->SetJobSetup( getPrinter()->GetJobSetup() );
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
);
408 mpViewShell
->pImpl
->m_xPrinterController
.reset();
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
423 SfxViewShell
* const _pViewSh
;
424 PrinterSetupDialog
& _rSetupParent
;
425 std::unique_ptr
<SfxItemSet
> _pOptions
;
428 DECL_LINK( Execute
, weld::Button
&, void );
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
454 _pOptions
= static_cast<SfxPrinter
*>( _rSetupParent
.GetPrinter() )->GetOptions().Clone();
462 SfxPrintOptionsDialog
aDlg(_rSetupParent
.GetFrameWeld(), _pViewSh
, _pOptions
.get() );
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() ) ||
500 ( bOriChg
? aNewPgSz
.Height() : aNewPgSz
.Width() ) ) &&
503 // Message and Flags for page format, summaries changes
505 SfxPrinterChangeFlags nNewOpt
= SfxPrinterChangeFlags::NONE
;
506 if( bOriChg
&& bPgSzChg
)
508 aMsg
= SfxResId(STR_PRINT_NEWORISIZE
);
509 nNewOpt
= SfxPrinterChangeFlags::CHG_ORIENTATION
| SfxPrinterChangeFlags::CHG_SIZE
;
513 aMsg
= SfxResId(STR_PRINT_NEWORI
);
514 nNewOpt
= SfxPrinterChangeFlags::CHG_ORIENTATION
;
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
,
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
;
551 // Compare extra options
552 if ( ! (pNewPrinter
->GetOptions() == pDocPrinter
->GetOptions()) )
554 // Option have changed
555 pDocPrinter
->SetOptions( pNewPrinter
->GetOptions() );
556 nChangedFlags
|= SfxPrinterChangeFlags::OPTIONS
;
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
);
587 aSelection
= xSupplier
->getSelection();
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
>(
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
);
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();
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();
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 ) );
682 if ( !bSilent
&& pDoc
->QueryHiddenInformation( HiddenWarningFact::WhenPrinting
, nullptr ) != RET_YES
)
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 )
692 uno::Sequence
< beans::PropertyValue
> aProps
;
695 // supported properties:
696 // String PrinterName
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" )
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
) );
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
);
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
788 SetPrinter( pPrinter
, SfxPrinterChangeFlags::PRINTER
);
792 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
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
802 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
803 VclMessageType::Warning
, VclButtonsType::Ok
,
804 SfxResId(STR_NODEFPRINTER
)));
808 rReq
.SetReturnValue(SfxBoolItem(0,false));
813 // FIXME: printer isn't used for printing anymore!
814 if( pPrinter
->IsPrinting() )
816 // if printer is busy, abort configuration
819 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
820 VclMessageType::Info
, VclButtonsType::Ok
,
821 SfxResId(STR_ERROR_PRINTER_BUSY
)));
824 rReq
.SetReturnValue(SfxBoolItem(0,false));
829 // if no arguments are given, retrieve them from a dialog
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
) );
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() );
858 pPrinter
->SetOptions( *pExecutor
->GetOptions() );
859 SetPrinter( pPrinter
, SfxPrinterChangeFlags::OPTIONS
);
863 // no recording of PrinterSetup except printer name (is printer dependent)
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() ) );
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;
885 // PrinterDialog is used to transfer information on printing,
886 // so it will only be deleted here if dialog was cancelled
887 pDlgPrinter
.disposeAndClear();
895 SfxPrinter
* SfxViewShell::GetPrinter( bool /*bCreate*/ )
900 sal_uInt16
SfxViewShell::SetPrinter( SfxPrinter
* /*pNewPrinter*/, SfxPrinterChangeFlags
/*nDiffFlags*/ )
905 std::unique_ptr
<SfxTabPage
> SfxViewShell::CreatePrintOptionsPage(weld::Container
*, weld::DialogController
*, const SfxItemSet
&)
910 bool SfxViewShell::HasPrintOptionsPage() const
915 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */