From d0d8e4273335909fa1afebb34df82147e3111880 Mon Sep 17 00:00:00 2001
From: Michael Stahl <mstahl@redhat.com>
Date: Wed, 26 Sep 2012 12:43:29 +0200
Subject: [PATCH 14/14] 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
(cherry picked from commit d53e12c7a9c2d0a3b487303673c1fafd09f6593c)
Reviewed-on: https://gerrit.libreoffice.org/699
Reviewed-by: Noel Power <noel.power@suse.com>
Tested-by: Noel Power <noel.power@suse.com>
---
 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 02d56b8..a64ece9 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;
@@ -278,6 +277,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 42d646f..a460565 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -587,7 +587,7 @@ public:
   -----------------------------------------------------------------------*/
 class SwViewOptionAdjust_Impl
 {
-    ViewShell &    m_rShell;
+    ViewShell *     m_pShell;
     SwViewOption    m_aOldViewOptions;
 
 public:
@@ -595,7 +595,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 870ecbe..5c8e0ab 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 8fb89db..ea33ccd 100644
--- a/sw/source/ui/uno/unotxdoc.cxx
+++ b/sw/source/ui/uno/unotxdoc.cxx
@@ -404,6 +404,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;
 }
 
@@ -3864,14 +3871,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
@@ -3879,14 +3889,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 );
 
@@ -3926,7 +3936,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 );
     }
 }
 
-- 
1.7.10.4

