Blob Blame History Raw
From f1d36a5eaaff6404fee0865947040e92026c7996 Mon Sep 17 00:00:00 2001
From: Kohei Yoshida <kohei.yoshida@collabora.com>
Date: Tue, 12 Aug 2014 21:24:17 -0400
Subject: [PATCH 098/137] bnc#822170: Let's not even try to export invalid
 chart objects.

If we do, at best, Excel will complain about the document needing
repair.  At worst Excel will skip some of the other valid drawing
objects from being loaded.

(cherry picked from commit 692878e3bb83c0fc104c5cca946c25ccf2d84ab2)

Conflicts:
	sc/source/filter/xcl97/xcl97rec.cxx
	sc/source/filter/excel/xeescher.cxx

Change-Id: If3794d0ae9d8b44b124020bb12b5369dfebc95ae
Reviewed-on: https://gerrit.libreoffice.org/10900
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Eike Rathke <erack@redhat.com>
---
 sc/source/filter/excel/xeescher.cxx |  5 ++-
 sc/source/filter/inc/xeescher.hxx   |  2 ++
 sc/source/filter/xcl97/xcl97rec.cxx | 68 ++++++++++++++++++++++++++++++++-----
 3 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx
index 241182c..bb3a2a5 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -1207,7 +1207,10 @@ void XclExpChartObj::WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS,
     pFS->endElementNS( XML_xdr, XML_xfrm );
 }
 
-// ============================================================================
+const css::uno::Reference<css::chart::XChartDocument>& XclExpChartObj::GetChartDoc() const
+{
+    return mxChartDoc;
+}
 
 XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos,
         const ScPostIt* pScNote, const OUString& rAddText ) :
diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx
index 4d7be77..cce4c66 100644
--- a/sc/source/filter/inc/xeescher.hxx
+++ b/sc/source/filter/inc/xeescher.hxx
@@ -324,6 +324,8 @@ public:
     virtual void        WriteChartObj( sax_fastparser::FSHelperPtr pDrawing, XclExpXmlStream& rStrm );
     void WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, const XShapeRef& rXShape, sal_Bool bFlipH = false, sal_Bool bFlipV = false, sal_Int32 nRotation = 0 );
 
+    const css::uno::Reference<css::chart::XChartDocument>& GetChartDoc() const;
+
 private:
     typedef boost::shared_ptr< XclExpChart > XclExpChartRef;
     XclExpChartRef      mxChart;        /// The chart itself (BOF/EOF substream data).
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx
index d61383a..24624cb 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -71,6 +71,8 @@
 #include <com/sun/star/sheet/XCellAddressable.hpp>
 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
 #include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
 #include <oox/token/tokens.hxx>
 #include <oox/export/shapes.hxx>
 #include <oox/export/utils.hxx>
@@ -162,6 +164,8 @@ void XclExpObjList::Save( XclExpStream& rStrm )
         pSolverContainer->Save( rStrm );
 }
 
+namespace {
+
 static bool IsVmlObject( const XclObj *rObj )
 {
     switch( rObj->GetObjType() )
@@ -186,11 +190,61 @@ static sal_Int32 GetVmlObjectCount( XclExpObjList& rList )
     return nNumVml;
 }
 
+bool IsValidObject( const XclObj& rObj )
+{
+    if (rObj.GetObjType() == EXC_OBJTYPE_CHART)
+    {
+        // Chart object.  Make sure it's a valid chart object.  We skip
+        // invalid chart objects from exporting to prevent Excel from
+        // complaining on load.
+
+        const XclExpChartObj& rChartObj = static_cast<const XclExpChartObj&>(rObj);
+        uno::Reference<chart2::XChartDocument> xChartDoc(rChartObj.GetChartDoc(), uno::UNO_QUERY);
+        if (!xChartDoc.is())
+            return false;
+
+        uno::Reference<chart2::XDiagram> xDiagram = xChartDoc->getFirstDiagram();
+        if (!xDiagram.is())
+            return false;
+
+        uno::Reference<chart2::XCoordinateSystemContainer> xCooSysContainer(xDiagram, uno::UNO_QUERY);
+        if (!xCooSysContainer.is())
+            return false;
+
+        uno::Sequence<uno::Reference<chart2::XCoordinateSystem> > xCooSysSeq = xCooSysContainer->getCoordinateSystems();
+        if (!xCooSysSeq.getLength())
+            return false;
+
+        for (sal_Int32 nCooSys = 0; nCooSys < xCooSysSeq.getLength(); ++nCooSys)
+        {
+            Reference<chart2::XChartTypeContainer> xChartTypeCont(xCooSysSeq[nCooSys], uno::UNO_QUERY);
+            if (!xChartTypeCont.is())
+                return false;
+
+            uno::Sequence<uno::Reference<chart2::XChartType> > xChartTypeSeq = xChartTypeCont->getChartTypes();
+            if (!xChartTypeSeq.getLength())
+                // No chart type.  Not good.
+                return false;
+        }
+    }
+
+    return true;
+}
 
 static void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nDrawingMLCount )
 {
-    sal_Int32 nVmlObjects = GetVmlObjectCount( rList );
-    if( (rList.size() - nVmlObjects) == 0 )
+    std::vector<XclObj*> aList;
+    aList.reserve(rList.size());
+    std::vector<XclObj*>::iterator it = rList.begin(), itEnd = rList.end();
+    for (; it != itEnd; ++it)
+    {
+        if (IsVmlObject(*it) || !IsValidObject(**it))
+            continue;
+
+        aList.push_back(*it);
+    }
+
+    if (aList.empty())
         return;
 
     sal_Int32 nDrawing = ++nDrawingMLCount;
@@ -214,13 +268,8 @@ static void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm,
             FSNS( XML_xmlns, XML_r ),   "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
             FSEND );
 
-    std::vector<XclObj*>::iterator pIter;
-    for ( pIter = rList.begin(); pIter != rList.end(); ++pIter )
-    {
-        if( IsVmlObject( *pIter ) )
-            continue;
-        (*pIter)->SaveXml( rStrm );
-    }
+    for (it = aList.begin(), itEnd = aList.end(); it != itEnd; ++it)
+        (*it)->SaveXml(rStrm);
 
     pDrawing->endElement( FSNS( XML_xdr, XML_wsDr ) );
 
@@ -267,6 +316,7 @@ static void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_In
     rStrm.PopStream();
 }
 
+}
 
 void XclExpObjList::SaveXml( XclExpXmlStream& rStrm )
 {
-- 
1.9.3