/************************************************************** * * 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 #include #include "com/sun/star/view/XRenderable.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "viewimp.hxx" #include #include #include "sfx2/sfxresid.hxx" #include #include #include "sfxtypes.hxx" #include #include #include #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 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& 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& 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 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 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 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 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 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 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() ) ); // 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) 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 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(_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 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 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 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>= 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(); }