Kaydet (Commit) 692878e3 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

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
üst 1e68aabd
...@@ -1190,6 +1190,11 @@ void XclExpChartObj::WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, ...@@ -1190,6 +1190,11 @@ void XclExpChartObj::WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS,
pFS->endElementNS( XML_xdr, XML_xfrm ); 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, XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos,
const ScPostIt* pScNote, const OUString& rAddText ) : const ScPostIt* pScNote, const OUString& rAddText ) :
XclExpRecord( EXC_ID_NOTE ), XclExpRecord( EXC_ID_NOTE ),
......
...@@ -303,6 +303,8 @@ public: ...@@ -303,6 +303,8 @@ public:
virtual void WriteChartObj( sax_fastparser::FSHelperPtr pDrawing, XclExpXmlStream& rStrm ); 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 ); void WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, const XShapeRef& rXShape, bool bFlipH = false, bool bFlipV = false, sal_Int32 nRotation = 0 );
const css::uno::Reference<css::chart::XChartDocument>& GetChartDoc() const;
private: private:
typedef boost::shared_ptr< XclExpChart > XclExpChartRef; typedef boost::shared_ptr< XclExpChart > XclExpChartRef;
XclExpChartRef mxChart; /// The chart itself (BOF/EOF substream data). XclExpChartRef mxChart; /// The chart itself (BOF/EOF substream data).
......
...@@ -71,6 +71,8 @@ ...@@ -71,6 +71,8 @@
#include <com/sun/star/sheet/XCellAddressable.hpp> #include <com/sun/star/sheet/XCellAddressable.hpp>
#include <com/sun/star/sheet/XCellRangeAddressable.hpp> #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#include <com/sun/star/embed/Aspects.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/token/tokens.hxx>
#include <oox/export/shapes.hxx> #include <oox/export/shapes.hxx>
#include <oox/export/utils.hxx> #include <oox/export/utils.hxx>
...@@ -163,6 +165,8 @@ void XclExpObjList::Save( XclExpStream& rStrm ) ...@@ -163,6 +165,8 @@ void XclExpObjList::Save( XclExpStream& rStrm )
pSolverContainer->Save( rStrm ); pSolverContainer->Save( rStrm );
} }
namespace {
static bool IsVmlObject( const XclObj *rObj ) static bool IsVmlObject( const XclObj *rObj )
{ {
switch( rObj->GetObjType() ) switch( rObj->GetObjType() )
...@@ -186,10 +190,61 @@ static sal_Int32 GetVmlObjectCount( XclExpObjList& rList ) ...@@ -186,10 +190,61 @@ static sal_Int32 GetVmlObjectCount( XclExpObjList& rList )
return nNumVml; 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 ) static void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nDrawingMLCount )
{ {
sal_Int32 nVmlObjects = GetVmlObjectCount( rList ); std::vector<XclObj*> aList;
if( (rList.size() - nVmlObjects) == 0 ) 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; return;
sal_Int32 nDrawing = ++nDrawingMLCount; sal_Int32 nDrawing = ++nDrawingMLCount;
...@@ -213,13 +268,8 @@ static void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, ...@@ -213,13 +268,8 @@ static void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm,
FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships", FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
FSEND ); FSEND );
std::vector<XclObj*>::iterator pIter; for (it = aList.begin(), itEnd = aList.end(); it != itEnd; ++it)
for ( pIter = rList.begin(); pIter != rList.end(); ++pIter ) (*it)->SaveXml(rStrm);
{
if( IsVmlObject( *pIter ) )
continue;
(*pIter)->SaveXml( rStrm );
}
pDrawing->endElement( FSNS( XML_xdr, XML_wsDr ) ); pDrawing->endElement( FSNS( XML_xdr, XML_wsDr ) );
...@@ -266,6 +316,8 @@ static void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_In ...@@ -266,6 +316,8 @@ static void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_In
rStrm.PopStream(); rStrm.PopStream();
} }
}
void XclExpObjList::SaveXml( XclExpXmlStream& rStrm ) void XclExpObjList::SaveXml( XclExpXmlStream& rStrm )
{ {
if( pSolverContainer ) if( pSolverContainer )
......
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