You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by or...@apache.org on 2013/08/20 11:02:16 UTC

svn commit: r1515749 - in /openoffice/trunk/main/sw: inc/unotxdoc.hxx source/ui/app/docsh.cxx source/ui/uno/unotxdoc.cxx

Author: orw
Date: Tue Aug 20 09:02:15 2013
New Revision: 1515749

URL: http://svn.apache.org/r1515749
Log:
122868: PDF export - assure that rendering data are cleaned up by calling corresponding method in <SwDocShell::SaveCompleted(..)>
        This changes the fix for issue 121125 which triggers 122868


Modified:
    openoffice/trunk/main/sw/inc/unotxdoc.hxx
    openoffice/trunk/main/sw/source/ui/app/docsh.cxx
    openoffice/trunk/main/sw/source/ui/uno/unotxdoc.cxx

Modified: openoffice/trunk/main/sw/inc/unotxdoc.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/inc/unotxdoc.hxx?rev=1515749&r1=1515748&r2=1515749&view=diff
==============================================================================
--- openoffice/trunk/main/sw/inc/unotxdoc.hxx (original)
+++ openoffice/trunk/main/sw/inc/unotxdoc.hxx Tue Aug 20 09:02:15 2013
@@ -440,8 +440,8 @@ public:
 	SwXDrawPage*				GetDrawPage();
 	SwDocShell* 				GetDocShell() {return pDocShell;}
 
-    // #121125# react on ViewShell change
-    void ReactOnViewShellChange();
+    // #121125#, #122868# - clean up rendering data
+    void CleanUpRenderingData();
     
     void * SAL_CALL operator new( size_t ) throw();
 	void SAL_CALL operator delete( void * ) throw();

Modified: openoffice/trunk/main/sw/source/ui/app/docsh.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/ui/app/docsh.cxx?rev=1515749&r1=1515748&r2=1515749&view=diff
==============================================================================
--- openoffice/trunk/main/sw/source/ui/app/docsh.cxx (original)
+++ openoffice/trunk/main/sw/source/ui/app/docsh.cxx Tue Aug 20 09:02:15 2013
@@ -77,6 +77,7 @@
 #include <shellio.hxx> 		// I/O
 #include <docstyle.hxx>
 #include <doc.hxx>
+#include <unotxdoc.hxx>
 #include <IDocumentUndoRedo.hxx>
 #include <docstat.hxx>
 #include <pagedesc.hxx>
