initial work on an odc export

We can now export a chart to odc when we are in chart edit mode from
Calc. I need to add support for it to Writer and Impress as well.

We can already open these files but copy&paste from the opened file
fails. The next step is then to add a new menu entry
Insert->Object->Chart from file

Change-Id: I14d1702e79517e7319a1929de2be5501d375885d
diff --git a/filter/source/config/fragments/filters/chart8.xcu b/filter/source/config/fragments/filters/chart8.xcu
index 6b0a183..36c4e4a 100644
--- a/filter/source/config/fragments/filters/chart8.xcu
+++ b/filter/source/config/fragments/filters/chart8.xcu
@@ -16,7 +16,7 @@
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
    <node oor:name="chart8" oor:op="replace">
        <prop oor:name="Flags"><value>IMPORT EXPORT OWN DEFAULT NOTINFILEDIALOG NOTINCHOOSER PREFERRED ENCRYPTION</value></prop>
        <prop oor:name="Flags"><value>IMPORT EXPORT OWN DEFAULT PREFERRED ENCRYPTION</value></prop>
        <prop oor:name="UIComponent"/>
        <prop oor:name="FilterService"><value>com.sun.star.comp.chart2.XMLFilter</value></prop>
        <prop oor:name="UserData"><value>XML</value></prop>
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 0295e74..066e0b6 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -298,6 +298,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
	sc/source/filter/xml/xmlsubti \
	sc/source/filter/xml/xmltabi \
	sc/source/filter/xml/xmlwrap \
	sc/source/filter/chart/chart_imp \
	sc/source/ui/Accessibility/AccessibilityHints \
	sc/source/ui/Accessibility/AccessibleCell \
	sc/source/ui/Accessibility/AccessibleCellBase \
diff --git a/sc/inc/xmlwrap.hxx b/sc/inc/xmlwrap.hxx
index 42ab215..b4b505c 100644
--- a/sc/inc/xmlwrap.hxx
+++ b/sc/inc/xmlwrap.hxx
@@ -23,6 +23,7 @@
#include <tools/solar.h>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/frame/XModel.hpp>

class ScDocument;
class SfxMedium;
@@ -71,6 +72,18 @@ public:
    sal_Bool Export(sal_Bool bStylesOnly);
};

class ScXMLChartExportWrapper
{
public:
    ScXMLChartExportWrapper( com::sun::star::uno::Reference< com::sun::star::frame::XModel > xModel, SfxMedium& rMed );
    bool Export();

private:
    com::sun::star::uno::Reference< com::sun::star::frame::XModel > mxModel;
    ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > mxStorage;
    SfxMedium& mrMedium;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/app/drwtrans.cxx b/sc/source/ui/app/drwtrans.cxx
index c0fb8ab..1fdd9e3 100644
--- a/sc/source/ui/app/drwtrans.cxx
+++ b/sc/source/ui/app/drwtrans.cxx
@@ -578,7 +578,7 @@ sal_Bool ScDrawTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUse
                        ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );

                    // write document storage
                    pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
                    pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false, false );

                    // mba: no relative ULRs for clipboard!
                    SfxMedium aMedium( xWorkStore, String() );
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 103f64f..5325fac 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -446,7 +446,7 @@ sal_Bool ScTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObj
                    ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );

                // write document storage
                pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
                pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false, false );

                // mba: no relative ULRs for clipboard!
                SfxMedium aMedium( xWorkStore, String() );
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index c56d010..150c269 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -47,6 +47,16 @@
#include <com/sun/star/task/XJob.hpp>
#include <com/sun/star/ui/ModuleUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/table/XTableChartsSupplier.hpp>
#include <com/sun/star/table/XTableCharts.hpp>
#include <com/sun/star/table/XTableChart.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
#include <com/sun/star/frame/XStorable2.hpp>
#include <com/sun/star/frame/Desktop.hpp>

#include "scabstdlg.hxx"
#include <sot/formats.hxx>
@@ -493,6 +503,29 @@ sal_Bool ScDocShell::SaveXML( SfxMedium* pSaveMedium, const ::com::sun::star::un
    return bRet;
}

bool ScDocShell::SaveCurrentChart( SfxMedium& rMedium )
{
    bool bRet = false;

    try
    {

        uno::Reference< lang::XComponent > xCurrentComponent = frame::Desktop::create( comphelper::getProcessComponentContext() )->getCurrentComponent();

        uno::Reference< frame::XStorable2 > xStorable( xCurrentComponent, uno::UNO_QUERY_THROW );

        uno::Reference< frame::XModel > xChartDoc ( xCurrentComponent, uno::UNO_QUERY_THROW );

        ScXMLChartExportWrapper aExport( xChartDoc, rMedium );
        bRet = aExport.Export();
    }
    catch(...)
    {
        SAL_WARN("sc", "exception thrown while saving chart. Bug!!!");
    }
    return bRet;
}

