9830fd36db
- nanosecond precision - signed (allowed negative) year Also: assorted improvements / bugfixes in date/time handling code. Some factorisation of copy/pasted code. Change-Id: I761a1b0b8731c82f19a0c37acbcf43d3c06d6cd6
925 lines
34 KiB
C++
925 lines
34 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* 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 .
|
|
*/
|
|
|
|
|
|
#include <com/sun/star/document/XDocumentProperties.hpp>
|
|
#include <com/sun/star/view/PrintableState.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, SfxHint);
|
|
|
|
// -----------------------------------------------------------------------
|
|
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;
|
|
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 = OUString( "ExtraPrintUIOptions" );
|
|
aRenderOptions[1].Name = OUString( "View" );
|
|
aRenderOptions[1].Value = i_rViewProp;
|
|
aRenderOptions[2].Name = OUString( "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 == "ExtraPrintUIOptions" )
|
|
{
|
|
Sequence< beans::PropertyValue > aUIProps;
|
|
aRenderParms[i].Value >>= aUIProps;
|
|
setUIOptions( aUIProps );
|
|
}
|
|
else if( aRenderParms[i].Name == "NUp" )
|
|
{
|
|
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( OUString( "IsApi" ), makeAny( i_bApi ) );
|
|
setValue( OUString( "IsDirect" ), makeAny( i_bDirect ) );
|
|
setValue( OUString( "IsPrinter" ), makeAny( sal_True ) );
|
|
setValue( OUString( "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( OUString( "PrintSelectionOnly" ) );
|
|
if( pVal )
|
|
{
|
|
sal_Bool bSel = sal_False;
|
|
pVal->Value >>= bSel;
|
|
return bSel ? maSelection : maCompleteSelection;
|
|
}
|
|
|
|
sal_Int32 nChoice = 0;
|
|
pVal = getValue( OUString( "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 = OUString( "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() );
|
|
try
|
|
{
|
|
nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions );
|
|
}
|
|
catch (lang::DisposedException &)
|
|
{
|
|
OSL_TRACE("SfxPrinterController: document disposed while printing");
|
|
const_cast<SfxPrinterController*>(this)->setJobState(
|
|
view::PrintableState_JOB_ABORTED);
|
|
}
|
|
}
|
|
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& )
|
|
{
|
|
}
|
|
catch (lang::DisposedException &)
|
|
{
|
|
OSL_TRACE("SfxPrinterController: document disposed while printing");
|
|
const_cast<SfxPrinterController*>(this)->setJobState(
|
|
view::PrintableState_JOB_ABORTED);
|
|
}
|
|
}
|
|
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
|
|
}
|
|
catch (lang::DisposedException &)
|
|
{
|
|
OSL_TRACE("SfxPrinterController: document disposed while printing");
|
|
const_cast<SfxPrinterController*>(this)->setJobState(
|
|
view::PrintableState_JOB_ABORTED);
|
|
}
|
|
}
|
|
}
|
|
|
|
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()
|
|
? OUString( SvtUserOptions().GetFullName() )
|
|
: OUString() );
|
|
::DateTime now( ::DateTime::SYSTEM );
|
|
|
|
xDocProps->setPrintDate( util::DateTime(
|
|
now.GetNanoSec(), now.GetSec(), now.GetMin(), now.GetHour(),
|
|
now.GetDay(), now.GetMonth(), now.GetYear() ) );
|
|
|
|
SFX_APP()->NotifyEvent( SfxEventHint(SFX_EVENT_PRINTDOC, GlobalEventConfig::GetEventName( STR_EVENT_PRINTDOC ), mpObjectShell ) );
|
|
// FIXME: how to get all print options incl. AdditionalOptions easily?
|
|
uno::Sequence < beans::PropertyValue > aOpts;
|
|
mpObjectShell->Broadcast( SfxPrintingHint( view::PrintableState_JOB_STARTED, aOpts ) );
|
|
}
|
|
}
|
|
|
|
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)
|
|
OUString aMsg( SfxResId(STR_NOSTARTPRINTER).toString() );
|
|
if ( !m_bApi )
|
|
ErrorBox( mpViewShell->GetWindow(), WB_OK | WB_DEF_OK, aMsg ).Execute();
|
|
// intentionally no break
|
|
}
|
|
case view::PrintableState_JOB_ABORTED :
|
|
{
|
|
// printing not successful, 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
|
|
|
|
/* [Description]
|
|
|
|
An instance of this class is created for the life span of the
|
|
printer dialogue, to create in its click handler for the additions by the
|
|
virtual method of the derived SfxViewShell generated print options dialogue
|
|
and to cache the options set there as SfxItemSet.
|
|
*/
|
|
|
|
{
|
|
private:
|
|
SfxViewShell* _pViewSh;
|
|
PrinterSetupDialog* _pSetupParent;
|
|
SfxItemSet* _pOptions;
|
|
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 ),
|
|
_bHelpDisabled ( sal_False )
|
|
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
IMPL_LINK_NOARG(SfxDialogExecutor_Impl, Execute)
|
|
{
|
|
// Options noted locally
|
|
if ( !_pOptions )
|
|
{
|
|
DBG_ASSERT( _pSetupParent, "no dialog parent" );
|
|
if( _pSetupParent )
|
|
_pOptions = ( (SfxPrinter*)_pSetupParent->GetPrinter() )->GetOptions().Clone();
|
|
}
|
|
|
|
// Create Dialog
|
|
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;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
SfxPrinter* SfxViewShell::SetPrinter_Impl( SfxPrinter *pNewPrinter )
|
|
|
|
|
|
/* Internal method for setting the differences between 'pNewPrinter' to the
|
|
current printer. pNewPrinter is either taken over or deleted.
|
|
*/
|
|
|
|
{
|
|
// get current Printer
|
|
SfxPrinter *pDocPrinter = GetPrinter();
|
|
|
|
// Evaluate Printer Options
|
|
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;
|
|
}
|
|
|
|
// Determine the previous format and size
|
|
Orientation eOldOri = pDocPrinter->GetOrientation();
|
|
Size aOldPgSz = pDocPrinter->GetPaperSizePixel();
|
|
|
|
// Determine the new format and size
|
|
Orientation eNewOri = pNewPrinter->GetOrientation();
|
|
Size aNewPgSz = pNewPrinter->GetPaperSizePixel();
|
|
|
|
// Determine the changes in page format
|
|
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 and Flags for page format, summaries changes
|
|
OUString aMsg;
|
|
sal_uInt16 nNewOpt=0;
|
|
if( bOriChg && bPgSzChg )
|
|
{
|
|
aMsg = SfxResId(STR_PRINT_NEWORISIZE).toString();
|
|
nNewOpt = SFX_PRINTER_CHG_ORIENTATION | SFX_PRINTER_CHG_SIZE;
|
|
}
|
|
else if (bOriChg )
|
|
{
|
|
aMsg = SfxResId(STR_PRINT_NEWORI).toString();
|
|
nNewOpt = SFX_PRINTER_CHG_ORIENTATION;
|
|
}
|
|
else if (bPgSzChg)
|
|
{
|
|
aMsg = SfxResId(STR_PRINT_NEWSIZE).toString();
|
|
nNewOpt = SFX_PRINTER_CHG_SIZE;
|
|
}
|
|
|
|
// Summaries in this variable what has been changed.
|
|
sal_uInt16 nChangedFlags = 0;
|
|
|
|
// Ask if possible, if page format should be taken over from printer.
|
|
if ( ( bOriChg || bPgSzChg ) &&
|
|
RET_YES == QueryBox(0, WB_YES_NO | WB_DEF_OK, aMsg).Execute() )
|
|
{
|
|
// Flags wich changes for <SetPrinter(SfxPrinter*)> are maintained
|
|
nChangedFlags |= nNewOpt;
|
|
}
|
|
|
|
// For the MAC to have its "temporary of class String" in next if()
|
|
String aTempPrtName = pNewPrinter->GetName();
|
|
String aDocPrtName = pDocPrinter->GetName();
|
|
|
|
// Was the printer selection changed from Default to Specific
|
|
// or the other way around?
|
|
if ( (aTempPrtName != aDocPrtName) || (pDocPrinter->IsDefPrinter() != pNewPrinter->IsDefPrinter()) )
|
|
{
|
|
nChangedFlags |= SFX_PRINTER_PRINTER|SFX_PRINTER_JOBSETUP;
|
|
pDocPrinter = pNewPrinter;
|
|
}
|
|
else
|
|
{
|
|
// Compare extra options
|
|
if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
|
|
{
|
|
// Option have changed
|
|
pDocPrinter->SetOptions( pNewPrinter->GetOptions() );
|
|
nChangedFlags |= SFX_PRINTER_OPTIONS;
|
|
}
|
|
|
|
// Compare JobSetups
|
|
JobSetup aNewJobSetup = pNewPrinter->GetJobSetup();
|
|
JobSetup aOldJobSetup = pDocPrinter->GetJobSetup();
|
|
if ( aNewJobSetup != aOldJobSetup )
|
|
{
|
|
nChangedFlags |= SFX_PRINTER_JOBSETUP;
|
|
}
|
|
|
|
// Keep old changed Printer.
|
|
pDocPrinter->SetPrinterProps( pNewPrinter );
|
|
delete pNewPrinter;
|
|
}
|
|
|
|
if ( 0 != nChangedFlags )
|
|
// SetPrinter will delete the old printer if it changes
|
|
SetPrinter( pDocPrinter, nChangedFlags );
|
|
return pDocPrinter;
|
|
}
|
|
|
|
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 == "PrinterName" )
|
|
{
|
|
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( OUString( "JobName" ),
|
|
makeAny( OUString( pObjShell->GetTitle(0) ) ) );
|
|
|
|
// FIXME: job setup
|
|
SfxPrinter* pDocPrt = GetPrinter(sal_False);
|
|
JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : GetJobSetup();
|
|
if( bIsDirect )
|
|
aJobSetup.SetValue( String( "IsQuickJob" ),
|
|
String( "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 nDialogRet = RET_CANCEL;
|
|
SfxPrinter* pPrinter = 0;
|
|
SfxDialogExecutor_Impl* pExecutor = 0;
|
|
bool bSilent = false;
|
|
|
|
// does the function have been called by the user interface or by an API call
|
|
sal_Bool bIsAPI = rReq.GetArgs() && rReq.GetArgs()->Count();
|
|
if ( bIsAPI )
|
|
{
|
|
// the function have been called by the API
|
|
|
|
// Should it be visible on the user interface,
|
|
// should it launch popup dialogue ?
|
|
SFX_REQUEST_ARG(rReq, pSilentItem, SfxBoolItem, SID_SILENT, sal_False);
|
|
bSilent = pSilentItem && pSilentItem->GetValue();
|
|
}
|
|
|
|
// 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( "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: // display the printer selection and properties dialogue : File > Print…
|
|
case SID_PRINTDOCDIRECT: // Print the document directly, without displaying the dialogue
|
|
{
|
|
SfxObjectShell* pDoc = GetObjectShell();
|
|
|
|
// derived class may decide to abort this
|
|
if( pDoc == NULL || !pDoc->QuerySlotExecutable( nId ) )
|
|
{
|
|
rReq.SetReturnValue( SfxBoolItem( 0, sal_False ) );
|
|
return;
|
|
}
|
|
|
|
if ( !bSilent && pDoc->QueryHiddenInformation( WhenPrinting, NULL ) != RET_YES )
|
|
return;
|
|
|
|
// should we print only the selection or the whole document
|
|
SFX_REQUEST_ARG(rReq, pSelectItem, SfxBoolItem, SID_SELECTION, sal_False);
|
|
sal_Bool bSelection = ( pSelectItem != NULL && pSelectItem->GetValue() );
|
|
// detect non api call from writer ( that adds SID_SELECTION ) and reset bIsAPI
|
|
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
|
|
|
|
// the TransformItems function overwrite aProps
|
|
TransformItems( nId, *rReq.GetArgs(), aProps, GetInterface()->GetSlot(nId) );
|
|
|
|
for ( sal_Int32 nProp=0; nProp < aProps.getLength(); ++nProp )
|
|
{
|
|
if ( aProps[nProp].Name == "Copies" )
|
|
{
|
|
aProps[nProp]. Name = OUString("CopyCount");
|
|
}
|
|
else if ( aProps[nProp].Name == "RangeText" )
|
|
{
|
|
aProps[nProp]. Name = OUString("Pages");
|
|
}
|
|
else if ( aProps[nProp].Name == "Asynchron" )
|
|
{
|
|
aProps[nProp]. Name = OUString("Wait");
|
|
sal_Bool bAsynchron = sal_False;
|
|
aProps[nProp].Value >>= bAsynchron;
|
|
aProps[nProp].Value <<= (sal_Bool) (!bAsynchron);
|
|
}
|
|
else if ( aProps[nProp].Name == "Silent" )
|
|
{
|
|
aProps[nProp]. Name = OUString("MonitorVisible");
|
|
sal_Bool bPrintSilent = sal_False;
|
|
aProps[nProp].Value >>= bPrintSilent;
|
|
aProps[nProp].Value <<= (sal_Bool) (!bPrintSilent);
|
|
}
|
|
}
|
|
}
|
|
|
|
// we will add the "PrintSelectionOnly" or "HideHelpButton" properties
|
|
// we have to increase the capacity of aProps
|
|
sal_Int32 nLen = aProps.getLength();
|
|
aProps.realloc( nLen + 1 );
|
|
|
|
// 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 )
|
|
{
|
|
aProps[nLen].Name = OUString( "PrintSelectionOnly" );
|
|
aProps[nLen].Value = makeAny( bSelection );
|
|
}
|
|
else // if nId == SID_PRINTDOC ; nothing to do with the previous HACK
|
|
{
|
|
// should the printer selection and properties dialogue display an help button
|
|
aProps[nLen].Name = OUString( "HideHelpButton" );
|
|
aProps[nLen].Value = makeAny( bPrintOnHelp );
|
|
}
|
|
|
|
ExecPrint( aProps, bIsAPI, (nId == SID_PRINTDOCDIRECT) );
|
|
|
|
// FIXME: Recording
|
|
rReq.Done();
|
|
break;
|
|
}
|
|
case SID_SETUPPRINTER : // display the printer settings dialogue : File > Printer Settings…
|
|
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->IsKnown() )
|
|
DELETEZ(pPrinter);
|
|
}
|
|
|
|
if ( SID_PRINTER_NAME == nId )
|
|
{
|
|
// just set a recorded printer name
|
|
if ( pPrinter )
|
|
SetPrinter( pPrinter, SFX_PRINTER_PRINTER );
|
|
return;
|
|
}
|
|
|
|
// 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 )
|
|
ErrorBox( NULL, WB_OK | WB_DEF_OK, SfxResId(STR_NODEFPRINTER).toString() ).Execute();
|
|
|
|
rReq.SetReturnValue(SfxBoolItem(0,sal_False));
|
|
|
|
break;
|
|
}
|
|
|
|
// FIXME: printer isn't used for printing anymore!
|
|
if( pPrinter->IsPrinting() )
|
|
{
|
|
// if printer is busy, abort configuration
|
|
if ( !bSilent )
|
|
InfoBox( NULL, SfxResId(STR_ERROR_PRINTER_BUSY).toString() ).Execute();
|
|
rReq.SetReturnValue(SfxBoolItem(0,sal_False));
|
|
|
|
return;
|
|
}
|
|
|
|
// 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 && HasPrintOptionsPage())
|
|
{
|
|
// 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));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
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;
|
|
}
|
|
|
|
bool SfxViewShell::HasPrintOptionsPage() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
JobSetup SfxViewShell::GetJobSetup() const
|
|
{
|
|
return JobSetup();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|