@@ -786,26 +787,26 @@ sal_Bool SwDocShell::ConvertTo( SfxMediu
 
 sal_Bool SwDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor  )
 {
-	RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722",  "SwDocShell::SaveCompleted" );
+    RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722",  "SwDocShell::SaveCompleted" );
     sal_Bool bRet = SfxObjectShell::SaveCompleted( xStor );
-	if( bRet )
-	{
-		// erst hier entscheiden, ob das Speichern geklappt hat oder nicht
-		if( IsModified() )
-			pDoc->SetModified();
-		else
-			pDoc->ResetModified();
-	}
+    if( bRet )
+    {
+        // erst hier entscheiden, ob das Speichern geklappt hat oder nicht
+        if( IsModified() )
+            pDoc->SetModified();
+        else
+            pDoc->ResetModified();
+    }
 
     if( pOLEChildList )
-	{
-		sal_Bool bResetModified = IsEnableSetModified();
-		if( bResetModified )
-			EnableSetModified( sal_False );
+    {
+        sal_Bool bResetModified = IsEnableSetModified();
+        if( bResetModified )
+            EnableSetModified( sal_False );
 
         uno::Sequence < rtl::OUString > aNames = pOLEChildList->GetObjectNames();
         for( sal_Int32 n = aNames.getLength(); n; n-- )
-		{
+        {
             if ( !pOLEChildList->MoveEmbeddedObject( aNames[n-1], GetEmbeddedObjectContainer() ) )
             {
                 DBG_ERROR( "Copying of objects didn't work!" );
@@ -814,13 +815,25 @@ sal_Bool SwDocShell::SaveCompleted( cons
             //SvPersist* pPersist = this;
             //SvInfoObjectRef aRef( pInfList->GetObject( --n ));
             //pPersist->Move( &aRef, aRef->GetStorageName() );
-		}
+        }
 
         DELETEZ( pOLEChildList );
-		if( bResetModified )
-			EnableSetModified( sal_True );
+        if( bResetModified )
+            EnableSetModified( sal_True );
     }
-	return bRet;
+
+    // #121125#, #122868#
+    // Clean up rendering data created by the usage of <XRenderable> interface
+    // of <SwXDocument> (e.g. export to PDF) and which is not cleaned up by
+    // "rendering the last page".
+    // This is needed to restore former <ViewOptions>. This is performed via
+    // a <ViewShell> reference hold by the rendering data. The rendering data
+    // also needs to loose the hold <ViewShell> reference. Otherwise, the application
+    // will crash on closing the document.
+    uno::Reference< text::XTextDocument >  xDoc(GetBaseModel(), uno::UNO_QUERY);
+    ((SwXTextDocument*)xDoc.get())->CleanUpRenderingData();
+
+    return bRet;
 }
 
 /*--------------------------------------------------------------------
@@ -1125,31 +1138,15 @@ SfxStyleSheetBasePool*	SwDocShell::GetSt
 }
 
 
-#include <unotxdoc.hxx>
-
 void SwDocShell::SetView(SwView* pVw)
 {
-    bool bChanged(false);
-
     if(0 != (pView = pVw))
     {
         pWrtShell = &pView->GetWrtShell();
-        bChanged = true;
     }
     else
     {
         pWrtShell = 0;
-        bChanged = true;
-    }
-
-    if(bChanged)
-    {
-        // #121125# SwXTextDocument may hold references to the ViewShell, so inform
-        // it about changes to allow to react on it. This happens e.g. when printing
-        // and/or PDF export (SwViewOptionAdjust_Impl holds a reference to the view
-        // and needs to be destroyed)
-        uno::Reference< text::XTextDocument >  xDoc(GetBaseModel(), uno::UNO_QUERY);
-        ((SwXTextDocument*)xDoc.get())->ReactOnViewShellChange();
     }
 }
 
@@ -1159,51 +1156,30 @@ void SwDocShell::PrepareReload()
 	::DelAllGrfCacheEntries( pDoc );
 }
 
-// --> OD 2006-11-07 #i59688#
 // linked graphics are now loaded on demand.
 // Thus, loading of linked graphics no longer needed and necessary for
 // the load of document being finished.
 void SwDocShell::LoadingFinished()
 {
-    // --> OD 2007-10-08 #i38810#
-    // Original fix fails after integration of cws xmlsec11:
     // interface <SfxObjectShell::EnableSetModified(..)> no longer works, because
     // <SfxObjectShell::FinishedLoading(..)> doesn't care about its status and
     // enables the document modification again.
     // Thus, manuell modify the document, if its modified and its links are updated
     // before <FinishedLoading(..)> is called.
     const bool bHasDocToStayModified( pDoc->IsModified() && pDoc->LinksUpdated() );
-//    // --> OD 2005-02-11 #i38810# - disable method <SetModified(..)>, if document
-//    // has stay in modified state, due to the update of its links during load.
-//    bool bResetEnableSetModified(false);
-//    if ( IsEnableSetModified() &&
-//         pDoc->IsModified() && pDoc->LinksUpdated() )
-//    {
-//        EnableSetModified( sal_False );
-//        bResetEnableSetModified = true;
-//    }
-    // <--
     FinishedLoading( SFX_LOADED_ALL );
-//    // --> OD 2005-02-11 #i38810#
-//    if ( bResetEnableSetModified )
-//    {
-//        EnableSetModified( sal_True );
-//    }
-//    // <--
-	SfxViewFrame* pVFrame = SfxViewFrame::GetFirst(this);
-	if(pVFrame)
-	{
-		SfxViewShell* pShell = pVFrame->GetViewShell();
-		if(PTR_CAST(SwSrcView, pShell))
-			((SwSrcView*)pShell)->Load(this);
-	}
+    SfxViewFrame* pVFrame = SfxViewFrame::GetFirst(this);
+    if(pVFrame)
+    {
+        SfxViewShell* pShell = pVFrame->GetViewShell();
+        if(PTR_CAST(SwSrcView, pShell))
+            ((SwSrcView*)pShell)->Load(this);
+    }
 
-    // --> OD 2007-10-08 #i38810#
     if ( bHasDocToStayModified && !pDoc->IsModified() )
     {
         pDoc->SetModified();
     }
-    // <--
 }
 
 // eine Uebertragung wird abgebrochen (wird aus dem SFX gerufen)

Modified: openoffice/trunk/main/sw/source/ui/uno/unotxdoc.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/ui/uno/unotxdoc.cxx?rev=1515749&r1=1515748&r2=1515749&view=diff
==============================================================================
--- openoffice/trunk/main/sw/source/ui/uno/unotxdoc.cxx (original)
+++ openoffice/trunk/main/sw/source/ui/uno/unotxdoc.cxx Tue Aug 20 09:02:15 2013
@@ -1510,9 +1510,9 @@ SwXDrawPage* SwXTextDocument::GetDrawPag
   -----------------------------------------------------------------------*/
 void SwXTextDocument::Invalidate()
 {
-	bObjectValid = sal_False;
-	if(xNumFmtAgg.is())
-	{
+    bObjectValid = sal_False;
+    if(xNumFmtAgg.is())
+    {
         const uno::Type& rTunnelType = ::getCppuType((Reference <XUnoTunnel>*)0);
         Any aNumTunnel = xNumFmtAgg->queryAggregation(rTunnelType);
         SvNumberFormatsSupplierObj* pNumFmt = 0;
@@ -1524,10 +1524,10 @@ void SwXTextDocument::Invalidate()
             pNumFmt->SetNumberFormatter(0);
         }
         DBG_ASSERT(pNumFmt, "No number formatter available");
-	}
-	InitNewDoc();
-	pDocShell = 0;
-	aRefreshCont.Disposing();
+    }
+    InitNewDoc();
+    pDocShell = 0;
+    aRefreshCont.Disposing();
 }
 /* -----------------------------13.07.00 15:59--------------------------------
 
@@ -2661,24 +2661,41 @@ sal_Int32 SAL_CALL SwXTextDocument::getR
     const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
     bool bIsSwSrcView = false;
     SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
-    
-    if (!bIsSwSrcView && !m_pRenderData)
-        m_pRenderData = new SwRenderData;
-    if (!m_pPrintUIOptions)
-        m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView );
-    bool bFormat = m_pPrintUIOptions->processPropertiesAndCheckFormat( rxOptions );
-    // const bool bIsSkipEmptyPages    = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
-    
+
     SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
     DBG_ASSERT( pDoc && pView, "doc or view shell missing!" );
-    if (!pDoc || !pView)
+    if ( pDoc == 0 || pView == 0 )
+    {
         return 0;
+    }
+
+    // clean up <RenderData> and <PrintUIOptions>
+    {
+        if ( m_pRenderData )
+        {
+            delete m_pRenderData;
+            m_pRenderData = 0;
+        }
+        if ( m_pPrintUIOptions )
+        {
+            delete m_pPrintUIOptions;
+            m_pPrintUIOptions = 0;
+        }
+    }
+
+    if ( !bIsSwSrcView )
+    {
+        m_pRenderData = new SwRenderData;
+    }
+    // new <PrintUIOptions>
+    m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView );
+    const bool bFormat = m_pPrintUIOptions->processPropertiesAndCheckFormat( rxOptions );
 
     // save current UI options from the print dialog for the next call to that dialog
     lcl_SavePrintUIOptionsToDocumentPrintData( *pDoc, *m_pPrintUIOptions, bIsPDFExport );
 
     sal_Int32 nRet = 0;
-    if (bIsSwSrcView)
+    if ( bIsSwSrcView )
     {
         SwSrcView *pSwSrcView = dynamic_cast< SwSrcView * >(pView);
         OutputDevice *pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
@@ -2711,7 +2728,7 @@ sal_Int32 SAL_CALL SwXTextDocument::getR
         if (!pViewShell || !pViewShell->GetLayout())
             return 0;
 
-        if (bFormat)
+        if ( bFormat )
         {
             // #i38289
             if( pViewShell->GetViewOptions()->getBrowseMode() )
@@ -2727,7 +2744,7 @@ sal_Int32 SAL_CALL SwXTextDocument::getR
             // We don't want that! Thus we disable updating of the view. 
             pViewShell->StartAction();
 
-            if (pSwView)
+            if ( pSwView )
             {
                 if (m_pRenderData && m_pRenderData->NeedNewViewOptionAdjust( *pViewShell ) )
                     m_pRenderData->ViewOptionAdjustStop();
@@ -2739,11 +2756,12 @@ sal_Int32 SAL_CALL SwXTextDocument::getR
             m_pRenderData->MakeSwPrtOptions( m_pRenderData->GetSwPrtOptionsRef(), pRenderDocShell,
                     m_pPrintUIOptions, m_pRenderData, bIsPDFExport );
                 
-            if (pSwView)
+            if ( pSwView )
             {
                 // PDF export should not make use of the SwPrtOptions
                 const SwPrintData *pPrtOptions = (bIsPDFExport)
-                    ? NULL : m_pRenderData->GetSwPrtOptions();
+                                                 ? NULL
+                                                 : m_pRenderData->GetSwPrtOptions();
                 m_pRenderData->ViewOptionAdjust( pPrtOptions );
             }
 
@@ -2758,7 +2776,7 @@ sal_Int32 SAL_CALL SwXTextDocument::getR
                 pRenderDocShell->EnableSetModified( sal_False );                
                 bStateChanged = true;
             }
-            
+
             // --> FME 2005-05-23 #122919# Force field update before PDF export:
             pViewShell->ViewShell::UpdateFlds(sal_True);
             // <--
@@ -2770,9 +2788,9 @@ sal_Int32 SAL_CALL SwXTextDocument::getR
             //TODO: check what exatly needs to be done and make just one function for that
             pViewShell->CalcLayout();
             pViewShell->CalcPagesForPrint( pViewShell->GetPageCount() );
-            
+
             pViewShell->SetPDFExportOption( sal_False );
-            
+
             // enable view again
             pViewShell->EndAction();
         }
@@ -2854,10 +2872,7 @@ uno::Sequence< beans::PropertyValue > SA
     if (!pDoc || !pView)
         return uno::Sequence< beans::PropertyValue >();
 
-    // due to #110067# (document page count changes sometimes during
-    // PDF export/printing) we can not check for the upper bound properly.
-    // Thus instead of throwing the exception we silently return.
-    if (0 > nRenderer)
+    if ( nRenderer < 0 || nRenderer >= SAL_MAX_UINT16 )
         throw IllegalArgumentException();
 
     // TODO/mba: we really need a generic way to get the ViewShell!
@@ -2884,15 +2899,10 @@ uno::Sequence< beans::PropertyValue > SA
     uno::Sequence< beans::PropertyValue > aRenderer;
     if (m_pRenderData)
     {
-        // --> TL, OD 2010-09-07 #i114210#
-        // determine the correct page number from the renderer index
-        // --> OD 2010-10-01 #i114875
-        // consider brochure print
-        const sal_uInt16 nPage = bPrintProspect
-                             ? nRenderer + 1
-                             : m_pRenderData->GetPagesToPrint()[ nRenderer ];
-        // <--
-        
+        const sal_Int32 nPage = bPrintProspect
+                                ? nRenderer + 1
+                                : m_pRenderData->GetPagesToPrint()[ nRenderer ];
+
         // get paper tray to use ... 
         sal_Int32 nPrinterPaperTray = -1;
         if (! bPrintPaperFromSetup)
@@ -2928,19 +2938,6 @@ uno::Sequence< beans::PropertyValue > SA
                 aTmpSize = pPrinter->LogicToLogic( aTmpSize,
                             pPrinter->GetMapMode(), MapMode( MAP_100TH_MM ));
                 aPageSize = awt::Size( aTmpSize.Width(), aTmpSize.Height() );
-                #if 0
-                // #i115048# it seems users didn't like getting double the formatted page size
-                // revert to "old" behavior scaling to the current paper size of the printer
-                if (bPrintProspect)
-                {
-                    // we just state what output size we would need
-                    // which may cause vcl to set that page size on the printer
-                    // (if available and not overriden by the user)
-                    aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
-                    aPreferredPageSize = awt::Size ( TWIP_TO_MM100( 2 * aTmpSize.Width() ),
-                                                     TWIP_TO_MM100( aTmpSize.Height() ));
-                }
-                #else
                 if( bPrintProspect )
                 {
                     // just switch to an appropriate portrait/landscape format
@@ -2953,12 +2950,13 @@ uno::Sequence< beans::PropertyValue > SA
                         aPreferredPageSize.Height = aPageSize.Width;
                     }
                 }
-                #endif
             }
         }
         else
         {
-            aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
+            ASSERT( nPage > 0 && nPage <= SAL_MAX_UINT16,
+                    "<SwXTextDocument::getRenderer(..)> - unexpected value for the page number, it does not fit into sal_uInt16." );
+            aTmpSize = pVwSh->GetPageSize( static_cast< sal_uInt16 >(nPage), bIsSkipEmptyPages );
             aPageSize = awt::Size ( TWIP_TO_MM100( aTmpSize.Width() ),
                                     TWIP_TO_MM100( aTmpSize.Height() ));
         }
@@ -2985,7 +2983,6 @@ uno::Sequence< beans::PropertyValue > SA
         }    
     }
 
-    // --> OD #i117783#
     if ( bApplyPagePrintSettingsFromXPagePrintable )
     {
         const SwPagePreViewPrtData* pPagePrintSettings =
@@ -3040,7 +3037,6 @@ uno::Sequence< beans::PropertyValue > SA
 
         bApplyPagePrintSettingsFromXPagePrintable = sal_False;
     }
-    // <--
 
     m_pPrintUIOptions->appendPrintUIOptions( aRenderer );
     
@@ -3086,9 +3082,6 @@ SfxViewShell * SwXTextDocument::GuessVie
     if (pView)
         rbIsSwSrcView = pSwSrcView != 0;
     return pView;
-//    return pSwView ? dynamic_cast< SfxViewShell * >(pSwView) : 
-//            (pSwSrcView ? dynamic_cast< SfxViewShell * >(pSwSrcView) :
-//                          dynamic_cast< SfxViewShell * >(pSwPagePreView) );
 }
 
 
@@ -3111,13 +3104,19 @@ void SAL_CALL SwXTextDocument::render(
     const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
     bool bIsSwSrcView = false;
     SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
-    
-    DBG_ASSERT( m_pRenderData, "data should have been created already in getRendererCount..." );
-    DBG_ASSERT( m_pPrintUIOptions, "data should have been created already in getRendererCount..." );
-    if (!bIsSwSrcView && !m_pRenderData)
+
+    // error handling - avoid crash
+    if ( !bIsSwSrcView && m_pRenderData == NULL )
+    {
+        DBG_ASSERT( false, "data should have been created already in getRendererCount..." );
         m_pRenderData = new SwRenderData;
-    if (!m_pPrintUIOptions)
+    }
+    if ( m_pPrintUIOptions == 0 )
+    {
+        DBG_ASSERT( false, "data should have been created already in getRendererCount..." );
         m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView );
+    }
+
     m_pPrintUIOptions->processProperties( rxOptions );
     const bool bPrintProspect   = m_pPrintUIOptions->getBoolValue( "PrintProspect", false );
     const bool bLastPage        = m_pPrintUIOptions->getBoolValue( "IsLastPage", sal_False );
@@ -3161,7 +3160,7 @@ void SAL_CALL SwXTextDocument::render(
                     else
                         pVwSh = ((SwPagePreView*)pView)->GetViewShell();
                 }
-        
+
                 // get output device to use
                 OutputDevice * pOut = lcl_GetOutputDevice( *m_pPrintUIOptions );
         
@@ -3170,11 +3169,11 @@ void SAL_CALL SwXTextDocument::render(
                     const rtl::OUString aPageRange  = m_pPrintUIOptions->getStringValue( "PageRange", OUString() );
                     const bool bFirstPage           = m_pPrintUIOptions->getBoolValue( "IsFirstPage", sal_False );
                     bool bIsSkipEmptyPages          = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
-        
+
                     DBG_ASSERT(( pView->IsA(aSwViewTypeId) &&  m_pRenderData->IsViewOptionAdjust())
                             || (!pView->IsA(aSwViewTypeId) && !m_pRenderData->IsViewOptionAdjust()), 
                             "SwView / SwViewOptionAdjust_Impl availability mismatch" );
-        
+
                     // since printing now also use the API for PDF export this option
                     // should be set for printing as well ...
                     pVwSh->SetPDFExportOption( sal_True );
@@ -3236,7 +3235,6 @@ void SAL_CALL SwXTextDocument::render(
                             SwDocShell *pRenderDocShell = pDoc->GetDocShell();
                             SfxItemSet *pSet = pRenderDocShell->GetMedium()->GetItemSet();
                             pSet->Put( SfxBoolItem( SID_HIDDEN, sal_False ) );
-
                         }
                     }
                 }
@@ -3504,19 +3502,24 @@ uno::Sequence< lang::Locale > SAL_CALL S
 	return aLanguages;
 }
 
-// #121125# react on ViewShell change; a reference to the ViewShell is 
-// held in SwViewOptionAdjust_Impl, thus needs to be cleaned up
-void SwXTextDocument::ReactOnViewShellChange()
+// #121125#, #122868#
+// method to assure clean up of the rendering data to restore view options
+// and to loose hold reference to the ViewShell in SwViewOptionAdjust_Impl.
+void SwXTextDocument::CleanUpRenderingData()
 {
-    if(m_pRenderData)
+    if( m_pRenderData != NULL )
     {
-        delete m_pRenderData; 
+        if ( m_pRenderData->HasPostItData() )
+        {
+            m_pRenderData->DeletePostItData();
+        }
+        delete m_pRenderData;
         m_pRenderData = NULL;
     }
 
-    if(m_pPrintUIOptions)
+    if( m_pPrintUIOptions != NULL )
     {
-        delete m_pPrintUIOptions; 
+        delete m_pPrintUIOptions;
         m_pPrintUIOptions = NULL;
     }
 }