/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: graphicshapecontext.cxx,v $ * $Revision: 1.7 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include "oox/drawingml/fillpropertiesgroupcontext.hxx" #include "oox/drawingml/graphicshapecontext.hxx" #include "oox/drawingml/diagram/diagramfragmenthandler.hxx" #include "oox/drawingml/table/tablecontext.hxx" #include "oox/core/namespaces.hxx" #include "oox/helper/attributelist.hxx" #include "oox/helper/propertyset.hxx" #include "oox/drawingml/transform2dcontext.hxx" #include "oox/drawingml/chart/chartconverter.hxx" #include "oox/drawingml/chart/chartspacefragment.hxx" #include "oox/drawingml/chart/chartspacemodel.hxx" #include "tokens.hxx" #include #include #include #include #include #include #include using ::rtl::OUString; using namespace ::com::sun::star; using namespace ::com::sun::star::io; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; using namespace ::oox::core; using namespace ::com::sun::star::xml::sax; namespace oox { namespace drawingml { // ==================================================================== // CT_Picture GraphicShapeContext::GraphicShapeContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr ) : ShapeContext( rParent, pMasterShapePtr, pShapePtr ) { } Reference< XFastContextHandler > GraphicShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException) { Reference< XFastContextHandler > xRet; switch( getToken( aElementToken ) ) { // CT_ShapeProperties case XML_xfrm: xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) ); break; case XML_blipFill: xRet.set( new BlipFillPropertiesContext( *this, xAttribs, *mpShapePtr->getGraphicProperties() ) ); break; } if (getNamespace( aElementToken ) == NMSP_VML && mpShapePtr) { mpShapePtr->setServiceName("com.sun.star.drawing.CustomShape"); CustomShapePropertiesPtr pCstmShpProps (mpShapePtr->getCustomShapeProperties()); sal_uInt32 nType = aElementToken & (~ NMSP_MASK); OUString sType(GetShapeType(nType)); if (sType.getLength() > 0) pCstmShpProps->setShapePresetType(sType); } if( !xRet.is() ) xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) ); return xRet; } // ==================================================================== // CT_GraphicalObjectFrameContext GraphicalObjectFrameContext::GraphicalObjectFrameContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr ) : ShapeContext( rParent, pMasterShapePtr, pShapePtr ) { } Reference< XFastContextHandler > GraphicalObjectFrameContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException) { Reference< XFastContextHandler > xRet; switch( aElementToken &(~NMSP_MASK) ) { // CT_ShapeProperties case XML_nvGraphicFramePr: // CT_GraphicalObjectFrameNonVisual break; case XML_xfrm: // CT_Transform2D xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) ); break; case XML_graphic: // CT_GraphicalObject xRet.set( this ); break; case XML_graphicData : // CT_GraphicalObjectData { OUString sUri( xAttribs->getOptionalValue( XML_uri ) ); if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/presentationml/2006/ole" ) ) xRet.set( new PresentationOle2006Context( *this, mpShapePtr ) ); else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ) ) xRet.set( new DiagramGraphicDataContext( *this, mpShapePtr ) ); else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/chart" ) ) xRet.set( new ChartGraphicDataContext( *this, mpShapePtr ) ); else if ( sUri.compareToAscii( "http://schemas.openxmlformats.org/drawingml/2006/table" ) == 0 ) xRet.set( new table::TableContext( *this, mpShapePtr ) ); else { OSL_TRACE( "OOX: Ignore graphicsData of %s", OUSTRING_TO_CSTR( sUri ) ); return xRet; } } break; } if( !xRet.is() ) xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) ); return xRet; } // ==================================================================== PresentationOle2006Context::PresentationOle2006Context( ContextHandler& rParent, ShapePtr pShapePtr ) : ShapeContext( rParent, ShapePtr(), pShapePtr ) { } PresentationOle2006Context::~PresentationOle2006Context() { static sal_Int32 nObjectCount = 100; XmlFilterBase& rFilter = getFilter(); const OUString aFragmentPath = getFragmentPathFromRelId( msId ); if( aFragmentPath.getLength() > 0 ) try { Reference< ::com::sun::star::io::XInputStream > xInputStream( rFilter.openInputStream( aFragmentPath ), UNO_QUERY_THROW ); Sequence< sal_Int8 > aData; xInputStream->readBytes( aData, 0x7fffffff ); uno::Reference< lang::XMultiServiceFactory > xMSF( rFilter.getModel(), UNO_QUERY_THROW ); Reference< com::sun::star::document::XEmbeddedObjectResolver > xEmbeddedResolver( xMSF->createInstance( CREATE_OUSTRING( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY_THROW ); Reference< com::sun::star::container::XNameAccess > xNA( xEmbeddedResolver, UNO_QUERY_THROW ); OUString aURL = CREATE_OUSTRING( "Obj" ) + OUString::valueOf( nObjectCount++ ); Reference < XOutputStream > xOLEStream; if( (xNA->getByName( aURL ) >>= xOLEStream) && xOLEStream.is() ) { xOLEStream->writeBytes( aData ); xOLEStream->closeOutput(); static const OUString sProtocol = CREATE_OUSTRING( "vnd.sun.star.EmbeddedObject:" ); OUString aPersistName( xEmbeddedResolver->resolveEmbeddedObjectURL( aURL ) ); aPersistName = aPersistName.copy( sProtocol.getLength() ); static const OUString sPersistName = CREATE_OUSTRING( "PersistName" ); mpShapePtr->getShapeProperties()[ sPersistName ] <<= aPersistName; } Reference< XComponent > xComp( xEmbeddedResolver, UNO_QUERY_THROW ); xComp->dispose(); } catch( Exception& ) { } // taking care of the representation graphic if ( msSpid.getLength() ) { oox::vml::DrawingPtr pDrawingPtr = rFilter.getDrawings(); if ( pDrawingPtr ) { OUString aGraphicURL( pDrawingPtr->getGraphicUrlById( msSpid ) ); if ( aGraphicURL.getLength() ) { try { Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() ); Reference< io::XInputStream > xInputStream( rFilter.openInputStream( aGraphicURL ), UNO_QUERY_THROW ); Reference< graphic::XGraphicProvider > xGraphicProvider( xMSF->createInstance( CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY_THROW ); Sequence< PropertyValue > aArgs( 1 ); const OUString sInputStream = CREATE_OUSTRING( "InputStream" ); aArgs[ 0 ].Name = sInputStream; aArgs[ 0 ].Value <<= xInputStream; Reference< graphic::XGraphic > xGraphic = xGraphicProvider->queryGraphic( aArgs ); if ( xGraphic.is() ) { static const OUString sEmptyGraphicURL; static const OUString sGraphicURL = CREATE_OUSTRING( "GraphicURL" ); mpShapePtr->getShapeProperties()[ sGraphicURL ] <<= sEmptyGraphicURL; static const OUString sThumbnailGraphic = CREATE_OUSTRING( "Graphic" ); mpShapePtr->getShapeProperties()[ sThumbnailGraphic ] <<= xGraphic; } } catch( Exception& ) { } } } } } Reference< XFastContextHandler > PresentationOle2006Context::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException) { Reference< XFastContextHandler > xRet; switch( aElementToken &(~NMSP_MASK) ) { case XML_oleObj: { msSpid = xAttribs->getOptionalValue( XML_spid ); msName = xAttribs->getOptionalValue( XML_name ); msId = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_id ); mnWidth = GetCoordinate( xAttribs->getOptionalValue( XML_imgW ) ); mnHeight = GetCoordinate( xAttribs->getOptionalValue( XML_imgH ) ); msProgId = xAttribs->getOptionalValue( XML_progId ); } break; case XML_embed: { mnFollowColorSchemeToken = xAttribs->getOptionalValueToken( XML_followColorScheme, XML_full ); } break; } if( !xRet.is() ) xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) ); return xRet; } // ==================================================================== DiagramGraphicDataContext::DiagramGraphicDataContext( ContextHandler& rParent, ShapePtr pShapePtr ) : ShapeContext( rParent, ShapePtr(), pShapePtr ) { pShapePtr->setServiceName( "com.sun.star.drawing.GroupShape" ); pShapePtr->setSubType( 0 ); } DiagramGraphicDataContext::~DiagramGraphicDataContext() { } DiagramPtr DiagramGraphicDataContext::loadDiagram() { DiagramPtr pDiagram( new Diagram() ); XmlFilterBase& rFilter = getFilter(); // data OUString sDmPath = getFragmentPathFromRelId( msDm ); if( sDmPath.getLength() > 0 ) { DiagramDataPtr pData( new DiagramData() ); pDiagram->setData( pData ); rFilter.importFragment( new DiagramDataFragmentHandler( rFilter, sDmPath, pData ) ); } // layout OUString sLoPath = getFragmentPathFromRelId( msLo ); if( sLoPath.getLength() > 0 ) { DiagramLayoutPtr pLayout( new DiagramLayout() ); pDiagram->setLayout( pLayout ); rFilter.importFragment( new DiagramLayoutFragmentHandler( rFilter, sLoPath, pLayout ) ); } // style OUString sQsPath = getFragmentPathFromRelId( msQs ); if( sQsPath.getLength() > 0 ) { DiagramQStylesPtr pStyles( new DiagramQStyles() ); pDiagram->setQStyles( pStyles ); rFilter.importFragment( new DiagramQStylesFragmentHandler( rFilter, sQsPath, pStyles ) ); } // colors OUString sCsPath = getFragmentPathFromRelId( msCs ); if( sCsPath.getLength() > 0 ) { DiagramColorsPtr pColors( new DiagramColors() ); pDiagram->setColors( pColors ); rFilter.importFragment( new DiagramColorsFragmentHandler( rFilter, sCsPath, pColors ) ) ; } return pDiagram; } Reference< XFastContextHandler > DiagramGraphicDataContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException) { Reference< XFastContextHandler > xRet; switch( aElementToken ) { case NMSP_DIAGRAM|XML_relIds: { msDm = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_dm ); msLo = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_lo ); msQs = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_qs ); msCs = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_cs ); DiagramPtr pDiagram = loadDiagram(); pDiagram->addTo( mpShapePtr ); OSL_TRACE("diagram added shape %s of type %s", OUSTRING_TO_CSTR( mpShapePtr->getName() ), OUSTRING_TO_CSTR( mpShapePtr->getServiceName() ) ); break; } default: break; } if( !xRet.is() ) xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) ); return xRet; } // ==================================================================== class CreateChartCallback : public CreateShapeCallback { public: explicit CreateChartCallback( XmlFilterBase& rFilter, const OUString& rFragmentPath ); virtual void onCreateXShape( const Reference< drawing::XShape >& rxShape ); private: XmlFilterBase& mrFilter; OUString maFragmentPath; }; // -------------------------------------------------------------------- CreateChartCallback::CreateChartCallback( XmlFilterBase& rFilter, const OUString& rFragmentPath ) : mrFilter( rFilter ), maFragmentPath( rFragmentPath ) { } void CreateChartCallback::onCreateXShape( const Reference< drawing::XShape >& rxShape ) { OSL_ENSURE( maFragmentPath.getLength() > 0, "CreateChartCallback::onCreateXShape - missing chart fragment" ); if( maFragmentPath.getLength() > 0 ) try { // set the chart2 OLE class ID at the OLE shape PropertySet aShapeProp( rxShape ); aShapeProp.setProperty( CREATE_OUSTRING( "CLSID" ), CREATE_OUSTRING( "12dcae26-281f-416f-a234-c3086127382e" ) ); // get the XModel interface of the embedded object from the OLE shape Reference< frame::XModel > xDocModel; aShapeProp.getProperty( xDocModel, CREATE_OUSTRING( "Model" ) ); // load the chart data from the XML fragment chart::ChartSpaceModel aModel; mrFilter.importFragment( new chart::ChartSpaceFragment( mrFilter, maFragmentPath, aModel ) ); // convert imported chart model to chart document Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW ); mrFilter.getChartConverter().convertFromModel( mrFilter, aModel, xChartDoc ); } catch( Exception& ) { } } // ==================================================================== ChartGraphicDataContext::ChartGraphicDataContext( ContextHandler& rParent, ShapePtr pShapePtr ) : ShapeContext( rParent, ShapePtr(), pShapePtr ) { pShapePtr->setServiceName( "com.sun.star.drawing.OLE2Shape" ); } Reference< XFastContextHandler > ChartGraphicDataContext::createFastChildContext( ::sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException) { if( nElement == (NMSP_CHART | XML_chart) ) { AttributeList aAttribs( rxAttribs ); OUString aFragmentPath = getFragmentPathFromRelId( aAttribs.getString( NMSP_RELATIONSHIPS | XML_id, OUString() ) ); CreateShapeCallbackRef xCallback( new CreateChartCallback( getFilter(), aFragmentPath ) ); mpShapePtr->setCreateShapeCallback( xCallback ); } return 0; } // ==================================================================== } }