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>
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>
58 using namespace com::sun::star
;
59 using namespace com::sun::star::uno
;
61 class SfxPrinterController
: public vcl::PrinterController
, public SfxListener
63 Any maCompleteSelection
;
65 Reference
< view::XRenderable
> mxRenderable
;
66 mutable VclPtr
<Printer
> mpLastPrinter
;
67 mutable Reference
<awt::XDevice
> mxDevice
;
68 SfxViewShell
* mpViewShell
;
69 SfxObjectShell
* mpObjectShell
;
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
)
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" ) );
189 pVal
->Value
>>= bSel
;
190 return bSel
? maSelection
: maCompleteSelection
;
193 sal_Int32 nChoice
= 0;
194 pVal
= getValue( OUString( "PrintContent" ) );
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
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
);
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
);
266 void SfxPrinterController::printPage( int i_nPage
) const
268 VclPtr
<Printer
> xPrinter( getPrinter() );
269 if( !mxRenderable
.is() || !xPrinter
)
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
)
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()
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
;
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
)
333 bool bCopyJobSetup
= false;
334 mpObjectShell
->Broadcast( SfxPrintingHint( 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
) );
344 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(mpViewShell
->GetFrameWeld(),
345 VclMessageType::Warning
, VclButtonsType::Ok
,
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
);
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
;
375 if( bCopyJobSetup
&& mpViewShell
)
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);
385 if( pDocPrt
->GetName() == getPrinter()->GetName() )
386 pDocPrt
->SetJobSetup( getPrinter()->GetJobSetup() );
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
);
401 mpViewShell
->pImpl
->m_xPrinterController
.reset();
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
416 SfxViewShell
* _pViewSh
;
417 PrinterSetupDialog
& _rSetupParent
;
418 std::unique_ptr
<SfxItemSet
> _pOptions
;
421 DECL_LINK( Execute
, weld::Button
&, void );
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
447 _pOptions
= static_cast<SfxPrinter
*>( _rSetupParent
.GetPrinter() )->GetOptions().Clone();
455 SfxPrintOptionsDialog
aDlg(_rSetupParent
.GetFrameWeld(), _pViewSh
, _pOptions
.get() );
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() ) ||
493 ( bOriChg
? aNewPgSz
.Height() : aNewPgSz
.Width() ) ) &&
496 // Message and Flags for page format changes
498 SfxPrinterChangeFlags nNewOpt
= SfxPrinterChangeFlags::NONE
;
499 if( bOriChg
&& bPgSzChg
)
501 aMsg
= SfxResId(STR_PRINT_NEWORISIZE
);
502 nNewOpt
= SfxPrinterChangeFlags::CHG_ORIENTATION
| SfxPrinterChangeFlags::CHG_SIZE
;
506 aMsg
= SfxResId(STR_PRINT_NEWORI
);
507 nNewOpt
= SfxPrinterChangeFlags::CHG_ORIENTATION
;
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
,
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
;
546 // Compare extra options
547 if ( ! (pNewPrinter
->GetOptions() == pDocPrinter
->GetOptions()) )
549 // Option have changed
550 pDocPrinter
->SetOptions( pNewPrinter
->GetOptions() );
551 nChangedFlags
|= SfxPrinterChangeFlags::OPTIONS
;
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
);
582 aSelection
= xSupplier
->getSelection();
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
>(
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
);
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();
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();
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 ) );
677 if ( !bSilent
&& pDoc
->QueryHiddenInformation( HiddenWarningFact::WhenPrinting
, nullptr ) != RET_YES
)
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 )
687 uno::Sequence
< beans::PropertyValue
> aProps
;
690 // supported properties:
691 // String PrinterName
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" )
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
) );
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
);
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
783 SetPrinter( pPrinter
, SfxPrinterChangeFlags::PRINTER
);
787 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
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
797 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
798 VclMessageType::Warning
, VclButtonsType::Ok
,
799 SfxResId(STR_NODEFPRINTER
)));
803 rReq
.SetReturnValue(SfxBoolItem(0,false));
808 // FIXME: printer isn't used for printing anymore!
809 if( pPrinter
->IsPrinting() )
811 // if printer is busy, abort configuration
814 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
815 VclMessageType::Info
, VclButtonsType::Ok
,
816 SfxResId(STR_ERROR_PRINTER_BUSY
)));
819 rReq
.SetReturnValue(SfxBoolItem(0,false));
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
) );
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() );
853 pPrinter
->SetOptions( *pExecutor
->GetOptions() );
854 SetPrinter( pPrinter
, SfxPrinterChangeFlags::OPTIONS
);
858 // no recording of PrinterSetup except printer name (is printer dependent)
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() ) );
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;
880 // PrinterDialog is used to transfer information on printing,
881 // so it will only be deleted here if dialog was cancelled
882 pDlgPrinter
.disposeAndClear();
890 SfxPrinter
* SfxViewShell::GetPrinter( bool /*bCreate*/ )
895 sal_uInt16
SfxViewShell::SetPrinter( SfxPrinter
* /*pNewPrinter*/, SfxPrinterChangeFlags
/*nDiffFlags*/ )
900 std::unique_ptr
<SfxTabPage
> SfxViewShell::CreatePrintOptionsPage(weld::Container
*, weld::DialogController
*, const SfxItemSet
&)
905 bool SfxViewShell::HasPrintOptionsPage() const
910 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */