From 17f1adc78adf3b8b943dc36882855b901259d4c1 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Mon, 31 Oct 2011 20:07:00 +0100 Subject: [PATCH] rhbz#657394: crash closing document while printing - XRenderable implementation in SwXTextDocument and ScModelObj throw DisposedExceptions instead of RuntimeExceptions - SfxPrinterController catches DisposedException and aborts printing - vcl::PrinterController checks that the printing was not aborted --- sc/source/ui/unoobj/docuno.cxx | 15 ++++++++++++--- sfx2/source/view/viewprn.cxx | 23 ++++++++++++++++++++++- sw/source/ui/uno/unotxdoc.cxx | 15 ++++++++++++--- vcl/source/gdi/print3.cxx | 22 ++++++++++++++++++++++ 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 4d4d5880a2a2..7332edab9b24 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -934,7 +934,10 @@ sal_Int32 SAL_CALL ScModelObj::getRendererCount( const uno::Any& aSelection, { SolarMutexGuard aGuard; if (!pDocShell) - throw uno::RuntimeException(); + { + throw lang::DisposedException( ::rtl::OUString(), + static_cast< sheet::XSpreadsheetDocument* >(this) ); + } ScMarkData aMark; ScPrintSelectionStatus aStatus; @@ -982,7 +985,10 @@ uno::Sequence SAL_CALL ScModelObj::getRenderer( sal_Int32 { SolarMutexGuard aGuard; if (!pDocShell) - throw uno::RuntimeException(); + { + throw lang::DisposedException( ::rtl::OUString(), + static_cast< sheet::XSpreadsheetDocument* >(this) ); + } ScMarkData aMark; ScPrintSelectionStatus aStatus; @@ -1089,7 +1095,10 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec { SolarMutexGuard aGuard; if (!pDocShell) - throw uno::RuntimeException(); + { + throw lang::DisposedException( ::rtl::OUString(), + static_cast< sheet::XSpreadsheetDocument* >(this) ); + } ScMarkData aMark; ScPrintSelectionStatus aStatus; diff --git a/sfx2/source/view/viewprn.cxx b/sfx2/source/view/viewprn.cxx index 70c98d6a55bd..628c35686cc0 100644 --- a/sfx2/source/view/viewprn.cxx +++ b/sfx2/source/view/viewprn.cxx @@ -238,7 +238,16 @@ int SfxPrinterController::getPageCount() const if( mxRenderable.is() && pPrinter ) { Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() ); - nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions ); + try + { + nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions ); + } + catch (lang::DisposedException &) + { + OSL_TRACE("SfxPrinterController: document disposed while printing"); + const_cast(this)->setJobState( + view::PrintableState_JOB_ABORTED); + } } return nPages; } @@ -258,6 +267,12 @@ Sequence< beans::PropertyValue > SfxPrinterController::getPageParameters( int i_ catch( lang::IllegalArgumentException& ) { } + catch (lang::DisposedException &) + { + OSL_TRACE("SfxPrinterController: document disposed while printing"); + const_cast(this)->setJobState( + view::PrintableState_JOB_ABORTED); + } } return aResult; } @@ -277,6 +292,12 @@ void SfxPrinterController::printPage( int i_nPage ) const // don't care enough about nonexistant page here // to provoke a crash } + catch (lang::DisposedException &) + { + OSL_TRACE("SfxPrinterController: document disposed while printing"); + const_cast(this)->setJobState( + view::PrintableState_JOB_ABORTED); + } } } diff --git a/sw/source/ui/uno/unotxdoc.cxx b/sw/source/ui/uno/unotxdoc.cxx index 43f2400eabc5..c849fa7ab961 100644 --- a/sw/source/ui/uno/unotxdoc.cxx +++ b/sw/source/ui/uno/unotxdoc.cxx @@ -2469,7 +2469,10 @@ sal_Int32 SAL_CALL SwXTextDocument::getRendererCount( { SolarMutexGuard aGuard; if(!IsValid()) - throw RuntimeException(); + { + throw DisposedException( ::rtl::OUString(), + static_cast< XTextDocument* >(this) ); + } const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ); bool bIsSwSrcView = false; @@ -2633,7 +2636,10 @@ uno::Sequence< beans::PropertyValue > SAL_CALL SwXTextDocument::getRenderer( { SolarMutexGuard aGuard; if(!IsValid()) - throw RuntimeException(); + { + throw DisposedException( ::rtl::OUString(), + static_cast< XTextDocument* >(this) ); + } const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ); bool bIsSwSrcView = false; @@ -2840,7 +2846,10 @@ void SAL_CALL SwXTextDocument::render( { SolarMutexGuard aGuard; if(!IsValid()) - throw RuntimeException(); + { + throw DisposedException( ::rtl::OUString(), + static_cast< XTextDocument* >(this) ); + } // due to #110067# (document page count changes sometimes during // PDF export/printing) we can not check for the upper bound properly. diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx index 6365b20abb2d..c2b0e876b227 100644 --- a/vcl/source/gdi/print3.cxx +++ b/vcl/source/gdi/print3.cxx @@ -626,6 +626,10 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptrisProgressCanceled() ) { i_pController->abortJob(); + } + if (i_pController->getJobState() == + view::PrintableState_JOB_ABORTED) + { bAborted = true; } } @@ -865,6 +869,11 @@ PrinterController::PageSize PrinterController::getPageFile( int i_nUnfilteredPag Sequence< PropertyValue > aPageParm( getPageParametersProtected( i_nUnfilteredPage ) ); const MapMode aMapMode( MAP_100TH_MM ); + if (mpImplData->meJobState != view::PrintableState_JOB_STARTED) + { // rhbz#657394: check that we are still printing... + return PrinterController::PageSize(); + } + mpImplData->mpPrinter->Push(); mpImplData->mpPrinter->SetMapMode( aMapMode ); @@ -951,6 +960,10 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte rMPS.nTopMargin == 0 && rMPS.nBottomMargin == 0 ) { PrinterController::PageSize aPageSize = getPageFile( i_nFilteredPage, o_rMtf, i_bMayUseCache ); + if (mpImplData->meJobState != view::PrintableState_JOB_STARTED) + { // rhbz#657394: check that we are still printing... + return PrinterController::PageSize(); + } Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize, true ); mpImplData->mpPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); mpImplData->mpPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() ); @@ -996,6 +1009,10 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte o_rMtf.AddAction( new MetaMapModeAction( MapMode( MAP_100TH_MM ) ) ); int nDocPages = getPageCountProtected(); + if (mpImplData->meJobState != view::PrintableState_JOB_STARTED) + { // rhbz#657394: check that we are still printing... + return PrinterController::PageSize(); + } for( int nSubPage = 0; nSubPage < nSubPages; nSubPage++ ) { // map current sub page to real page @@ -1143,6 +1160,11 @@ void PrinterController::printFilteredPage( int i_nPage ) GDIMetaFile aPageFile; PrinterController::PageSize aPageSize = getFilteredPageFile( i_nPage, aPageFile ); + if (mpImplData->meJobState != view::PrintableState_JOB_STARTED) + { // rhbz#657394: check that we are still printing... + return; + } + if( mpImplData->mpProgress ) { // do nothing if printing is canceled