sal_Bool ScDocShell::Load( SfxMedium& rMedium )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Load" );
@@ -1584,10 +1617,20 @@ sal_Bool ScDocShell::SaveAs( SfxMedium& rMedium )

    PrepareSaveGuard aPrepareGuard( *this);

    OUString aFltName = rMedium.GetFilter()->GetFilterName();
    bool bChartExport = aFltName.indexOf("chart8") != -1;

    //  wait cursor is handled with progress bar
    sal_Bool bRet = SfxObjectShell::SaveAs( rMedium );
    if( bRet )
    sal_Bool bRet = false;
    if(!bChartExport)
    {
        bRet = SfxObjectShell::SaveAs( rMedium );
        bRet = SaveXML( &rMedium, NULL );
    }
    else
    {
        bRet = SaveCurrentChart( rMedium );
    }

    return bRet;
}
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index 010ea82..55054f8 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -139,6 +139,8 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener
    SC_DLLPRIVATE sal_Bool            SaveXML( SfxMedium* pMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& );
    SC_DLLPRIVATE SCTAB         GetSaveTab();

    SC_DLLPRIVATE bool SaveCurrentChart( SfxMedium& rMedium );

    SC_DLLPRIVATE sal_uLong         DBaseImport( const String& rFullFileName, CharSet eCharSet,
                                             ScColWidthParam aColWidthParam[MAXCOLCOUNT], ScFlatBoolRowSegments& rRowHeightsRecalc );
    SC_DLLPRIVATE sal_uLong DBaseExport(
diff --git a/sfx2/inc/sfx2/objsh.hxx b/sfx2/inc/sfx2/objsh.hxx
index 73a1934..7e34147 100644
--- a/sfx2/inc/sfx2/objsh.hxx
+++ b/sfx2/inc/sfx2/objsh.hxx
@@ -569,10 +569,12 @@ public:
    virtual void    SetModified( sal_Bool bModified = sal_True );
    sal_Bool        IsModified();

    /**
     * @param bChart true if the file is a chart doc and FillClass should not be called
     */
    void            SetupStorage(
                        const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
                        sal_Int32 nVersion,
                        sal_Bool bTemplate ) const;
                        sal_Int32 nVersion, sal_Bool bTemplate, bool bChart = false ) const;

    ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetStorage();

diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx
index 727e817..092bf89 100644
--- a/sfx2/source/doc/guisaveas.cxx
+++ b/sfx2/source/doc/guisaveas.cxx
@@ -87,6 +87,10 @@
#include <svtools/sfxecode.hxx>
#include "../appl/app.hrc"

#include <boost/scoped_ptr.hpp>

#include <com/sun/star/frame/Desktop.hpp>

// flags that specify requested operation
#define EXPORT_REQUESTED            1
#define PDFEXPORT_REQUESTED         2
@@ -322,6 +326,29 @@ ModelData_Impl::ModelData_Impl( SfxStoringHelper& aOwner,
, m_bRecommendReadOnly( sal_False )
{
    CheckInteractionHandler();
    rtl::OUString sModuleName;
    try
    {
        uno::Reference< lang::XComponent > xCurrentComponent = frame::Desktop::create( comphelper::getProcessComponentContext() )->getCurrentComponent();
        sModuleName = aOwner.GetModuleManager()->identify(xCurrentComponent);
        if(sModuleName == "com.sun.star.chart2.ChartDocument")
        {
            // let us switch the model and set the xStorable and
            // XStorable2 to the old model.
            // This is an ugly hack because we have no SfxObjectShell for chart2 yet.
            // We need SfxObjectShell for the heavy work around ODF document creation
            // because chart2 only writes the basic stream out.
            // In future in might make sense to implement a full scale object shell in
            // chart2 and make chart2 an own program.
            m_xModel = uno::Reference< frame::XModel >(xCurrentComponent, uno::UNO_QUERY_THROW );
            m_xStorable = uno::Reference< frame::XStorable >(xModel, uno::UNO_QUERY_THROW );
            m_xStorable2 = uno::Reference< frame::XStorable2 >(xModel, uno::UNO_QUERY_THROW );
        }
    }
    catch(...)
    {
        // we don't want to pass on any errors;
    }
}

//-------------------------------------------------------------------------
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index e352b5a..15828e1 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -305,10 +305,38 @@ SvGlobalName SfxObjectShell::GetClassName() const
    return GetFactory().GetClassId();
}

