Author: orw Date: Tue Aug 20 10:57:22 2013 New Revision: 1515772 URL: http://svn.apache.org/r1515772 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
cherry-picked from trunk Modified: openoffice/branches/AOO401/ (props changed) openoffice/branches/AOO401/main/sw/inc/unotxdoc.hxx openoffice/branches/AOO401/main/sw/source/ui/app/docsh.cxx openoffice/branches/AOO401/main/sw/source/ui/uno/unotxdoc.cxx Propchange: openoffice/branches/AOO401/ ------------------------------------------------------------------------------ Merged /openoffice/trunk:r1515749,1515762 Modified: openoffice/branches/AOO401/main/sw/inc/unotxdoc.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO401/main/sw/inc/unotxdoc.hxx?rev=1515772&r1=1515771&r2=1515772&view=diff ============================================================================== --- openoffice/branches/AOO401/main/sw/inc/unotxdoc.hxx (original) +++ openoffice/branches/AOO401/main/sw/inc/unotxdoc.hxx Tue Aug 20 10:57:22 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/branches/AOO401/main/sw/source/ui/app/docsh.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO401/main/sw/source/ui/app/docsh.cxx?rev=1515772&r1=1515771&r2=1515772&view=diff ============================================================================== --- openoffice/branches/AOO401/main/sw/source/ui/app/docsh.cxx (original) +++ openoffice/branches/AOO401/main/sw/source/ui/app/docsh.cxx Tue Aug 20 10:57:22 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/branches/AOO401/main/sw/source/ui/uno/unotxdoc.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO401/main/sw/source/ui/uno/unotxdoc.cxx?rev=1515772&r1=1515771&r2=1515772&view=diff ============================================================================== --- openoffice/branches/AOO401/main/sw/source/ui/uno/unotxdoc.cxx (original) +++ openoffice/branches/AOO401/main/sw/source/ui/uno/unotxdoc.cxx Tue Aug 20 10:57:22 2013 @@ -618,8 +618,16 @@ void SwXTextDocument::dispose(void) thro -----------------------------------------------------------------------*/ void SwXTextDocument::close( sal_Bool bDeliverOwnership ) throw( util::CloseVetoException, RuntimeException ) { - if(IsValid() && m_pHiddenViewFrame) + if ( IsValid() && m_pHiddenViewFrame ) + { + ASSERT( false, "<SwXTextDocument::close(..)> - rendering data not cleaned up???" ); lcl_DisposeView( m_pHiddenViewFrame, pDocShell); + m_pHiddenViewFrame = 0; + // prevent crash described in #i108805 + SfxItemSet *pSet = pDocShell->GetMedium()->GetItemSet(); + pSet->Put( SfxBoolItem( SID_HIDDEN, sal_False ) ); + } + SfxBaseModel::close(bDeliverOwnership); } /*-- 18.12.98 13:12:25--------------------------------------------------- @@ -1510,9 +1518,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 +1532,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 +2669,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 +2736,7 @@ sal_Int32 SAL_CALL SwXTextDocument::getR if (!pViewShell || !pViewShell->GetLayout()) return 0; - if (bFormat) + if ( bFormat ) { // #i38289 if( pViewShell->GetViewOptions()->getBrowseMode() ) @@ -2727,7 +2752,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 +2764,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 +2784,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 +2796,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 +2880,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 +2907,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 +2946,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 +2958,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 +2991,6 @@ uno::Sequence< beans::PropertyValue > SA } } - // --> OD #i117783# if ( bApplyPagePrintSettingsFromXPagePrintable ) { const SwPagePreViewPrtData* pPagePrintSettings = @@ -3040,7 +3045,6 @@ uno::Sequence< beans::PropertyValue > SA bApplyPagePrintSettingsFromXPagePrintable = sal_False; } - // <-- m_pPrintUIOptions->appendPrintUIOptions( aRenderer ); @@ -3086,9 +3090,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 +3112,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 +3168,7 @@ void SAL_CALL SwXTextDocument::render( else pVwSh = ((SwPagePreView*)pView)->GetViewShell(); } - + // get output device to use OutputDevice * pOut = lcl_GetOutputDevice( *m_pPrintUIOptions ); @@ -3170,11 +3177,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 ); @@ -3202,8 +3209,6 @@ void SAL_CALL SwXTextDocument::render( else // normal printing and PDF export pVwSh->PrintOrPDFExport( pOut, rSwPrtOptions, nRenderer ); - // --> FME 2004-10-08 #i35176# - // // After printing the last page, we take care for the links coming // from the EditEngine. The links are generated during the painting // process, but the destinations are still missing. @@ -3212,41 +3217,17 @@ void SAL_CALL SwXTextDocument::render( { SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, sal_True ); } - // <-- - - pVwSh->SetPDFExportOption( sal_False ); - - // last page to be rendered? (not necessarily the last page of the document) - // -> do clean-up of data - if (bLastPage) - { - // #i96167# haggai: delete ViewOptionsAdjust here because it makes use - // of the shell, which might get destroyed in lcl_DisposeView! - if (m_pRenderData && m_pRenderData->IsViewOptionAdjust()) - m_pRenderData->ViewOptionAdjustStop(); - - if (m_pRenderData && m_pRenderData->HasPostItData()) - m_pRenderData->DeletePostItData(); - if (m_pHiddenViewFrame) - { - lcl_DisposeView( m_pHiddenViewFrame, pDocShell ); - m_pHiddenViewFrame = 0; - - // prevent crash described in #i108805 - SwDocShell *pRenderDocShell = pDoc->GetDocShell(); - SfxItemSet *pSet = pRenderDocShell->GetMedium()->GetItemSet(); - pSet->Put( SfxBoolItem( SID_HIDDEN, sal_False ) ); - } - } + pVwSh->SetPDFExportOption( sal_False ); } } } } - if( bLastPage ) + // last page to be rendered? (not necessarily the last page of the document) + // -> do clean-up of data + if ( bLastPage ) { - delete m_pRenderData; m_pRenderData = NULL; - delete m_pPrintUIOptions; m_pPrintUIOptions = NULL; + CleanUpRenderingData(); } } /* -----------------------------03.10.04 ------------------------------------- @@ -3504,21 +3485,35 @@ 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. +// also perform clean up for the still existing hidden frame for PDF export from Page Preview +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; } + + if ( IsValid() && m_pHiddenViewFrame ) + { + lcl_DisposeView( m_pHiddenViewFrame, pDocShell); + m_pHiddenViewFrame = 0; + SfxItemSet *pSet = pDocShell->GetMedium()->GetItemSet(); + pSet->Put( SfxBoolItem( SID_HIDDEN, sal_False ) ); + } } /* -----------------25.10.99 11:06-------------------