From 692878e3bb83c0fc104c5cca946c25ccf2d84ab2 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Tue, 12 Aug 2014 21:24:17 -0400 Subject: 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. Change-Id: If3794d0ae9d8b44b124020bb12b5369dfebc95ae --- sc/source/filter/excel/xeescher.cxx | 5 +++ sc/source/filter/inc/xeescher.hxx | 2 ++ sc/source/filter/xcl97/xcl97rec.cxx | 70 ++++++++++++++++++++++++++++++++----- 3 files changed, 68 insertions(+), 9 deletions(-) (limited to 'sc') diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx index 1223057cba01..f3cd939ff3d2 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -1190,6 +1190,11 @@ void XclExpChartObj::WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, pFS->endElementNS( XML_xdr, XML_xfrm ); } +const css::uno::Reference& XclExpChartObj::GetChartDoc() const +{ + return mxChartDoc; +} + XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos, const ScPostIt* pScNote, const OUString& rAddText ) : XclExpRecord( EXC_ID_NOTE ), diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx index 7171046ab0b7..1703630cf363 100644 --- a/sc/source/filter/inc/xeescher.hxx +++ b/sc/source/filter/inc/xeescher.hxx @@ -303,6 +303,8 @@ public: virtual void WriteChartObj( sax_fastparser::FSHelperPtr pDrawing, XclExpXmlStream& rStrm ); void WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, const XShapeRef& rXShape, bool bFlipH = false, bool bFlipV = false, sal_Int32 nRotation = 0 ); + const css::uno::Reference& 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 e28bccf69353..ba20be771724 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -71,6 +71,8 @@ #include #include #include +#include +#include #include #include #include @@ -163,6 +165,8 @@ void XclExpObjList::Save( XclExpStream& rStrm ) pSolverContainer->Save( rStrm ); } +namespace { + static bool IsVmlObject( const XclObj *rObj ) { switch( rObj->GetObjType() ) @@ -186,10 +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(rObj); + uno::Reference xChartDoc(rChartObj.GetChartDoc(), uno::UNO_QUERY); + if (!xChartDoc.is()) + return false; + + uno::Reference xDiagram = xChartDoc->getFirstDiagram(); + if (!xDiagram.is()) + return false; + + uno::Reference xCooSysContainer(xDiagram, uno::UNO_QUERY); + if (!xCooSysContainer.is()) + return false; + + uno::Sequence > xCooSysSeq = xCooSysContainer->getCoordinateSystems(); + if (!xCooSysSeq.getLength()) + return false; + + for (sal_Int32 nCooSys = 0; nCooSys < xCooSysSeq.getLength(); ++nCooSys) + { + Reference xChartTypeCont(xCooSysSeq[nCooSys], uno::UNO_QUERY); + if (!xChartTypeCont.is()) + return false; + + uno::Sequence > 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 aList; + aList.reserve(rList.size()); + std::vector::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; @@ -213,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::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 ) ); @@ -266,6 +316,8 @@ static void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_In rStrm.PopStream(); } +} + void XclExpObjList::SaveXml( XclExpXmlStream& rStrm ) { if( pSolverContainer ) -- cgit