diff options
author | Armin Le Grand <alg@apache.org> | 2012-06-21 14:25:25 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-05-15 10:12:59 +0100 |
commit | 1ba29be90f7141077f2d079d40dffc2efd4f1a2c (patch) | |
tree | fb14188199683ece6c3f95520ef9ee921dce74ae | |
parent | 9c82c2734553690b38fa47afb7e026b6e38787c4 (diff) |
Resolves: #i119941# Avoid crash when chart is removed in Writer...
by keeping it's storage and graphic stream.
Patch by: Clarence Guo, zhaoshzh
Review by: alg
Found by: Shan Zhu
(cherry picked from commit 0b71c735dc10202b26972cf91779954b6a96af9a)
Conflicts:
comphelper/inc/comphelper/embeddedobjectcontainer.hxx
comphelper/source/container/embeddedobjectcontainer.cxx
Change-Id: I6ec172644806309d0f06f8522eb8a2adb45899ed
-rw-r--r-- | comphelper/source/container/embeddedobjectcontainer.cxx | 15 | ||||
-rw-r--r-- | include/comphelper/embeddedobjectcontainer.hxx | 5 | ||||
-rw-r--r-- | sw/source/core/ole/ndole.cxx | 26 |
3 files changed, 38 insertions, 8 deletions
diff --git a/comphelper/source/container/embeddedobjectcontainer.cxx b/comphelper/source/container/embeddedobjectcontainer.cxx index 6acf6d800c94..99bccd07fea6 100644 --- a/comphelper/source/container/embeddedobjectcontainer.cxx +++ b/comphelper/source/container/embeddedobjectcontainer.cxx @@ -923,13 +923,15 @@ sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( EmbeddedObjectContainer& r return bRet; } -sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const OUString& rName, sal_Bool bClose ) +// #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+ +sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const OUString& rName, sal_Bool bClose, sal_Bool bKeepToTempStorage ) { RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Name )" ); uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( rName ); if ( xObj.is() ) - return RemoveEmbeddedObject( xObj, bClose ); + //return RemoveEmbeddedObject( xObj, bClose ); + return RemoveEmbeddedObject( xObj, bClose, bKeepToTempStorage ); else return sal_False; } @@ -987,7 +989,9 @@ sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( const OUString& rName, Emb return sal_False; } -sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose ) +//sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose ) +// #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+ +sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose, sal_Bool bKeepToTempStorage ) { RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Object )" ); @@ -1024,7 +1028,8 @@ sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < e // somebody still needs the object, so we must assign a temporary persistence try { - if ( xPersist.is() ) + // if ( xPersist.is() ) + if ( xPersist.is() && bKeepToTempStorage ) // #i119941 { /* //TODO/LATER: needs storage handling! Why not letting the object do it?! @@ -1105,7 +1110,7 @@ sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < e OSL_ENSURE( bFound, "Object not found for removal!" ); (void)bFound; - if ( xPersist.is() ) + if ( xPersist.is() && bKeepToTempStorage ) // #i119941# { // remove replacement image (if there is one) RemoveGraphicStream( aName ); diff --git a/include/comphelper/embeddedobjectcontainer.hxx b/include/comphelper/embeddedobjectcontainer.hxx index 0347e12ba2c2..f60506651fca 100644 --- a/include/comphelper/embeddedobjectcontainer.hxx +++ b/include/comphelper/embeddedobjectcontainer.hxx @@ -125,8 +125,9 @@ public: sal_Bool MoveEmbeddedObject( EmbeddedObjectContainer& rSrc, const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, OUString& ); // remove an embedded object from the container and from the storage; if object can't be closed - sal_Bool RemoveEmbeddedObject( const OUString& rName, sal_Bool bClose=sal_True ); - sal_Bool RemoveEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, sal_Bool bClose=sal_True ); + // #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+ + sal_Bool RemoveEmbeddedObject( const OUString& rName, sal_Bool bClose = sal_True, sal_Bool bKeepToTempStorage = sal_True ); + sal_Bool RemoveEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, sal_Bool bClose = sal_True, sal_Bool bKeepToTempStorage = sal_True ); // close and remove an embedded object from the container without removing it from the storage sal_Bool CloseEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& ); diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx index 46f7dd7754d8..1f74ff5aed50 100644 --- a/sw/source/core/ole/ndole.cxx +++ b/sw/source/core/ole/ndole.cxx @@ -27,6 +27,7 @@ #include <com/sun/star/util/XCloseable.hpp> #include <com/sun/star/util/XModifiable.hpp> #include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> // #i119941 #include <cppuhelper/implbase1.hxx> #include <cppuhelper/implbase2.hxx> @@ -339,7 +340,30 @@ sal_Bool SwOLENode::SavePersistentData() if ( xChild.is() ) xChild->setParent( 0 ); - pCnt->RemoveEmbeddedObject( aOLEObj.aName, sal_False ); + // pCnt->RemoveEmbeddedObject( aOLEObj.aName, sal_False ); + /* #i119941: When cut or move the chart, SwUndoFlyBase::DelFly will call SaveSection to store the comtent to strorage. + In this step, chart filter functions will be called. And chart filter will call chart core functions to create the chart again. + Then chart core function will call the class ExplicitCategoryProvider to create data source. + In this step, when SW data source provider create the data source, it will create a new SwFlyFrm. + But later in SwUndoFlyBase::DelFly, it will clear anchor related attributes of SwFlyFrm. Then finally null pointer occur. + Resolution: + In pCnt->RemoveEmbeddedObject in SaveSection process of table chart, only remove the object from the object container, + without removing it's storage and graphic stream. The chart already removed from formatter.> */ + sal_Bool bChartWithInternalProvider = sal_False; + sal_Bool bKeepObjectToTempStorage = sal_True; + uno::Reference < embed::XEmbeddedObject > xIP = GetOLEObj().GetOleRef(); + if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) ) + { + uno::Reference< chart2::XChartDocument > xChart( xIP->getComponent(), UNO_QUERY ); + if ( xChart.is() && xChart->hasInternalDataProvider() ) + bChartWithInternalProvider = sal_True; + } + + if ( IsChart() && sChartTblName.Len() && !bChartWithInternalProvider ) + bKeepObjectToTempStorage = sal_False; + pCnt->RemoveEmbeddedObject( aOLEObj.aName, sal_False, bKeepObjectToTempStorage ); + // modify end + // TODO/LATER: aOLEObj.aName has no meaning here, since the undo container contains the object // by different name, in future it might makes sence that the name is transported here. |