| /************************************************************** |
| * |
| * 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(); |
| } |
| |