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 <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>
60 using namespace com::sun::star
;
61 using namespace com::sun::star::uno
;
63 class SfxPrinterController
: public vcl::PrinterController
, public SfxListener
65 Any maCompleteSelection
;
67 Reference
< view::XRenderable
> mxRenderable
;
68 mutable VclPtr
<Printer
> mpLastPrinter
;
69 mutable Reference
<awt::XDevice
> mxDevice
;
70 SfxViewShell
* mpViewShell
;
71 SfxObjectShell
* mpObjectShell
;
76 util::DateTime m_aLastPrinted
;
77 OUString m_aLastPrintedBy
;
79 Sequence
< beans::PropertyValue
> getMergedOptions() const;
80 const Any
& getSelectionObject() const;
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
,
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
,
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 )
121 , m_bTempPrinter( i_rPrinter
)
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" ) );
190 pVal
->Value
>>= bSel
;
191 return bSel
? maSelection
: maCompleteSelection
;
194 sal_Int32 nChoice
= 0;
195 pVal
= getValue( OUString( "PrintContent" ) );
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
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 uno::Sequence
< beans::PropertyValue
> aOpts
;
317 aOpts
= getJobProperties( aOpts
);
319 uno::Reference
< frame::XController2
> xController
;
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
)
332 bool bCopyJobSetup
= false;
333 mpObjectShell
->Broadcast( SfxPrintingHint( 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
) );
343 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(mpViewShell
->GetFrameWeld(),
344 VclMessageType::Warning
, VclButtonsType::Ok
,
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
);
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
;
374 if( bCopyJobSetup
&& mpViewShell
)
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);
384 if( pDocPrt
->GetName() == getPrinter()->GetName() )
385 pDocPrt
->SetJobSetup( getPrinter()->GetJobSetup() );
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
);
400 mpViewShell
->pImpl
->m_xPrinterController
.reset();
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
415 SfxViewShell
* _pViewSh
;
416 PrinterSetupDialog
& _rSetupParent
;
417 std::unique_ptr
<SfxItemSet
> _pOptions
;
420 DECL_LINK( Execute
, weld::Button
&, void );
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
446 _pOptions
= static_cast<SfxPrinter
*>( _rSetupParent
.GetPrinter() )->GetOptions().Clone();
454 SfxPrintOptionsDialog
aDlg(_rSetupParent
.GetFrameWeld(), _pViewSh
, _pOptions
.get() );
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() ) ||
492 ( bOriChg
? aNewPgSz
.Height() : aNewPgSz
.Width() ) ) &&
495 // Message and Flags for page format changes
497 SfxPrinterChangeFlags nNewOpt
= SfxPrinterChangeFlags::NONE
;
498 if( bOriChg
&& bPgSzChg
)
500 aMsg
= SfxResId(STR_PRINT_NEWORISIZE
);
501 nNewOpt
= SfxPrinterChangeFlags::CHG_ORIENTATION
| SfxPrinterChangeFlags::CHG_SIZE
;
505 aMsg
= SfxResId(STR_PRINT_NEWORI
);
506 nNewOpt
= SfxPrinterChangeFlags::CHG_ORIENTATION
;
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
,
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
;
545 // Compare extra options
546 if ( ! (pNewPrinter
->GetOptions() == pDocPrinter
->GetOptions()) )
548 // Option have changed
549 pDocPrinter
->SetOptions( pNewPrinter
->GetOptions() );
550 nChangedFlags
|= SfxPrinterChangeFlags::OPTIONS
;
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
);
581 aSelection
= xSupplier
->getSelection();
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
>(
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
);
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();
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();
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 ) );
676 if ( !bSilent
&& pDoc
->QueryHiddenInformation( HiddenWarningFact::WhenPrinting
, nullptr ) != RET_YES
)
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 )
686 uno::Sequence
< beans::PropertyValue
> aProps
;
689 // supported properties:
690 // String PrinterName
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" )
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
) );
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
);
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();
781 SetPrinter(pPrinter
, SfxPrinterChangeFlags::PRINTER
);
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
);
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
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
812 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
813 VclMessageType::Warning
, VclButtonsType::Ok
,
814 SfxResId(STR_NODEFPRINTER
)));
818 rReq
.SetReturnValue(SfxBoolItem(0,false));
823 // FIXME: printer isn't used for printing anymore!
824 if( pPrinter
->IsPrinting() )
826 // if printer is busy, abort configuration
829 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
830 VclMessageType::Info
, VclButtonsType::Ok
,
831 SfxResId(STR_ERROR_PRINTER_BUSY
)));
834 rReq
.SetReturnValue(SfxBoolItem(0,false));
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
));
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());
863 pPrinter
->SetOptions(*pExecutor
->GetOptions());
864 SetPrinter(pPrinter
, SfxPrinterChangeFlags::OPTIONS
);
868 // no recording of PrinterSetup except printer name (is printer dependent)
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()));
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;
890 // PrinterDialog is used to transfer information on printing,
891 // so it will only be deleted here if dialog was cancelled
892 pDlgPrinter
.disposeAndClear();
900 SfxPrinter
* SfxViewShell::GetPrinter( bool /*bCreate*/ )
905 sal_uInt16
SfxViewShell::SetPrinter( SfxPrinter
* /*pNewPrinter*/, SfxPrinterChangeFlags
/*nDiffFlags*/ )
910 std::unique_ptr
<SfxTabPage
> SfxViewShell::CreatePrintOptionsPage(weld::Container
*, weld::DialogController
*, const SfxItemSet
&)
915 bool SfxViewShell::HasPrintOptionsPage() const
920 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */