From d53e12c7a9c2d0a3b487303673c1fafd09f6593c Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Wed, 26 Sep 2012 12:43:29 +0200 Subject: rhbz#827695: sw: prevent crashes after incomplete print: If the last page is not printed for whatever reason, then SwXTextDocument's destructor will delete a SwViewOptionAdjust_Impl, which accesses the document's ViewShell, which has already been deleted at that point. Add a horrible kludge to not crash for now. Change-Id: I67fe37970d60782030b84f2badddd1e66ef3f9c6 --- sw/inc/printdata.hxx | 2 +- sw/inc/unotxdoc.hxx | 5 +++-- sw/source/core/view/printdata.cxx | 5 +++++ sw/source/ui/uno/unotxdoc.cxx | 26 ++++++++++++++++++-------- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/sw/inc/printdata.hxx b/sw/inc/printdata.hxx index 00e7fe544245..0f58d30d761f 100644 --- a/sw/inc/printdata.hxx +++ b/sw/inc/printdata.hxx @@ -42,7 +42,6 @@ class SwDoc; class SwDocShell; -class ViewShell; class _SetGetExpFlds; class SwViewOption; class OutputDevice; @@ -277,6 +276,7 @@ public: void ViewOptionAdjustStart( ViewShell &rSh, const SwViewOption &rViewOptions); void ViewOptionAdjust( SwPrintData const* const pPrtOptions ); void ViewOptionAdjustStop(); + void ViewOptionAdjustCrashPreventionKludge(); bool HasSwPrtOptions() const { return m_pPrtOptions != 0; } SwPrintData const* GetSwPrtOptions() const { return m_pPrtOptions.get(); } diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx index 443aa763a6eb..3182bd268156 100644 --- a/sw/inc/unotxdoc.hxx +++ b/sw/inc/unotxdoc.hxx @@ -579,7 +579,7 @@ public: -----------------------------------------------------------------------*/ class SwViewOptionAdjust_Impl { - ViewShell & m_rShell; + ViewShell * m_pShell; SwViewOption m_aOldViewOptions; public: @@ -587,7 +587,8 @@ public: ~SwViewOptionAdjust_Impl(); void AdjustViewOptions( SwPrintData const* const pPrtOptions ); bool checkShell( const ViewShell& rCompare ) const - { return &rCompare == &m_rShell; } + { return &rCompare == m_pShell; } + void DontTouchThatViewShellItSmellsFunny() { m_pShell = 0; } }; diff --git a/sw/source/core/view/printdata.cxx b/sw/source/core/view/printdata.cxx index 4e6d37f1cab1..99888555d2dd 100644 --- a/sw/source/core/view/printdata.cxx +++ b/sw/source/core/view/printdata.cxx @@ -131,6 +131,11 @@ void SwRenderData::ViewOptionAdjustStop() m_pViewOptionAdjust.reset(); } +void SwRenderData::ViewOptionAdjustCrashPreventionKludge() +{ + m_pViewOptionAdjust->DontTouchThatViewShellItSmellsFunny(); +} + void SwRenderData::MakeSwPrtOptions( SwDocShell const*const pDocShell, diff --git a/sw/source/ui/uno/unotxdoc.cxx b/sw/source/ui/uno/unotxdoc.cxx index 8bee384245dc..ef09ecf5a026 100644 --- a/sw/source/ui/uno/unotxdoc.cxx +++ b/sw/source/ui/uno/unotxdoc.cxx @@ -400,6 +400,13 @@ SwXTextDocument::~SwXTextDocument() xNumFmtAgg = 0; } delete m_pPrintUIOptions; + if (m_pRenderData && m_pRenderData->IsViewOptionAdjust()) + { // rhbz#827695: this can happen if the last page is not printed + // the ViewShell has been deleted already by SwView::~SwView + // FIXME: replace this awful implementation of XRenderable with + // something less insane that has its own view + m_pRenderData->ViewOptionAdjustCrashPreventionKludge(); + } delete m_pRenderData; } @@ -3852,14 +3859,17 @@ void SwXDocumentPropertyHelper::onChange() SwViewOptionAdjust_Impl::SwViewOptionAdjust_Impl( ViewShell& rSh, const SwViewOption &rViewOptions) - : m_rShell( rSh ) + : m_pShell(&rSh) , m_aOldViewOptions( rViewOptions ) { } SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl() { - m_rShell.ApplyViewOptions( m_aOldViewOptions ); + if (m_pShell) + { + m_pShell->ApplyViewOptions( m_aOldViewOptions ); + } } void @@ -3867,14 +3877,14 @@ SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData const*const pPrtOptions) { // to avoid unnecessary reformatting the view options related to the content // below should only change if necessary, that is if respective content is present - const bool bContainsHiddenChars = m_rShell.GetDoc()->ContainsHiddenChars(); - const SwFieldType* pFldType = m_rShell.GetDoc()->GetSysFldType( RES_HIDDENTXTFLD ); + const bool bContainsHiddenChars = m_pShell->GetDoc()->ContainsHiddenChars(); + const SwFieldType* pFldType = m_pShell->GetDoc()->GetSysFldType( RES_HIDDENTXTFLD ); const bool bContainsHiddenFields = pFldType && pFldType->GetDepends(); - pFldType = m_rShell.GetDoc()->GetSysFldType( RES_HIDDENPARAFLD ); + pFldType = m_pShell->GetDoc()->GetSysFldType( RES_HIDDENPARAFLD ); const bool bContainsHiddenParagraphs = pFldType && pFldType->GetDepends(); - pFldType = m_rShell.GetDoc()->GetSysFldType( RES_JUMPEDITFLD ); + pFldType = m_pShell->GetDoc()->GetSysFldType( RES_JUMPEDITFLD ); const bool bContainsPlaceHolders = pFldType && pFldType->GetDepends(); - const bool bContainsFields = m_rShell.IsAnyFieldInDoc(); + const bool bContainsFields = m_pShell->IsAnyFieldInDoc(); SwViewOption aRenderViewOptions( m_aOldViewOptions ); @@ -3914,7 +3924,7 @@ SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData const*const pPrtOptions) if (m_aOldViewOptions != aRenderViewOptions) // check if reformatting is necessary { aRenderViewOptions.SetPrinting( pPrtOptions != NULL ); - m_rShell.ApplyViewOptions( aRenderViewOptions ); + m_pShell->ApplyViewOptions( aRenderViewOptions ); } } -- cgit v1.2.3