blob: 90d21098558614de6d66ad62bd6508deb1167187 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"
#include <com/sun/star/document/XDocumentProperties.hpp>
#include "com/sun/star/view/XRenderable.hpp"
#include <svl/itempool.hxx>
#include <vcl/msgbox.hxx>
#include <svtools/prnsetup.hxx>
#include <svl/flagitem.hxx>
#include <svl/stritem.hxx>
#include <svl/intitem.hxx>
#include <svl/eitem.hxx>
#include <sfx2/app.hxx>
#include <unotools/useroptions.hxx>
#include <unotools/printwarningoptions.hxx>
#include <tools/datetime.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/viewsh.hxx>
#include "viewimp.hxx"
#include <sfx2/viewfrm.hxx>
#include <sfx2/prnmon.hxx>
#include "sfx2/sfxresid.hxx"
#include <sfx2/request.hxx>
#include <sfx2/objsh.hxx>
#include "sfxtypes.hxx"
#include <sfx2/event.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include "toolkit/awt/vclxdevice.hxx"
#include "view.hrc"
#include "helpid.hrc"
using namespace com::sun::star;
using namespace com::sun::star::uno;
TYPEINIT1(SfxPrintingHint, SfxViewEventHint);
// -----------------------------------------------------------------------
class SfxPrinterController : public vcl::PrinterController, public SfxListener
{
Any maCompleteSelection;
Any maSelection;
Reference< view::XRenderable > mxRenderable;
mutable Printer* mpLastPrinter;
mutable Reference<awt::XDevice> mxDevice;
SfxViewShell* mpViewShell;
SfxObjectShell* mpObjectShell;
sal_Bool m_bOrigStatus;
sal_Bool m_bNeedsChange;
sal_Bool m_bApi;
sal_Bool m_bTempPrinter;
util::DateTime m_aLastPrinted;
::rtl::OUString m_aLastPrintedBy;
Sequence< beans::PropertyValue > getMergedOptions() const;
const Any& getSelectionObject() const;
public:
SfxPrinterController( const boost::shared_ptr<Printer>& i_rPrinter,
const Any& i_rComplete,
const Any& i_rSelection,
const Any& i_rViewProp,
const Reference< view::XRenderable >& i_xRender,
sal_Bool i_bApi, sal_Bool i_bDirect,
SfxViewShell* pView,
const uno::Sequence< beans::PropertyValue >& rProps
);
virtual ~SfxPrinterController();
virtual void Notify( SfxBroadcaster&, const SfxHint& );
virtual int getPageCount() const;
virtual Sequence< beans::PropertyValue > getPageParameters( int i_nPage ) const;
virtual void printPage( int i_nPage ) const;
virtual void jobStarted();
virtual void jobFinished( com::sun::star::view::PrintableState );
};
SfxPrinterController::SfxPrinterController( const boost::shared_ptr<Printer>& i_rPrinter,
const Any& i_rComplete,
const Any& i_rSelection,
const Any& i_rViewProp,
const Reference< view::XRenderable >& i_xRender,
sal_Bool i_bApi, sal_Bool i_bDirect,
SfxViewShell* pView,
const uno::Sequence< beans::PropertyValue >& rProps
)
: PrinterController( i_rPrinter)
, maCompleteSelection( i_rComplete )
, maSelection( i_rSelection )
, mxRenderable( i_xRender )
, mpLastPrinter( NULL )
, mpViewShell( pView )
, mpObjectShell(0)
, m_bOrigStatus( sal_False )
, m_bNeedsChange( sal_False )
, m_bApi(i_bApi)
, m_bTempPrinter( i_rPrinter.get() != NULL )
{
if ( mpViewShell )
{
StartListening( *mpViewShell );
mpObjectShell = mpViewShell->GetObjectShell();
StartListening( *mpObjectShell );
}
// initialize extra ui options
if( mxRenderable.is() )
{
for (sal_Int32 nProp=0; nProp<rProps.getLength(); nProp++)
setValue( rProps[nProp].Name, rProps[nProp].Value );
Sequence< beans::PropertyValue > aRenderOptions( 3 );
aRenderOptions[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ExtraPrintUIOptions" ) );
aRenderOptions[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "View" ) );
aRenderOptions[1].Value = i_rViewProp;
aRenderOptions[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrinter" ) );
aRenderOptions[2].Value <<= sal_True;
try
{
Sequence< beans::PropertyValue > aRenderParms( mxRenderable->getRenderer( 0 , getSelectionObject(), aRenderOptions ) );
int nProps = aRenderParms.getLength();
for( int i = 0; i < nProps; i++ )
{
if( aRenderParms[i].Name.equalsAscii( "ExtraPrintUIOptions" ) )
{
Sequence< beans::PropertyValue > aUIProps;
aRenderParms[i].Value >>= aUIProps;
setUIOptions( aUIProps );
}
else if( aRenderParms[i].Name.compareToAscii( "NUp", 3 ) == 0 )
{
setValue( aRenderParms[i].Name, aRenderParms[i].Value );
}
}
}
catch( lang::IllegalArgumentException& )
{
// the first renderer should always be available for the UI options,
// but catch the exception to be safe
}
}
// set some job parameters
setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsApi" ) ), makeAny( i_bApi ) );
setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDirect" ) ), makeAny( i_bDirect ) );
setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrinter" ) ), makeAny( sal_True ) );
setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "View" ) ), i_rViewProp );
}
void SfxPrinterController::Notify( SfxBroadcaster& , const SfxHint& rHint )
{
if ( rHint.IsA(TYPE(SfxSimpleHint)) )
{
if ( ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
{
EndListening(*mpViewShell);
EndListening(*mpObjectShell);
mpViewShell = 0;
mpObjectShell = 0;
}
}
}
SfxPrinterController::~SfxPrinterController()
{
}
const Any& SfxPrinterController::getSelectionObject() const
{
const beans::PropertyValue* pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintSelectionOnly" ) ) );
if( pVal )
{
sal_Bool bSel = sal_False;
pVal->Value >>= bSel;
return bSel ? maSelection : maCompleteSelection;
}
sal_Int32 nChoice = 0;
pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ) );
if( pVal )
pVal->Value >>= nChoice;
return (nChoice > 1) ? maSelection : maCompleteSelection;
}
Sequence< beans::PropertyValue > SfxPrinterController::getMergedOptions() const
{
boost::shared_ptr<Printer> pPrinter( getPrinter() );
if( pPrinter.get() != mpLastPrinter )
{
mpLastPrinter = pPrinter.get();
VCLXDevice* pXDevice = new VCLXDevice();
pXDevice->SetOutputDevice( mpLastPrinter );
mxDevice = Reference< awt::XDevice >( pXDevice );
}
Sequence< beans::PropertyValue > aRenderOptions( 1 );
aRenderOptions[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) );
aRenderOptions[ 0 ].Value <<= mxDevice;
aRenderOptions = getJobProperties( aRenderOptions );
return aRenderOptions;
}
int SfxPrinterController::getPageCount() const
{
int nPages = 0;
boost::shared_ptr<Printer> pPrinter( getPrinter() );
if( mxRenderable.is() && pPrinter )
{
Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions );
}
return nPages;
}
Sequence< beans::PropertyValue > SfxPrinterController::getPageParameters( int i_nPage ) const
{
boost::shared_ptr<Printer> pPrinter( getPrinter() );
Sequence< beans::PropertyValue > aResult;
if( mxRenderable.is() && pPrinter )
{
Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
try
{
aResult = mxRenderable->getRenderer( i_nPage, getSelectionObject(), aJobOptions );
}
catch( lang::IllegalArgumentException& )
{
}
}
return aResult;
}
void SfxPrinterController::printPage( int i_nPage ) const
{
boost::shared_ptr<Printer> pPrinter( getPrinter() );
if( mxRenderable.is() && pPrinter )
{
Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
try
{
mxRenderable->render( i_nPage, getSelectionObject(), aJobOptions );
}
catch( lang::IllegalArgumentException& )
{
// don't care enough about nonexistant page here
// to provoke a crash
}
}
}
void SfxPrinterController::jobStarted()
{
if ( mpObjectShell )
{
m_bOrigStatus = mpObjectShell->IsEnableSetModified();
// check configuration: shall update of printing information in DocInfo set the document to "modified"?
if ( m_bOrigStatus && !SvtPrintWarningOptions().IsModifyDocumentOnPrintingAllowed() )
{
mpObjectShell->EnableSetModified( sal_False );
m_bNeedsChange = sal_True;
}
// refresh document info
uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
m_aLastPrintedBy = xDocProps->getPrintedBy();
m_aLastPrinted = xDocProps->getPrintDate();
xDocProps->setPrintedBy( mpObjectShell->IsUseUserData()
? ::rtl::OUString( SvtUserOptions().GetFullName() )
: ::rtl::OUString() );
::DateTime now;
xDocProps->setPrintDate( util::DateTime(
now.Get100Sec(), now.GetSec(), now.GetMin(), now.GetHour(),
now.GetDay(), now.GetMonth(), now.GetYear() ) );
uno::Sequence < beans::PropertyValue > aOpts;
aOpts = getJobProperties( aOpts );
uno::Reference< frame::XController2 > xController;
if ( mpViewShell )
xController.set( mpViewShell->GetController(), uno::UNO_QUERY );
mpObjectShell->Broadcast( SfxPrintingHint(
view::PrintableState_JOB_STARTED, aOpts, mpObjectShell, xController ) );
}
}
void SfxPrinterController::jobFinished( com::sun::star::view::PrintableState nState )
{
if ( mpObjectShell )
{
bool bCopyJobSetup = false;
mpObjectShell->Broadcast( SfxPrintingHint( nState ) );
switch ( nState )
{
case view::PrintableState_JOB_FAILED :
{
// "real" problem (not simply printing cancelled by user)
String aMsg( SfxResId( STR_NOSTARTPRINTER ) );
if ( !m_bApi )
ErrorBox( mpViewShell->GetWindow(), WB_OK | WB_DEF_OK, aMsg ).Execute();
// intentionally no break
}
case view::PrintableState_JOB_ABORTED :
{
// printing not succesful, reset DocInfo
uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
xDocProps->setPrintedBy(m_aLastPrintedBy);
xDocProps->setPrintDate(m_aLastPrinted);
break;
}
case view::PrintableState_JOB_SPOOLED :
case view::PrintableState_JOB_COMPLETED :
{
SfxBindings& rBind = mpViewShell->GetViewFrame()->GetBindings();
rBind.Invalidate( SID_PRINTDOC );
rBind.Invalidate( SID_PRINTDOCDIRECT );
rBind.Invalidate( SID_SETUPPRINTER );
bCopyJobSetup = ! m_bTempPrinter;
break;
}
default:
break;
}
if( bCopyJobSetup && mpViewShell )
{
// #i114306#
// Note: this possibly creates a printer that gets immediately replaced
// by a new one. The reason for this is that otherwise we would not get
// the printer's SfxItemSet here to copy. Awkward, but at the moment there is no
// other way here to get the item set.
SfxPrinter* pDocPrt = mpViewShell->GetPrinter(sal_True);
if( pDocPrt )
{
if( pDocPrt->GetName() == getPrinter()->GetName() )
pDocPrt->SetJobSetup( getPrinter()->GetJobSetup() );
else
{
SfxPrinter* pNewPrt = new SfxPrinter( pDocPrt->GetOptions().Clone(), getPrinter()->GetName() );
pNewPrt->SetJobSetup( getPrinter()->GetJobSetup() );
mpViewShell->SetPrinter( pNewPrt, SFX_PRINTER_PRINTER | SFX_PRINTER_JOBSETUP );
}
}
}
if ( m_bNeedsChange )
mpObjectShell->EnableSetModified( m_bOrigStatus );
if ( mpViewShell )
{
mpViewShell->pImp->m_pPrinterController.reset();
}
}
}
//====================================================================
class SfxDialogExecutor_Impl
/* [Beschreibung]
Eine Instanz dieser Klasse wird f"ur die Laufzeit des Printer-Dialogs
erzeugt, um im dessen Click-Handler f"ur die Zus"atze den per
virtueller Methode von der abgeleiteten SfxViewShell erzeugten
Print-Options-Dialog zu erzeugen und die dort eingestellten Optionen
als SfxItemSet zu zwischenzuspeichern.
*/
{
private:
SfxViewShell* _pViewSh;
PrinterSetupDialog* _pSetupParent;
SfxItemSet* _pOptions;
sal_Bool _bModified;
sal_Bool _bHelpDisabled;
DECL_LINK( Execute, void * );
public:
SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog* pParent );
~SfxDialogExecutor_Impl() { delete _pOptions; }
Link GetLink() const { return LINK( this, SfxDialogExecutor_Impl, Execute); }
const SfxItemSet* GetOptions() const { return _pOptions; }
void DisableHelp() { _bHelpDisabled = sal_True; }
};
//--------------------------------------------------------------------
SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog* pParent ) :
_pViewSh ( pViewSh ),
_pSetupParent ( pParent ),
_pOptions ( NULL ),
_bModified ( sal_False ),
_bHelpDisabled ( sal_False )
{
}
//--------------------------------------------------------------------
IMPL_LINK( SfxDialogExecutor_Impl, Execute, void *, EMPTYARG )
{
// Options lokal merken
if ( !_pOptions )
{
DBG_ASSERT( _pSetupParent, "no dialog parent" );
if( _pSetupParent )
_pOptions = ( (SfxPrinter*)_pSetupParent->GetPrinter() )->GetOptions().Clone();
}
// Dialog ausf"uhren
SfxPrintOptionsDialog* pDlg = new SfxPrintOptionsDialog( static_cast<Window*>(_pSetupParent),
_pViewSh, _pOptions );
if ( _bHelpDisabled )
pDlg->DisableHelp();
if ( pDlg->Execute() == RET_OK )
{
delete _pOptions;
_pOptions = pDlg->GetOptions().Clone();
}
delete pDlg;
return 0;
}
//-------------------------------------------------------------------------
sal_Bool UseStandardPrinter_Impl( Window* /*pParent*/, SfxPrinter* pDocPrinter )
{
// Optionen abfragen, ob gewarnt werden soll (Doc uebersteuert App)
sal_Bool bWarn = sal_False;
const SfxItemSet *pDocOptions = &pDocPrinter->GetOptions();
if ( pDocOptions )
{
sal_uInt16 nWhich = pDocOptions->GetPool()->GetWhich(SID_PRINTER_NOTFOUND_WARN);
const SfxBoolItem* pBoolItem = NULL;
pDocPrinter->GetOptions().GetItemState( nWhich, sal_False, (const SfxPoolItem**) &pBoolItem );
if ( pBoolItem )
bWarn = pBoolItem->GetValue();
}
/*
// ggf. den User fragen
if ( bWarn )
{
// Geht nicht mehr ohne OrigJobSetup!
String aTmp( SfxResId( STR_PRINTER_NOTAVAIL ) );
QueryBox aBox( pParent, WB_OK_CANCEL | WB_DEF_OK, aTmp );
return RET_OK == aBox.Execute();
}
*/
// nicht gewarnt => einfach so den StandardDrucker nehmen
return sal_True;
}
//-------------------------------------------------------------------------
SfxPrinter* SfxViewShell::SetPrinter_Impl( SfxPrinter *pNewPrinter )
/* Interne Methode zum Setzen der Unterschiede von 'pNewPrinter' zum
aktuellen Printer. pNewPrinter wird entweder "ubernommen oder gel"oscht.
*/
{
// aktuellen Printer holen
SfxPrinter *pDocPrinter = GetPrinter();
// Printer-Options auswerten
bool bOriToDoc = false;
bool bSizeToDoc = false;
if ( &pDocPrinter->GetOptions() )
{
sal_uInt16 nWhich = GetPool().GetWhich(SID_PRINTER_CHANGESTODOC);
const SfxFlagItem *pFlagItem = 0;
pDocPrinter->GetOptions().GetItemState( nWhich, sal_False, (const SfxPoolItem**) &pFlagItem );
bOriToDoc = pFlagItem ? (pFlagItem->GetValue() & SFX_PRINTER_CHG_ORIENTATION) : sal_False;
bSizeToDoc = pFlagItem ? (pFlagItem->GetValue() & SFX_PRINTER_CHG_SIZE) : sal_False;
}
// vorheriges Format und Size feststellen
Orientation eOldOri = pDocPrinter->GetOrientation();
Size aOldPgSz = pDocPrinter->GetPaperSizePixel();
// neues Format und Size feststellen
Orientation eNewOri = pNewPrinter->GetOrientation();
Size aNewPgSz = pNewPrinter->GetPaperSizePixel();
// "Anderungen am Seitenformat feststellen
sal_Bool bOriChg = (eOldOri != eNewOri) && bOriToDoc;
sal_Bool bPgSzChg = ( aOldPgSz.Height() !=
( bOriChg ? aNewPgSz.Width() : aNewPgSz.Height() ) ||
aOldPgSz.Width() !=
( bOriChg ? aNewPgSz.Height() : aNewPgSz.Width() ) ) &&
bSizeToDoc;
// Message und Flags f"ur Seitenformat-"Anderung zusammenstellen
String aMsg;
sal_uInt16 nNewOpt=0;
if( bOriChg && bPgSzChg )
{
aMsg = String(SfxResId(STR_PRINT_NEWORISIZE));
nNewOpt = SFX_PRINTER_CHG_ORIENTATION | SFX_PRINTER_CHG_SIZE;
}
else if (bOriChg )
{
aMsg = String(SfxResId(STR_PRINT_NEWORI));
nNewOpt = SFX_PRINTER_CHG_ORIENTATION;
}
else if (bPgSzChg)
{
aMsg = String(SfxResId(STR_PRINT_NEWSIZE));
nNewOpt = SFX_PRINTER_CHG_SIZE;
}
// in dieser Variable sammeln, was sich so ge"aendert hat
sal_uInt16 nChangedFlags = 0;
// ggf. Nachfrage, ob Seitenformat vom Drucker "ubernommen werden soll
if ( ( bOriChg || bPgSzChg ) &&
RET_YES == QueryBox(0, WB_YES_NO | WB_DEF_OK, aMsg).Execute() )
// Flags mit "Anderungen f"ur <SetPrinter(SfxPrinter*)> mitpflegen
nChangedFlags |= nNewOpt;
// fuer den MAC sein "temporary of class String" im naechsten if()
String aTempPrtName = pNewPrinter->GetName();
String aDocPrtName = pDocPrinter->GetName();
// Wurde der Drucker gewechselt oder von Default auf Specific
// oder umgekehrt geaendert?
if ( (aTempPrtName != aDocPrtName) || (pDocPrinter->IsDefPrinter() != pNewPrinter->IsDefPrinter()) )
{
// neuen Printer "ubernehmen
// pNewPrinter->SetOrigJobSetup( pNewPrinter->GetJobSetup() );
nChangedFlags |= SFX_PRINTER_PRINTER|SFX_PRINTER_JOBSETUP;
pDocPrinter = pNewPrinter;
}
else
{
// Extra-Optionen vergleichen
if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
{
// Options haben sich geaendert
pDocPrinter->SetOptions( pNewPrinter->GetOptions() );
nChangedFlags |= SFX_PRINTER_OPTIONS;
}
// JobSetups vergleichen
JobSetup aNewJobSetup = pNewPrinter->GetJobSetup();
JobSetup aOldJobSetup = pDocPrinter->GetJobSetup();
if ( aNewJobSetup != aOldJobSetup )
{
// JobSetup hat sich geaendert (=> App mu\s neu formatieren)
// pDocPrinter->SetOrigJobSetup( aNewJobSetup );
nChangedFlags |= SFX_PRINTER_JOBSETUP;
}
// alten, ver"anderten Printer behalten
pDocPrinter->SetPrinterProps( pNewPrinter );
delete pNewPrinter;
}
if ( 0 != nChangedFlags )
// SetPrinter will delete the old printer if it changes
SetPrinter( pDocPrinter, nChangedFlags );
return pDocPrinter;
}
//-------------------------------------------------------------------------
// Unter WIN32 tritt leider das Problem auf, dass nichts gedruckt
// wird, wenn SID_PRINTDOCDIRECT auflaueft; bisher bekannte,
// einzige Abhilfe ist in diesem Fall das Abschalten der Optimierungen
// (KA 17.12.95)
#ifdef _MSC_VER
#pragma optimize ( "", off )
#endif
void SfxViewShell::ExecPrint( const uno::Sequence < beans::PropertyValue >& rProps, sal_Bool bIsAPI, sal_Bool bIsDirect )
{
// get the current selection; our controller should know it
Reference< frame::XController > xController( GetController() );
Reference< view::XSelectionSupplier > xSupplier( xController, UNO_QUERY );
Any aSelection;
if( xSupplier.is() )
aSelection = xSupplier->getSelection();
else
aSelection <<= GetObjectShell()->GetModel();
Any aComplete( makeAny( GetObjectShell()->GetModel() ) );
Any aViewProp( makeAny( xController ) );
boost::shared_ptr<Printer> aPrt;
const beans::PropertyValue* pVal = rProps.getConstArray();
for( sal_Int32 i = 0; i < rProps.getLength(); i++ )
{
if( pVal[i].Name.equalsAscii( "PrinterName" ) )
{
rtl::OUString aPrinterName;
pVal[i].Value >>= aPrinterName;
aPrt.reset( new Printer( aPrinterName ) );
break;
}
}
boost::shared_ptr<vcl::PrinterController> pController( new SfxPrinterController(
aPrt,
aComplete,
aSelection,
aViewProp,
GetRenderable(),
bIsAPI,
bIsDirect,
this,
rProps
) );
pImp->m_pPrinterController = pController;
SfxObjectShell *pObjShell = GetObjectShell();
pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "JobName" ) ),
makeAny( rtl::OUString( pObjShell->GetTitle(0) ) ) );
// FIXME: job setup
SfxPrinter* pDocPrt = GetPrinter(sal_False);
JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : GetJobSetup();
if( bIsDirect )
aJobSetup.SetValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) ),
String( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
Printer::PrintJob( pController, aJobSetup );
}
Printer* SfxViewShell::GetActivePrinter() const
{
return (pImp->m_pPrinterController)
? pImp->m_pPrinterController->getPrinter().get() : 0;
}
void SfxViewShell::ExecPrint_Impl( SfxRequest &rReq )
{
// sal_uInt16 nCopies=1;
sal_uInt16 nDialogRet = RET_CANCEL;
// sal_Bool bCollate=sal_False;
SfxPrinter* pPrinter = 0;
SfxDialogExecutor_Impl* pExecutor = 0;
bool bSilent = false;
sal_Bool bIsAPI = rReq.GetArgs() && rReq.GetArgs()->Count();
if ( bIsAPI )
{
SFX_REQUEST_ARG(rReq, pSilentItem, SfxBoolItem, SID_SILENT, sal_False);
bSilent = pSilentItem && pSilentItem->GetValue();
}
//FIXME: how to transport "bPrintOnHelp"?
// no help button in dialogs if called from the help window
// (pressing help button would exchange the current page inside the help document that is going to be printed!)
String aHelpFilterName( DEFINE_CONST_UNICODE("writer_web_HTML_help") );
SfxMedium* pMedium = GetViewFrame()->GetObjectShell()->GetMedium();
const SfxFilter* pFilter = pMedium ? pMedium->GetFilter() : NULL;
sal_Bool bPrintOnHelp = ( pFilter && pFilter->GetFilterName() == aHelpFilterName );
const sal_uInt16 nId = rReq.GetSlot();
switch( nId )
{
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case SID_PRINTDOC:
case SID_PRINTDOCDIRECT:
{
SfxObjectShell* pDoc = GetObjectShell();
// derived class may decide to abort this
if( !pDoc->QuerySlotExecutable( nId ) )
{
rReq.SetReturnValue( SfxBoolItem( 0, sal_False ) );
return;
}
bool bDetectHidden = ( !bSilent && pDoc );
if ( bDetectHidden && pDoc->QueryHiddenInformation( WhenPrinting, NULL ) != RET_YES )
break;
SFX_REQUEST_ARG(rReq, pSelectItem, SfxBoolItem, SID_SELECTION, sal_False);
sal_Bool bSelection = pSelectItem && pSelectItem->GetValue();
if( pSelectItem && rReq.GetArgs()->Count() == 1 )
bIsAPI = sal_False;
uno::Sequence < beans::PropertyValue > aProps;
if ( bIsAPI )
{
// supported properties:
// String PrinterName
// String FileName
// Int16 From
// Int16 To
// In16 Copies
// String RangeText
// bool Selection
// bool Asynchron
// bool Collate
// bool Silent
TransformItems( nId, *rReq.GetArgs(), aProps, GetInterface()->GetSlot(nId) );
for ( sal_Int32 nProp=0; nProp<aProps.getLength(); nProp++ )
{
if ( aProps[nProp].Name.equalsAscii("Copies") )
aProps[nProp]. Name = rtl::OUString::createFromAscii("CopyCount");
else if ( aProps[nProp].Name.equalsAscii("RangeText") )
aProps[nProp]. Name = rtl::OUString::createFromAscii("Pages");
if ( aProps[nProp].Name.equalsAscii("Asynchron") )
{
aProps[nProp]. Name = rtl::OUString::createFromAscii("Wait");
sal_Bool bAsynchron = sal_False;
aProps[nProp].Value >>= bAsynchron;
aProps[nProp].Value <<= (sal_Bool) (!bAsynchron);
}
if ( aProps[nProp].Name.equalsAscii("Silent") )
{
aProps[nProp]. Name = rtl::OUString::createFromAscii("MonitorVisible");
sal_Bool bPrintSilent = sal_False;
aProps[nProp].Value >>= bPrintSilent;
aProps[nProp].Value <<= (sal_Bool) (!bPrintSilent);
}
}
}
// HACK: writer sets the SID_SELECTION item when printing directly and expects
// to get only the selection document in that case (see getSelectionObject)
// however it also reacts to the PrintContent property. We need this distinction here, too,
// else one of the combinations print / print direct and selection / all will not work.
// it would be better if writer handled this internally
if( nId == SID_PRINTDOCDIRECT )
{
sal_Int32 nLen = aProps.getLength();
aProps.realloc( nLen + 1 );
aProps[nLen].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintSelectionOnly" ) );
aProps[nLen].Value = makeAny( bSelection );
}
ExecPrint( aProps, bIsAPI, (nId == SID_PRINTDOCDIRECT) );
// FIXME: Recording
rReq.Done();
break;
}
case SID_SETUPPRINTER :
case SID_PRINTER_NAME : // only for recorded macros
{
// get printer and printer settings from the document
SfxPrinter *pDocPrinter = GetPrinter(sal_True);
// look for printer in parameters
SFX_REQUEST_ARG( rReq, pPrinterItem, SfxStringItem, SID_PRINTER_NAME, sal_False );
if ( pPrinterItem )
{
// use PrinterName parameter to create a printer
pPrinter = new SfxPrinter( pDocPrinter->GetOptions().Clone(), ((const SfxStringItem*) pPrinterItem)->GetValue() );
// if printer is unknown, it can't be used - now printer from document will be used
if ( !pPrinter->IsOriginal() )
DELETEZ(pPrinter);
}
if ( SID_PRINTER_NAME == nId )
{
// just set a recorded printer name
if ( pPrinter )
SetPrinter( pPrinter, SFX_PRINTER_PRINTER );
break;
}
// no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
if ( !pPrinter )
// use default printer from document
pPrinter = pDocPrinter;
if( !pPrinter || !pPrinter->IsValid() )
{
// no valid printer either in ItemSet or at the document
if ( bSilent )
{
rReq.SetReturnValue(SfxBoolItem(0,sal_False));
break;
}
else
ErrorBox( NULL, WB_OK | WB_DEF_OK, String( SfxResId( STR_NODEFPRINTER ) ) ).Execute();
}
if ( !pPrinter->IsOriginal() && rReq.GetArgs() && !UseStandardPrinter_Impl( NULL, pPrinter ) )
{
// printer is not available, but standard printer should not be used
rReq.SetReturnValue(SfxBoolItem(0,sal_False));
break;
}
// FIXME: printer isn't used for printing anymore!
if( pPrinter->IsPrinting() )
{
// if printer is busy, abort printing
if ( !bSilent )
InfoBox( NULL, String( SfxResId( STR_ERROR_PRINTER_BUSY ) ) ).Execute();
rReq.SetReturnValue(SfxBoolItem(0,sal_False));
break;
}
// if no arguments are given, retrieve them from a dialog
if ( !bIsAPI )
{
// PrinterDialog needs a temporary printer
SfxPrinter* pDlgPrinter = pPrinter->Clone();
nDialogRet = 0;
// execute PrinterSetupDialog
PrinterSetupDialog* pPrintSetupDlg = new PrinterSetupDialog( GetWindow() );
if (pImp->m_bHasPrintOptions)
{
// additional controls for dialog
pExecutor = new SfxDialogExecutor_Impl( this, pPrintSetupDlg );
if ( bPrintOnHelp )
pExecutor->DisableHelp();
pPrintSetupDlg->SetOptionsHdl( pExecutor->GetLink() );
}
pPrintSetupDlg->SetPrinter( pDlgPrinter );
nDialogRet = pPrintSetupDlg->Execute();
if ( pExecutor && pExecutor->GetOptions() )
{
if ( nDialogRet == RET_OK )
// remark: have to be recorded if possible!
pDlgPrinter->SetOptions( *pExecutor->GetOptions() );
else
{
pPrinter->SetOptions( *pExecutor->GetOptions() );
SetPrinter( pPrinter, SFX_PRINTER_OPTIONS );
}
}
DELETEZ( pPrintSetupDlg );
// no recording of PrinterSetup except printer name (is printer dependent)
rReq.Ignore();
if ( nDialogRet == RET_OK )
{
if ( pPrinter->GetName() != pDlgPrinter->GetName() )
{
// user has changed the printer -> macro recording
SfxRequest aReq( GetViewFrame(), SID_PRINTER_NAME );
aReq.AppendItem( SfxStringItem( SID_PRINTER_NAME, pDlgPrinter->GetName() ) );
aReq.Done();
}
// take the changes made in the dialog
pPrinter = SetPrinter_Impl( pDlgPrinter );
// forget new printer, it was taken over (as pPrinter) or deleted
pDlgPrinter = NULL;
}
else
{
// PrinterDialog is used to transfer information on printing,
// so it will only be deleted here if dialog was cancelled
DELETEZ( pDlgPrinter );
rReq.Ignore();
if ( SID_PRINTDOC == nId )
rReq.SetReturnValue(SfxBoolItem(0,sal_False));
}
}
}
break;
}
}
// Optimierungen wieder einschalten
#ifdef _MSC_VER
#pragma optimize ( "", on )
#endif
//--------------------------------------------------------------------
sal_Bool SfxViewShell::IsPrinterLocked() const
{
return pImp->m_nPrinterLocks > 0;
}
//--------------------------------------------------------------------
void SfxViewShell::LockPrinter( sal_Bool bLock)
{
sal_Bool bChanged = sal_False;
if ( bLock )
{
bChanged = 1 == ++pImp->m_nPrinterLocks;
}
else
{
bChanged = 0 == --pImp->m_nPrinterLocks;
}
if ( bChanged )
{
Invalidate( SID_PRINTDOC );
Invalidate( SID_PRINTDOCDIRECT );
Invalidate( SID_SETUPPRINTER );
}
}
//--------------------------------------------------------------------
SfxPrinter* SfxViewShell::GetPrinter( sal_Bool /*bCreate*/ )
{
return 0;
}
//--------------------------------------------------------------------
sal_uInt16 SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, sal_uInt16 /*nDiffFlags*/, bool )
{
return 0;
}
//--------------------------------------------------------------------
SfxTabPage* SfxViewShell::CreatePrintOptionsPage
(
Window* /*pParent*/,
const SfxItemSet& /*rOptions*/
)
{
return 0;
}
JobSetup SfxViewShell::GetJobSetup() const
{
return JobSetup();
}