Kaydet (Commit) 0b71c735 authored tarafından Armin Le Grand's avatar Armin Le Grand

#119941# Avoid crash when chart is removed in Writer by keepintg it's storage and graphic stream.

Patch by: Clarence Guo, zhaoshzh
Review by: alg
Found by: Shan Zhu
üst ed3284ec
......@@ -127,10 +127,12 @@ public:
// move an embedded object from one container to another one
sal_Bool MoveEmbeddedObject( EmbeddedObjectContainer& rSrc, const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, ::rtl::OUString& );
// #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+
sal_Bool RemoveEmbeddedObject( const ::rtl::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 );
// remove an embedded object from the container and from the storage; if object can't be closed
sal_Bool RemoveEmbeddedObject( const ::rtl::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 );
//sal_Bool RemoveEmbeddedObject( const ::rtl::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 );
// 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 >& );
......
......@@ -950,13 +950,16 @@ sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( EmbeddedObjectContainer& r
return bRet;
}
sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose )
//sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose )
// #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+
sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::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;
}
......@@ -1014,7 +1017,9 @@ sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( const ::rtl::OUString& rNa
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 )" );
......@@ -1051,7 +1056,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?!
......@@ -1131,7 +1137,8 @@ sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < e
}
OSL_ENSURE( bFound, "Object not found for removal!" );
if ( xPersist.is() )
// if ( xPersist.is() )
if ( xPersist.is() && bKeepToTempStorage ) // #i119941
{
// remove replacement image (if there is one)
RemoveGraphicStream( aName );
......
......@@ -33,6 +33,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>
......@@ -357,7 +358,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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment