diff options
Diffstat (limited to 'sfx2/source/view/prnmon.cxx')
-rw-r--r-- | sfx2/source/view/prnmon.cxx | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/sfx2/source/view/prnmon.cxx b/sfx2/source/view/prnmon.cxx new file mode 100644 index 000000000000..a4e96ab1065e --- /dev/null +++ b/sfx2/source/view/prnmon.cxx @@ -0,0 +1,495 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <com/sun/star/view/PrintableState.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/util/XCloseBroadcaster.hpp> +#include <com/sun/star/util/XCloseListener.hpp> +#include <com/sun/star/util/CloseVetoException.hpp> +#include <vcl/fixed.hxx> +#include <vcl/msgbox.hxx> +#include <svtools/asynclink.hxx> + +#include <unotools/printwarningoptions.hxx> +#include <svl/eitem.hxx> + +#ifndef GCC +#endif + +#include <sfx2/prnmon.hxx> +#include <sfx2/viewsh.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/docfile.hxx> +#include "sfxtypes.hxx" +#include <sfx2/progress.hxx> +#include <sfx2/bindings.hxx> +#include "sfxresid.hxx" +#include <sfx2/event.hxx> +#include <sfx2/request.hxx> +#include <sfx2/app.hxx> + +#include "view.hrc" + +//------------------------------------------------------------------------ + +#define SFX_TITLE_MAXLEN_PRINTMONITOR 22 + +//------------------------------------------------------------------------ + +struct SfxPrintMonitor_Impl: public ModelessDialog +{ + + SfxPrintMonitor_Impl( Window *pParent, SfxViewShell *rpViewShell ); + virtual BOOL Close(); + + SfxViewShell* pViewShell; + FixedText aDocName; + FixedText aPrinting; + FixedText aPrinter; + FixedText aPrintInfo; + CancelButton aCancel; +}; + +//------------------------------------------------------------------------- + +struct SfxPrintProgress_Impl : public SfxListener +{ + SfxPrintMonitor_Impl* pMonitor; + SfxViewShell* pViewShell; + SfxPrinter* pPrinter; + SfxPrinter* pOldPrinter; + USHORT nLastPage; + BOOL bRunning; + BOOL bCancel; + BOOL bDeleteOnEndPrint; + BOOL bShow; + BOOL bCallbacks; + BOOL bOldEnablePrintFile; + BOOL bOldFlag; + BOOL bRestoreFlag; + BOOL bAborted; + svtools::AsynchronLink aDeleteLink; + Link aCancelHdl; + +private: + DECL_LINK( CancelHdl, Button * ); + DECL_STATIC_LINK( SfxPrintProgress_Impl, DeleteHdl, SfxPrintProgress * ); + +public: + SfxPrintProgress_Impl( SfxViewShell* pTheViewShell, SfxPrinter* pThePrinter ); + ~SfxPrintProgress_Impl(); + + void Delete( SfxPrintProgress* pAntiImpl ) { aDeleteLink.Call( pAntiImpl ); } + SfxViewShell* GetViewShell() const { return pViewShell; } + BOOL SetPage( USHORT nPage, const String &rPage ); + void CreateMonitor(); + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); +}; + +void SfxPrintProgress_Impl::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) +{ + SfxPrintingHint* pPrintHint = PTR_CAST( SfxPrintingHint, &rHint ); + if ( pPrintHint ) + { + if ( pPrintHint->GetWhich() == -2 ) + CancelHdl(0); + } +} + +//------------------------------------------------------------------------ + +SfxPrintMonitor_Impl::SfxPrintMonitor_Impl( Window* pParent, SfxViewShell* rpViewShell ) : + ModelessDialog( pParent, SfxResId( DLG_PRINTMONITOR ) ), + pViewShell ( rpViewShell ), + aDocName ( this, SfxResId( FT_DOCNAME ) ), + aPrinting ( this, SfxResId( FT_PRINTING ) ), + aPrinter ( this, SfxResId( FT_PRINTER ) ), + aPrintInfo ( this, SfxResId( FT_PRINTINFO ) ), + aCancel ( this, SfxResId( PB_CANCELPRNMON ) ) +{ + if( rpViewShell->GetPrinter()->GetCapabilities( PRINTER_CAPABILITIES_EXTERNALDIALOG ) != 0 ) + { + String aPrep( SfxResId( STR_FT_PREPARATION ) ); + aPrinting.SetText( aPrep ); + aPrinter.Show( FALSE ); + } + FreeResource(); +} + +//------------------------------------------------------------------------ + +IMPL_STATIC_LINK_NOINSTANCE( SfxPrintProgress_Impl, DeleteHdl, SfxPrintProgress*, pAntiImpl ) +{ + delete pAntiImpl; + return 0; +} + +void actualizePrintCancelState(CancelButton& rButton, const SfxObjectShell* pShell) +{ + sal_Bool bEnableCancelButton = sal_True; + if (pShell) + bEnableCancelButton = pShell->Stamp_GetPrintCancelState(); + + if (!bEnableCancelButton) + rButton.Disable(); + else + rButton.Enable(); +} + +//------------------------------------------------------------------------ + +SfxPrintProgress_Impl::SfxPrintProgress_Impl( SfxViewShell* pTheViewShell, + SfxPrinter* pThePrinter ) : + + pMonitor ( 0 ), + pViewShell ( pTheViewShell ), + pPrinter ( pThePrinter ), + pOldPrinter ( NULL ), + nLastPage ( 0 ), + bRunning ( TRUE ), + bCancel ( FALSE ), + bDeleteOnEndPrint ( FALSE ), + bShow ( FALSE ), + bCallbacks ( FALSE ), + bOldEnablePrintFile ( FALSE ), + bOldFlag ( TRUE ), + bRestoreFlag ( FALSE ), + bAborted ( FALSE ), + aDeleteLink ( STATIC_LINK( this, SfxPrintProgress_Impl, DeleteHdl ) ) +{ + StartListening( *pViewShell->GetObjectShell() ); +} + +void SfxPrintProgress_Impl::CreateMonitor() +{ + // mark monitor to been shown in first status indication + bShow = TRUE; + + if ( !pMonitor ) + { + Window* pParent = pViewShell->GetWindow(); + pMonitor = new SfxPrintMonitor_Impl( pParent, pViewShell ); + pMonitor->aDocName.SetText( pViewShell->GetObjectShell()->GetTitle( SFX_TITLE_MAXLEN_PRINTMONITOR ) ); + pMonitor->aPrinter.SetText( pViewShell->GetPrinter()->GetName() ); + + // Stampit enable/dsiable cancel button + actualizePrintCancelState( pMonitor->aCancel, pViewShell->GetObjectShell() ); + pMonitor->aCancel.SetClickHdl( LINK( this, SfxPrintProgress_Impl, CancelHdl ) ); + } +} + +//------------------------------------------------------------------------ + +SfxPrintProgress_Impl::~SfxPrintProgress_Impl() +{ +} + +//------------------------------------------------------------------------ + +BOOL SfxPrintProgress_Impl::SetPage( USHORT nPage, const String &rPage ) +{ + // wurde der Druckauftrag abgebrochen? + if ( bCancel || !pMonitor ) + return FALSE; + + // Stampit enable/dsiable cancel button + actualizePrintCancelState(pMonitor->aCancel, pViewShell->GetObjectShell()); + + nLastPage = nPage; + String aStrPrintInfo = String( SfxResId( STR_PAGE ) ); + if ( !rPage.Len() ) + aStrPrintInfo += String::CreateFromInt32( nLastPage ); + else + aStrPrintInfo += rPage; + pMonitor->aPrintInfo.SetText( aStrPrintInfo ); + pMonitor->Update(); + return TRUE; +} + +//------------------------------------------------------------------------ + +IMPL_LINK( SfxPrintProgress_Impl, CancelHdl, Button *, EMPTYARG ) +{ + if ( !pViewShell->GetPrinter()->IsJobActive() && pViewShell->GetPrinter()->IsPrinting() ) + // we are still in StartJob, cancelling now might lead to a crash + return 0; + + if ( pMonitor ) + pMonitor->Hide(); + + pViewShell->GetObjectShell()->Broadcast( SfxPrintingHint( com::sun::star::view::PrintableState_JOB_ABORTED, NULL, NULL ) ); + pViewShell->GetPrinter()->AbortJob(); + bCancel = TRUE; + + if ( aCancelHdl.IsSet() ) + aCancelHdl.Call( this ); + + bAborted = TRUE; + return 0; +} + +BOOL SfxPrintMonitor_Impl::Close() +{ + BOOL bAgree = pViewShell ? pViewShell->GetObjectShell()->Stamp_GetPrintCancelState() : TRUE; + if (!bAgree) + return FALSE; + else + return ModelessDialog::Close(); +} + +//-------------------------------------------------------------------- + +SfxPrintProgress::SfxPrintProgress( SfxViewShell* pViewSh, FASTBOOL bShow ) +: SfxProgress( pViewSh->GetViewFrame()->GetObjectShell(), + String(SfxResId(STR_PRINTING)), 1, FALSE ), + pImp( new SfxPrintProgress_Impl( pViewSh, pViewSh->GetPrinter() ) ) +{ + #if 0 + pImp->pPrinter->SetEndPrintHdl( LINK( this, SfxPrintProgress, EndPrintNotify ) ); + pImp->pPrinter->SetErrorHdl( LINK( this, SfxPrintProgress, PrintErrorNotify ) ); + pImp->pPrinter->SetStartPrintHdl( LINK( this, SfxPrintProgress, StartPrintNotify ) ); + pImp->bCallbacks = TRUE; + #endif + + SfxObjectShell* pDoc = pViewSh->GetObjectShell(); + SFX_ITEMSET_ARG( pDoc->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_HIDDEN, FALSE ); + if ( pItem && pItem->GetValue() ) + bShow = FALSE; + + if ( bShow ) + pImp->CreateMonitor(); + + Lock(); + if ( !SvtPrintWarningOptions().IsModifyDocumentOnPrintingAllowed() ) + { + pImp->bRestoreFlag = TRUE; + pImp->bOldFlag = pDoc->IsEnableSetModified(); + if ( pImp->bOldFlag ) + pDoc->EnableSetModified( FALSE ); + } +} + +//-------------------------------------------------------------------- + +SfxPrintProgress::~SfxPrintProgress() +{ + // k"onnte auch schon weg sein (in EndPrintNotify) + DELETEZ(pImp->pMonitor); + + // ggf. Callbacks entfermen + if ( pImp->bCallbacks ) + { + // pImp->pPrinter->SetEndPrintHdl( Link() ); + pImp->pPrinter->SetErrorHdl( Link() ); + pImp->bCallbacks = FALSE; + } + + // ggf. vorherigen Drucker wieder einsetzen + if ( pImp->pOldPrinter ) + pImp->pViewShell->SetPrinter( pImp->pOldPrinter, SFX_PRINTER_PRINTER ); + else + // ggf. vorherigen Print-To-File-Status zuruecksetzen + pImp->pViewShell->GetPrinter()->EnablePrintFile( pImp->bOldEnablePrintFile ); + + // EndPrint-Notification an Frame + //pImp->pViewShell->GetViewFrame()->GetFrame().Lock_Impl(FALSE); + pImp->EndListening( *(pImp->pViewShell->GetObjectShell()) ); + + // the following call might destroy the view or even the document + pImp->pViewShell->CheckOwnerShip_Impl(); + delete pImp; +} + +//-------------------------------------------------------------------- + +BOOL SfxPrintProgress::SetState( ULONG nValue, ULONG nNewRange ) +{ + if ( pImp->bShow ) + { + pImp->bShow = FALSE; + if ( pImp->pMonitor ) + { + pImp->pMonitor->Show(); + pImp->pMonitor->Update(); + } + } + + return pImp->SetPage( (USHORT)nValue, GetStateText_Impl() ) && + SfxProgress::SetState( nValue, nNewRange ); +} + +//-------------------------------------------------------------------- + +void SfxPrintProgress::SetText( const String& rText ) +{ + if ( pImp->pMonitor ) + { + pImp->pMonitor->SetText( rText ); + pImp->pMonitor->Update(); + } + SfxProgress::SetText( rText ); +} + +//------------------------------------------------------------------------ + +IMPL_LINK_INLINE_START( SfxPrintProgress, PrintErrorNotify, void *, EMPTYARG ) +{ + if ( pImp->pMonitor ) + pImp->pMonitor->Hide(); + // AbortJob calls EndPrint hdl, so do not delete pImp just now + BOOL bWasDeleteOnEndPrint = pImp->bDeleteOnEndPrint; + pImp->bDeleteOnEndPrint = FALSE; + pImp->pPrinter->AbortJob(); + InfoBox( pImp->GetViewShell()->GetWindow(), + String( SfxResId(STR_ERROR_PRINT) ) ).Execute(); + if ( pImp->bRestoreFlag && pImp->pViewShell->GetObjectShell()->IsEnableSetModified() != pImp->bOldFlag ) + pImp->pViewShell->GetObjectShell()->EnableSetModified( pImp->bOldFlag ); + pImp->GetViewShell()->GetObjectShell()->Broadcast( SfxPrintingHint( com::sun::star::view::PrintableState_JOB_FAILED, NULL, NULL ) ); + // now we can clean up like normally EndPrint hdl does + if( bWasDeleteOnEndPrint ) + { + DELETEZ(pImp->pMonitor); + delete this; + } + return 0; +} +IMPL_LINK_INLINE_END( SfxPrintProgress, PrintErrorNotify, void *, EMPTYARG ) + +//------------------------------------------------------------------------ + +IMPL_LINK( SfxPrintProgress, StartPrintNotify, void *, EMPTYARG ) +{ + SfxObjectShell *pObjShell = pImp->pViewShell->GetObjectShell(); + SFX_APP()->NotifyEvent(SfxEventHint(SFX_EVENT_PRINTDOC, GlobalEventConfig::GetEventName( STR_EVENT_PRINTDOC ), pObjShell)); + pObjShell->Broadcast( SfxPrintingHint( com::sun::star::view::PrintableState_JOB_STARTED, NULL, NULL ) ); + return 0; +} + +IMPL_LINK( SfxPrintProgress, EndPrintNotify, void *, EMPTYARG ) +{ + if ( pImp->pMonitor ) + pImp->pMonitor->Hide(); + + SfxViewShell* pViewShell = pImp->pViewShell; + + // Slots enablen + pViewShell->Invalidate( SID_PRINTDOC ); + pViewShell->Invalidate( SID_PRINTDOCDIRECT ); + pViewShell->Invalidate( SID_SETUPPRINTER ); + + // . . . falls der Printer im System umgestellt wurde, hier Aenderung + // nachziehen. + //! if( pMDI->IsPrinterChanged() ) pMDI->Changed( 0L ); + + // Callbacks rausnehmen + // pImp->pPrinter->SetEndPrintHdl( Link() ); + pImp->pPrinter->SetErrorHdl( Link() ); + pImp->bCallbacks = FALSE; + + // ggf. alten Printer wieder einsetzen + if ( pImp->pOldPrinter ) + { + // Fix #59613#: niemals den aktuellen Printer synchron abschiessen ! + // Da sowieso immer bDeleteOnEndPrint gesetzt wird, wird der der Drucker im + // dtor vom Printprogress ( dann aber asynchron !! ) zur"uckgesetzt. +/* + pImp->pViewShell->SetPrinter( pImp->pOldPrinter, SFX_PRINTER_PRINTER ); + pImp->pOldPrinter = 0; + pImp->pPrinter = 0; + */ + } + else + // ggf. vorherigen Print-To-File-Status zuruecksetzen + pViewShell->GetPrinter()->EnablePrintFile( pImp->bOldEnablePrintFile ); + + // it is possible that after printing the document or view is deleted (because the VieShell got the ownership) + // so first clean up + if ( pImp->bRestoreFlag && pViewShell->GetObjectShell()->IsEnableSetModified() != pImp->bOldFlag ) + pViewShell->GetObjectShell()->EnableSetModified( TRUE ); + + pViewShell->GetObjectShell()->Broadcast( SfxPrintingHint( com::sun::star::view::PrintableState_JOB_COMPLETED, NULL, NULL ) ); + if ( pImp->bDeleteOnEndPrint ) + { + DELETEZ(pImp->pMonitor); + delete this; + } + else + { + DBG_ASSERT( !pImp->pOldPrinter, "Unable to restore printer!" ); + pImp->bRunning = FALSE; + } + + return 0; +} + +//------------------------------------------------------------------------ + +void SfxPrintProgress::DeleteOnEndPrint() +{ + UnLock(); // jetzt schon, wg. Drucken im Thread +#ifndef WNT + // da das Drucken im 'Thread' unter Windows zu undefiniert ist bleibt der + // Print-Monitor dort stehen, auf den anderen Plattformen kann man dann + // weiterarbeiten, also kommt das Teil weg + DELETEZ( pImp->pMonitor ); +#endif + + pImp->bDeleteOnEndPrint = TRUE; + if ( !pImp->bRunning ) + delete this; +} + +//------------------------------------------------------------------------ + +void SfxPrintProgress::RestoreOnEndPrint( SfxPrinter *pOldPrinter, + BOOL bOldEnablePrintFile ) +{ + pImp->pOldPrinter = pOldPrinter; + pImp->bOldEnablePrintFile = bOldEnablePrintFile; +} + +//------------------------------------------------------------------------ + +void SfxPrintProgress::RestoreOnEndPrint( SfxPrinter *pOldPrinter ) +{ + RestoreOnEndPrint( pOldPrinter, FALSE ); +} + +//------------------------------------------------------------------------ + +void SfxPrintProgress::SetCancelHdl( const Link& aCancelHdl ) +{ + pImp->aCancelHdl = aCancelHdl; +} + +BOOL SfxPrintProgress::IsAborted() const +{ + return pImp->bAborted; +} |