namespace {

/**
 * Chart2 does not have an Object shell, so handle this here for now
 * If we ever implement a full scale object shell in chart2 move it there
 */
sal_uInt32 GetChartVersion( sal_Int32 nVersion, bool bTemplate )
{
    if( nVersion == SOFFICE_FILEFORMAT_60)
    {
        return SOT_FORMATSTR_ID_STARCHART_60;
    }
    else if( nVersion == SOFFICE_FILEFORMAT_8)
    {
        if (bTemplate)
        {
            SAL_WARN("sfx2", "no chart template support yet");
            return SOT_FORMATSTR_ID_STARCHART_8;
        }
        else
            return SOT_FORMATSTR_ID_STARCHART_8;
    }

    SAL_WARN("sfx2", "unsupported version");
    return 0;
}

}

//-------------------------------------------------------------------------
void SfxObjectShell::SetupStorage( const uno::Reference< embed::XStorage >& xStorage,
                                   sal_Int32 nVersion,
                                   sal_Bool bTemplate ) const
                                   sal_Int32 nVersion, sal_Bool bTemplate, bool bChart ) const
{
    uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );

@@ -318,7 +346,11 @@ void SfxObjectShell::SetupStorage( const uno::Reference< embed::XStorage >& xSto
        OUString aFullTypeName, aShortTypeName, aAppName;
        sal_uInt32 nClipFormat=0;

        FillClass( &aName, &nClipFormat, &aAppName, &aFullTypeName, &aShortTypeName, nVersion, bTemplate );
        if(!bChart)
            FillClass( &aName, &nClipFormat, &aAppName, &aFullTypeName, &aShortTypeName, nVersion, bTemplate );
        else
            nClipFormat = GetChartVersion(nVersion, bTemplate);

        if ( nClipFormat )
        {
            // basic doesn't have a ClipFormat
@@ -421,7 +453,7 @@ sal_Bool SfxObjectShell::GeneralInit_Impl( const uno::Reference< embed::XStorage
                    return sal_False;
                }

                SetupStorage( xStorage, SOFFICE_FILEFORMAT_CURRENT, sal_False );
                SetupStorage( xStorage, SOFFICE_FILEFORMAT_CURRENT, sal_False, false );
            }
        }
        catch ( uno::Exception& )
@@ -1874,7 +1906,7 @@ sal_Bool SfxObjectShell::DoSaveObjectAs( SfxMedium& rMedium, sal_Bool bCommit )
            if ( !(a>>=aMediaType) || aMediaType.isEmpty() )
            {
                OSL_FAIL( "The mediatype must be set already!\n" );
                SetupStorage( xNewStor, SOFFICE_FILEFORMAT_CURRENT, sal_False );
                SetupStorage( xNewStor, SOFFICE_FILEFORMAT_CURRENT, sal_False, false );
            }

            pImp->bIsSaving = sal_False;
@@ -3017,7 +3049,12 @@ sal_Bool SfxObjectShell::SaveAsOwnFormat( SfxMedium& rMedium )
        // OASIS templates have own mediatypes ( SO7 also actually, but it is to late to use them here )
        sal_Bool bTemplate = ( rMedium.GetFilter()->IsOwnTemplateFormat() && nVersion > SOFFICE_FILEFORMAT_60 );

        SetupStorage( xStorage, nVersion, bTemplate );
        const SfxFilter* pFilter = rMedium.GetFilter();
        bool bChart = false;
        if(pFilter->GetName() == OUString("chart8"))
            bChart = true;

        SetupStorage( xStorage, nVersion, bTemplate, bChart );
#ifndef DISABLE_SCRIPTING
        if ( HasBasic() )
        {
@@ -3043,7 +3080,7 @@ uno::Reference< embed::XStorage > SfxObjectShell::GetStorage()
            pImp->m_xDocStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
            OSL_ENSURE( pImp->m_xDocStorage.is(), "The method must either return storage or throw an exception!" );

            SetupStorage( pImp->m_xDocStorage, SOFFICE_FILEFORMAT_CURRENT, sal_False );
            SetupStorage( pImp->m_xDocStorage, SOFFICE_FILEFORMAT_CURRENT, sal_False, false );
            pImp->m_bCreateTempStor = sal_False;
            SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_STORAGECHANGED, GlobalEventConfig::GetEventName(STR_EVENT_STORAGECHANGED), this ) );
        }
diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
index 608214df..08e9b9f 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -3760,7 +3760,7 @@ void SAL_CALL SfxBaseModel::storeToStorage( const uno::Reference< XSTORAGE >& xS
    {
        // TODO/LATER: if the provided storage has some data inside the storing might fail, probably the storage must be truncated
        // TODO/LATER: is it possible to have a template here?
        m_pData->m_pObjectShell->SetupStorage( xStorage, nVersion, sal_False );
        m_pData->m_pObjectShell->SetupStorage( xStorage, nVersion, sal_False, false );

        // BaseURL is part of the ItemSet
        SfxMedium aMedium( xStorage, String(), &aSet );