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
diff --git a/comphelper/source/container/embeddedobjectcontainer.cxx b/comphelper/source/container/embeddedobjectcontainer.cxx
index 6acf6d80..99bccd0 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 0347e12..f6050665 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 46f7dd7..1f74ff5 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.