diff options
author | Radek Doulik <rodo@novell.com> | 2012-11-19 18:20:24 +0100 |
---|---|---|
committer | Radek Doulik <rodo@novell.com> | 2012-11-19 18:24:41 +0100 |
commit | f3221085e3b84e0c84c1adca3d76ab4c293678ee (patch) | |
tree | 3c95a317d6df415d82e0c94824312cf56c344211 | |
parent | 787704495a615f1ea749ba80b0e218c3aae684d9 (diff) |
export embedded spreadsheet(s), fixes n#780830
Change-Id: Iee8328a695b554d97f6805b64b98706b9e3d7ab9
-rw-r--r-- | oox/inc/oox/export/drawingml.hxx | 5 | ||||
-rw-r--r-- | oox/inc/oox/export/shapes.hxx | 3 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 53 | ||||
-rw-r--r-- | oox/source/export/shapes.cxx | 162 |
4 files changed, 176 insertions, 47 deletions
diff --git a/oox/inc/oox/export/drawingml.hxx b/oox/inc/oox/export/drawingml.hxx index 5da2d6a44e7b..37d579bdd9a8 100644 --- a/oox/inc/oox/export/drawingml.hxx +++ b/oox/inc/oox/export/drawingml.hxx @@ -81,6 +81,9 @@ protected: rtl::OUString WriteImage( const rtl::OUString& rURL ); + const char* GetComponentDir(); + const char* GetRelationCompPrefix(); + public: DrawingML( ::sax_fastparser::FSHelperPtr pFS, ::oox::core::XmlFilterBase* pFB = NULL, DocumentType eDocumentType = DOCUMENT_PPTX ) : meDocumentType( eDocumentType ), mpFS( pFS ), mpFB( pFB ) {} void SetFS( ::sax_fastparser::FSHelperPtr pFS ) { mpFS = pFS; } @@ -104,7 +107,7 @@ public: void WriteStretch(); void WriteLinespacing( ::com::sun::star::style::LineSpacing& rLineSpacing ); - ::rtl::OUString WriteBlip( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, ::rtl::OUString& rURL ); + ::rtl::OUString WriteBlip( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, ::rtl::OUString& rURL, Graphic *pGraphic=NULL ); void WriteBlipMode( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); void WriteShapeTransformation( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > rXShape, diff --git a/oox/inc/oox/export/shapes.hxx b/oox/inc/oox/export/shapes.hxx index b75db6365819..5f83326ad6a7 100644 --- a/oox/inc/oox/export/shapes.hxx +++ b/oox/inc/oox/export/shapes.hxx @@ -42,6 +42,7 @@ namespace oox { namespace drawingml { class OOX_DLLPUBLIC ShapeExport : public DrawingML { private: + static int mnSpreadsheetCounter; struct ShapeCheck { bool operator()( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape> s1, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape> s2 ) const @@ -61,6 +62,8 @@ public: protected: sal_Int32 mnShapeIdMax, mnPictureIdMax; + void WriteGraphicObjectShapePart( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, Graphic *pGraphic=NULL ); + private: sal_Int32 mnXmlNamespace; Fraction maFraction; diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 11c5c0d8d3f6..efbb1de64a97 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -421,6 +421,30 @@ OUString DrawingML::WriteImage( const OUString& rURL ) return OUString(); } +const char* DrawingML::GetComponentDir() +{ + switch ( meDocumentType ) + { + case DOCUMENT_DOCX: return "word"; + case DOCUMENT_PPTX: return "ppt"; + case DOCUMENT_XLSX: return "xl"; + } + + return "unknown"; +} + +const char* DrawingML::GetRelationCompPrefix() +{ + switch ( meDocumentType ) + { + case DOCUMENT_DOCX: return ""; + case DOCUMENT_PPTX: + case DOCUMENT_XLSX: return "../"; + } + + return "unknown"; +} + OUString DrawingML::WriteImage( const Graphic& rGraphic ) { GfxLink aLink = rGraphic.GetLink (); @@ -482,16 +506,8 @@ OUString DrawingML::WriteImage( const Graphic& rGraphic ) } } - const char *pComponent = ""; - switch ( meDocumentType ) - { - case DOCUMENT_DOCX: pComponent = "word"; break; - case DOCUMENT_PPTX: pComponent = "ppt"; break; - case DOCUMENT_XLSX: pComponent = "xl"; break; - } - Reference< XOutputStream > xOutStream = mpFB->openFragmentStream( OUStringBuffer() - .appendAscii( pComponent ) + .appendAscii( GetComponentDir() ) .appendAscii( "/media/image" ) .append( (sal_Int32) mnImageCounter ) .appendAscii( pExtension ) @@ -500,22 +516,11 @@ OUString DrawingML::WriteImage( const Graphic& rGraphic ) xOutStream->writeBytes( Sequence< sal_Int8 >( (const sal_Int8*) aData, nDataSize ) ); xOutStream->closeOutput(); - const char *pImagePrefix = ""; - switch ( meDocumentType ) - { - case DOCUMENT_DOCX: - pImagePrefix = "media/image"; - break; - case DOCUMENT_PPTX: - case DOCUMENT_XLSX: - pImagePrefix = "../media/image"; - break; - } - sRelId = mpFB->addRelation( mpFS->getOutputStream(), US( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ), OUStringBuffer() - .appendAscii( pImagePrefix ) + .appendAscii( GetRelationCompPrefix() ) + .appendAscii( "media/image" ) .append( (sal_Int32) mnImageCounter ++ ) .appendAscii( pExtension ) .makeStringAndClear() ); @@ -523,9 +528,9 @@ OUString DrawingML::WriteImage( const Graphic& rGraphic ) return sRelId; } -OUString DrawingML::WriteBlip( Reference< XPropertySet > rXPropSet, OUString& rURL ) +OUString DrawingML::WriteBlip( Reference< XPropertySet > rXPropSet, OUString& rURL, Graphic *pGraphic ) { - OUString sRelId = WriteImage( rURL ); + OUString sRelId = pGraphic ? WriteImage( *pGraphic ) : WriteImage( rURL ); sal_Int16 nBright = 0; sal_Int32 nContrast = 0; diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index f4650448cfcd..e4acb04958c4 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <comphelper/mediadescriptor.hxx> #include "oox/core/xmlfilterbase.hxx" #include "oox/export/shapes.hxx" #include "oox/export/utils.hxx" @@ -33,6 +34,7 @@ #include <com/sun/star/beans/XPropertySetInfo.hpp> #include <com/sun/star/beans/XPropertyState.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/document/XExporter.hpp> #include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/drawing/BitmapMode.hpp> #include <com/sun/star/drawing/ConnectorType.hpp> @@ -41,8 +43,10 @@ #include <com/sun/star/drawing/LineStyle.hpp> #include <com/sun/star/drawing/TextHorizontalAdjust.hpp> #include <com/sun/star/drawing/TextVerticalAdjust.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/style/ParagraphAdjust.hpp> #include <com/sun/star/text/XSimpleText.hpp> #include <com/sun/star/text/XText.hpp> @@ -67,6 +71,7 @@ #include <svl/languageoptions.hxx> #include <filter/msfilter/escherex.hxx> #include <svx/svdoashp.hxx> +#include <svx/svdoole2.hxx> #include <editeng/svxenum.hxx> #include <svx/unoapi.hxx> #include <oox/export/chartexport.hxx> @@ -84,8 +89,12 @@ using ::com::sun::star::beans::XPropertyState; using ::com::sun::star::container::XEnumeration; using ::com::sun::star::container::XEnumerationAccess; using ::com::sun::star::container::XIndexAccess; +using ::com::sun::star::document::XExporter; +using ::com::sun::star::document::XFilter; using ::com::sun::star::drawing::FillStyle; +using ::com::sun::star::graphic::XGraphic; using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::lang::XComponent; using ::com::sun::star::text::XSimpleText; using ::com::sun::star::text::XText; using ::com::sun::star::text::XTextContent; @@ -94,6 +103,8 @@ using ::com::sun::star::text::XTextRange; using ::oox::core::XmlFilterBase; using ::com::sun::star::chart2::XChartDocument; using ::com::sun::star::frame::XModel; +using ::com::sun::star::sheet::XSpreadsheetDocument; +using ::comphelper::MediaDescriptor; using ::oox::core::XmlFilterBase; using ::rtl::OString; using ::rtl::OStringBuffer; @@ -103,7 +114,6 @@ using ::sax_fastparser::FSHelperPtr; #define IDS(x) (OString(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr() - struct CustomShapeTypeTranslationTable { const char* sOOo; @@ -556,6 +566,9 @@ namespace oox { namespace drawingml { if ( GETA(propName) ) \ mAny >>= variable; +// not thread safe +int ShapeExport::mnSpreadsheetCounter = 1; + ShapeExport::ShapeExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, ShapeHashMap* pShapeMap, XmlFilterBase* pFB, DocumentType eDocumentType ) : DrawingML( pFS, pFB, eDocumentType ) , mnShapeIdMax( 1 ) @@ -802,6 +815,13 @@ ShapeExport& ShapeExport::WriteEllipseShape( Reference< XShape > xShape ) ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape ) { + WriteGraphicObjectShapePart( xShape ); + + return *this; +} + +void ShapeExport::WriteGraphicObjectShapePart( Reference< XShape > xShape, Graphic* pGraphic ) +{ DBG(printf("write graphic object shape\n")); if( NonEmptyText( xShape ) ) @@ -810,17 +830,17 @@ ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape ) //DBG(dump_pset(mXPropSet)); - return *this; + return; } DBG(printf("graphicObject without text\n")); OUString sGraphicURL; Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY ); - if( !xShapeProps.is() || !( xShapeProps->getPropertyValue( S( "GraphicURL" ) ) >>= sGraphicURL ) ) + if( !pGraphic && ( !xShapeProps.is() || !( xShapeProps->getPropertyValue( S( "GraphicURL" ) ) >>= sGraphicURL ) ) ) { DBG(printf("no graphic URL found\n")); - return *this; + return; } FSHelperPtr pFS = GetFS(); @@ -830,8 +850,12 @@ ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape ) pFS->startElementNS( mnXmlNamespace, XML_nvPicPr, FSEND ); OUString sName, sDescr; - bool bHaveName = xShapeProps->getPropertyValue( S( "Name" ) ) >>= sName; - bool bHaveDesc = xShapeProps->getPropertyValue( S( "Description" ) ) >>= sDescr; + bool bHaveName, bHaveDesc; + + if ( ( bHaveName= GetProperty( xShapeProps, S( "Name" ) ) ) ) + mAny >>= sName; + if ( ( bHaveDesc = GetProperty( xShapeProps, S( "Description" ) ) ) ) + mAny >>= sDescr; pFS->singleElementNS( mnXmlNamespace, XML_cNvPr, XML_id, I32S( GetNewShapeID( xShape ) ), @@ -850,13 +874,16 @@ ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape ) pFS->startElementNS( mnXmlNamespace, XML_blipFill, FSEND ); - WriteBlip( xShapeProps, sGraphicURL ); + WriteBlip( xShapeProps, sGraphicURL, pGraphic ); + // now we stretch always when we get pGraphic (when changing that + // behavior, test n#780830 for regression, where the OLE sheet might get tiled bool bStretch = false; - if( ( xShapeProps->getPropertyValue( S( "FillBitmapStretch" ) ) >>= bStretch ) && bStretch ) - { + if( !pGraphic && GetProperty( xShapeProps, S( "FillBitmapStretch" ) ) ) + mAny >>= bStretch; + + if ( pGraphic || bStretch ) WriteStretch(); - } pFS->endElementNS( mnXmlNamespace, XML_blipFill ); @@ -869,8 +896,6 @@ ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape ) pFS->endElementNS( mnXmlNamespace, XML_spPr ); pFS->endElementNS( mnXmlNamespace, XML_pic ); - - return *this; } ShapeExport& ShapeExport::WriteConnectorShape( Reference< XShape > xShape ) @@ -1271,17 +1296,110 @@ ShapeExport& ShapeExport::WriteTextShape( Reference< XShape > xShape ) ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape ) { Reference< XPropertySet > xPropSet( xShape, UNO_QUERY ); - if( xPropSet.is() && GetProperty( xPropSet, S("Model") ) ) - { - Reference< XChartDocument > xChartDoc; - mAny >>= xChartDoc; - if( xChartDoc.is() ) + if( xPropSet.is() ) { + if( GetProperty( xPropSet, S("Model") ) ) { - //export the chart - Reference< XModel > xModel( xChartDoc, UNO_QUERY ); - ChartExport aChartExport( mnXmlNamespace, GetFS(), xModel, GetFB(), GetDocumentType() ); - static sal_Int32 nChartCount = 0; - aChartExport.WriteChartObj( xShape, ++nChartCount ); + Reference< XChartDocument > xChartDoc; + mAny >>= xChartDoc; + if( xChartDoc.is() ) + { + //export the chart + Reference< XModel > xModel( xChartDoc, UNO_QUERY ); + ChartExport aChartExport( mnXmlNamespace, GetFS(), xModel, GetFB(), GetDocumentType() ); + static sal_Int32 nChartCount = 0; + aChartExport.WriteChartObj( xShape, ++nChartCount ); + } + else + { + // this part now supports only embedded spreadsheets, it can be extended to support remaining ooxml documents + // only exporter, counter and object filename are specific to spreadsheet + Reference< XSpreadsheetDocument > xSheetDoc( mAny, UNO_QUERY ); + if( xSheetDoc.is() ) + { + Reference< XComponent > xDocument( mAny, UNO_QUERY ); + Reference< XExporter > xExporter( mpFB->getServiceFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilterExport" ) ), UNO_QUERY ); + if( xDocument.is() && xExporter.is() && mpFB ) + { + Reference< XOutputStream > xOutStream = mpFB->openFragmentStream( OUStringBuffer() + .appendAscii( GetComponentDir() ) + .appendAscii( "/embeddings/spreadsheet" ) + .append( (sal_Int32) mnSpreadsheetCounter ) + .appendAscii( ".xlsx" ) + .makeStringAndClear(), + S("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") ); + // export the embedded document + Sequence< PropertyValue > rMedia(1); + + rMedia[0].Name = MediaDescriptor::PROP_STREAMFOROUTPUT(); + rMedia[0].Value <<= xOutStream; + + Reference< XFilter > xFilter( xExporter, UNO_QUERY ); + + if( xFilter.is() ) + { + xExporter->setSourceDocument( xDocument ); + xFilter->filter( rMedia ); + } + + xOutStream->closeOutput(); + + OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(), + US( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package" ), + OUStringBuffer() + .appendAscii( GetRelationCompPrefix() ) + .appendAscii( "embeddings/spreadsheet" ) + .append( (sal_Int32) mnSpreadsheetCounter ++ ) + .appendAscii( ".xlsx" ) + .makeStringAndClear() ); + + mpFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND ); + + mpFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND ); + + mpFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + XML_id, I32S( GetNewShapeID( xShape ) ), + XML_name, IDS(Object), + FSEND ); + + mpFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr, + FSEND ); + + if( GetDocumentType() == DOCUMENT_PPTX ) + mpFS->singleElementNS( mnXmlNamespace, XML_nvPr, + FSEND ); + mpFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr ); + + WriteShapeTransformation( xShape, mnXmlNamespace ); + + mpFS->startElementNS( XML_a, XML_graphic, FSEND ); + mpFS->startElementNS( XML_a, XML_graphicData, + XML_uri, "http://schemas.openxmlformats.org/presentationml/2006/ole", + FSEND ); + mpFS->startElementNS( mnXmlNamespace, XML_oleObj, + XML_name, "Spreadsheet", + FSNS(XML_r, XML_id), USS( sRelId ), + FSEND ); + + mpFS->singleElementNS( mnXmlNamespace, XML_embed, FSEND ); + + // pic element + SdrObject* pSdrOLE2( GetSdrObjectFromXShape( xShape ) ); + if ( pSdrOLE2 && pSdrOLE2->ISA( SdrOle2Obj ) ) + { + Graphic* pGraphic = ((SdrOle2Obj*)pSdrOLE2)->GetGraphic(); + if ( pGraphic ) + WriteGraphicObjectShapePart( xShape, pGraphic ); + } + + mpFS->endElementNS( mnXmlNamespace, XML_oleObj ); + + mpFS->endElementNS( XML_a, XML_graphicData ); + mpFS->endElementNS( XML_a, XML_graphic ); + + mpFS->endElementNS( mnXmlNamespace, XML_graphicFrame ); + } + } + } } } return *this; |