summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2012-06-21 14:25:25 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-05-15 10:12:59 +0100
commit1ba29be90f7141077f2d079d40dffc2efd4f1a2c (patch)
treefb14188199683ece6c3f95520ef9ee921dce74ae
parent9c82c2734553690b38fa47afb7e026b6e38787c4 (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.cxx15
-rw-r--r--include/comphelper/embeddedobjectcontainer.hxx5
-rw-r--r--sw/source/core/ole/ndole.cxx26
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.