update dev300-m58
[ooovba.git] / oox / source / drawingml / graphicshapecontext.cxx
blobbe338eff6173559081923fa1c9b7a5770abaf4c7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: graphicshapecontext.cxx,v $
10 * $Revision: 1.8.6.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/drawingml/graphicshapecontext.hxx"
32 #include <osl/diagnose.h>
33 #include <com/sun/star/chart2/XChartDocument.hpp>
35 #include "oox/drawingml/fillpropertiesgroupcontext.hxx"
36 #include "oox/drawingml/diagram/diagramfragmenthandler.hxx"
37 #include "oox/drawingml/table/tablecontext.hxx"
38 #include "oox/core/namespaces.hxx"
39 #include "oox/core/xmlfilterbase.hxx"
40 #include "oox/helper/attributelist.hxx"
41 #include "oox/helper/propertyset.hxx"
42 #include "oox/vml/vmldrawing.hxx"
43 #include "oox/vml/vmlshape.hxx"
44 #include "oox/vml/vmlshapecontainer.hxx"
45 #include "oox/ole/oleobjecthelper.hxx"
46 #include "oox/drawingml/fillproperties.hxx"
47 #include "oox/drawingml/transform2dcontext.hxx"
48 #include "oox/drawingml/chart/chartconverter.hxx"
49 #include "oox/drawingml/chart/chartspacefragment.hxx"
50 #include "oox/drawingml/chart/chartspacemodel.hxx"
51 #include "properties.hxx"
52 #include "tokens.hxx"
54 using ::rtl::OUString;
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::io;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::lang;
59 using namespace ::com::sun::star::beans;
60 using namespace ::com::sun::star::xml::sax;
61 using namespace ::oox::core;
62 using ::oox::vml::OleObjectInfo;
64 namespace oox {
65 namespace drawingml {
67 // ============================================================================
68 // CT_Picture
70 GraphicShapeContext::GraphicShapeContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
71 : ShapeContext( rParent, pMasterShapePtr, pShapePtr )
75 Reference< XFastContextHandler > GraphicShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
77 Reference< XFastContextHandler > xRet;
79 switch( getToken( aElementToken ) )
81 // CT_ShapeProperties
82 case XML_xfrm:
83 xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) );
84 break;
85 case XML_blipFill:
86 xRet.set( new BlipFillContext( *this, xAttribs, mpShapePtr->getGraphicProperties().maBlipProps ) );
87 break;
90 if (getNamespace( aElementToken ) == NMSP_VML && mpShapePtr)
92 mpShapePtr->setServiceName("com.sun.star.drawing.CustomShape");
93 CustomShapePropertiesPtr pCstmShpProps
94 (mpShapePtr->getCustomShapeProperties());
96 sal_uInt32 nType = aElementToken & (~ NMSP_MASK);
97 OUString sType(GetShapeType(nType));
99 if (sType.getLength() > 0)
100 pCstmShpProps->setShapePresetType(sType);
103 if( !xRet.is() )
104 xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
106 return xRet;
109 // ============================================================================
110 // CT_GraphicalObjectFrameContext
112 GraphicalObjectFrameContext::GraphicalObjectFrameContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
113 : ShapeContext( rParent, pMasterShapePtr, pShapePtr )
117 Reference< XFastContextHandler > GraphicalObjectFrameContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
119 Reference< XFastContextHandler > xRet;
121 switch( aElementToken &(~NMSP_MASK) )
123 // CT_ShapeProperties
124 case XML_nvGraphicFramePr: // CT_GraphicalObjectFrameNonVisual
125 break;
126 case XML_xfrm: // CT_Transform2D
127 xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) );
128 break;
129 case XML_graphic: // CT_GraphicalObject
130 xRet.set( this );
131 break;
133 case XML_graphicData : // CT_GraphicalObjectData
135 OUString sUri( xAttribs->getOptionalValue( XML_uri ) );
136 if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/presentationml/2006/ole" ) )
137 xRet.set( new OleObjectGraphicDataContext( *this, mpShapePtr ) );
138 else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ) )
139 xRet.set( new DiagramGraphicDataContext( *this, mpShapePtr ) );
140 else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/chart" ) )
141 xRet.set( new ChartGraphicDataContext( *this, mpShapePtr ) );
142 else if ( sUri.compareToAscii( "http://schemas.openxmlformats.org/drawingml/2006/table" ) == 0 )
143 xRet.set( new table::TableContext( *this, mpShapePtr ) );
144 else
146 OSL_TRACE( "OOX: Ignore graphicsData of %s", OUSTRING_TO_CSTR( sUri ) );
147 return xRet;
150 break;
152 if( !xRet.is() )
153 xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
155 return xRet;
158 // ============================================================================
160 class CreateOleObjectCallback : public CreateShapeCallback
162 public:
163 explicit CreateOleObjectCallback( XmlFilterBase& rFilter, const ::boost::shared_ptr< OleObjectInfo >& rxOleObjectInfo );
164 virtual OUString onCreateXShape( const OUString& rServiceName, const awt::Rectangle& rShapeRect );
166 private:
167 ::boost::shared_ptr< OleObjectInfo > mxOleObjectInfo;
170 // ----------------------------------------------------------------------------
172 CreateOleObjectCallback::CreateOleObjectCallback( XmlFilterBase& rFilter, const ::boost::shared_ptr< OleObjectInfo >& rxOleObjectInfo ) :
173 CreateShapeCallback( rFilter ),
174 mxOleObjectInfo( rxOleObjectInfo )
178 OUString CreateOleObjectCallback::onCreateXShape( const OUString&, const awt::Rectangle& rShapeRect )
180 awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
181 bool bSuccess = mrFilter.getOleObjectHelper().importOleObject( maShapeProps, *mxOleObjectInfo, aOleSize );
182 OUString aServiceName = bSuccess ? CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ) : CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" );
184 // get the path to the representation graphic
185 OUString aGraphicPath;
186 if( mxOleObjectInfo->maShapeId.getLength() > 0 )
187 if( ::oox::vml::Drawing* pVmlDrawing = mrFilter.getVmlDrawing() )
188 if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) )
189 aGraphicPath = pVmlShape->getGraphicPath();
191 // import and store the graphic
192 if( aGraphicPath.getLength() > 0 )
194 Reference< graphic::XGraphic > xGraphic = mrFilter.importEmbeddedGraphic( aGraphicPath );
195 if( xGraphic.is() )
196 maShapeProps[ PROP_Graphic ] <<= xGraphic;
199 return aServiceName;
202 // ============================================================================
204 OleObjectGraphicDataContext::OleObjectGraphicDataContext( ContextHandler& rParent, ShapePtr xShape ) :
205 ShapeContext( rParent, ShapePtr(), xShape ),
206 mxOleObjectInfo( new OleObjectInfo( true ) )
208 CreateShapeCallbackRef xCallback( new CreateOleObjectCallback( getFilter(), mxOleObjectInfo ) );
209 xShape->setCreateShapeCallback( xCallback );
212 OleObjectGraphicDataContext::~OleObjectGraphicDataContext()
214 /* Register the OLE shape at the VML drawing, this prevents that the
215 related VML shape converts the OLE object by itself. */
216 if( mxOleObjectInfo->maShapeId.getLength() > 0 )
217 if( ::oox::vml::Drawing* pVmlDrawing = getFilter().getVmlDrawing() )
218 pVmlDrawing->registerOleObject( *mxOleObjectInfo );
221 Reference< XFastContextHandler > OleObjectGraphicDataContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
223 Reference< XFastContextHandler > xRet;
224 AttributeList aAttribs( xAttribs );
226 switch( nElement )
228 case PPT_TOKEN( oleObj ):
230 mxOleObjectInfo->maShapeId = aAttribs.getXString( XML_spid, OUString() );
231 const Relation* pRelation = getRelations().getRelationFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
232 OSL_ENSURE( pRelation, "OleObjectGraphicDataContext::createFastChildContext - missing relation for OLE object" );
233 if( pRelation )
235 mxOleObjectInfo->mbLinked = pRelation->mbExternal;
236 if( pRelation->mbExternal )
238 mxOleObjectInfo->maTargetLink = getFilter().getAbsoluteUrl( pRelation->maTarget );
240 else
242 OUString aFragmentPath = getFragmentPathFromRelation( *pRelation );
243 if( aFragmentPath.getLength() > 0 )
244 getFilter().importBinaryData( mxOleObjectInfo->maEmbeddedData, aFragmentPath );
247 mxOleObjectInfo->maName = aAttribs.getXString( XML_name, OUString() );
248 mxOleObjectInfo->maProgId = aAttribs.getXString( XML_progId, OUString() );
249 mxOleObjectInfo->mbShowAsIcon = aAttribs.getBool( XML_showAsIcon, false );
250 xRet.set( this );
252 break;
254 case PPT_TOKEN( embed ):
255 OSL_ENSURE( !mxOleObjectInfo->mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
256 break;
258 case PPT_TOKEN( link ):
259 OSL_ENSURE( mxOleObjectInfo->mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
260 mxOleObjectInfo->mbAutoUpdate = aAttribs.getBool( XML_updateAutomatic, false );
261 break;
263 return xRet;
266 // ============================================================================
268 DiagramGraphicDataContext::DiagramGraphicDataContext( ContextHandler& rParent, ShapePtr pShapePtr )
269 : ShapeContext( rParent, ShapePtr(), pShapePtr )
271 pShapePtr->setServiceName( "com.sun.star.drawing.GroupShape" );
272 pShapePtr->setSubType( 0 );
275 DiagramGraphicDataContext::~DiagramGraphicDataContext()
279 DiagramPtr DiagramGraphicDataContext::loadDiagram()
281 DiagramPtr pDiagram( new Diagram() );
282 XmlFilterBase& rFilter = getFilter();
284 // data
285 OUString sDmPath = getFragmentPathFromRelId( msDm );
286 if( sDmPath.getLength() > 0 )
288 DiagramDataPtr pData( new DiagramData() );
289 pDiagram->setData( pData );
290 rFilter.importFragment( new DiagramDataFragmentHandler( rFilter, sDmPath, pData ) );
292 // layout
293 OUString sLoPath = getFragmentPathFromRelId( msLo );
294 if( sLoPath.getLength() > 0 )
296 DiagramLayoutPtr pLayout( new DiagramLayout() );
297 pDiagram->setLayout( pLayout );
298 rFilter.importFragment( new DiagramLayoutFragmentHandler( rFilter, sLoPath, pLayout ) );
300 // style
301 OUString sQsPath = getFragmentPathFromRelId( msQs );
302 if( sQsPath.getLength() > 0 )
304 DiagramQStylesPtr pStyles( new DiagramQStyles() );
305 pDiagram->setQStyles( pStyles );
306 rFilter.importFragment( new DiagramQStylesFragmentHandler( rFilter, sQsPath, pStyles ) );
308 // colors
309 OUString sCsPath = getFragmentPathFromRelId( msCs );
310 if( sCsPath.getLength() > 0 )
312 DiagramColorsPtr pColors( new DiagramColors() );
313 pDiagram->setColors( pColors );
314 rFilter.importFragment( new DiagramColorsFragmentHandler( rFilter, sCsPath, pColors ) ) ;
317 return pDiagram;
321 Reference< XFastContextHandler > DiagramGraphicDataContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
322 throw (SAXException, RuntimeException)
324 Reference< XFastContextHandler > xRet;
326 switch( aElementToken )
328 case NMSP_DIAGRAM|XML_relIds:
330 msDm = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_dm );
331 msLo = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_lo );
332 msQs = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_qs );
333 msCs = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_cs );
334 DiagramPtr pDiagram = loadDiagram();
335 pDiagram->addTo( mpShapePtr );
336 OSL_TRACE("diagram added shape %s of type %s", OUSTRING_TO_CSTR( mpShapePtr->getName() ),
337 OUSTRING_TO_CSTR( mpShapePtr->getServiceName() ) );
338 break;
340 default:
341 break;
344 if( !xRet.is() )
345 xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
347 return xRet;
350 // ============================================================================
352 class CreateChartCallback : public CreateShapeCallback
354 public:
355 explicit CreateChartCallback( XmlFilterBase& rFilter, const OUString& rFragmentPath );
356 virtual void onXShapeCreated( const Reference< drawing::XShape >& rxShape ) const;
358 private:
359 OUString maFragmentPath;
362 // ----------------------------------------------------------------------------
364 CreateChartCallback::CreateChartCallback( XmlFilterBase& rFilter, const OUString& rFragmentPath ) :
365 CreateShapeCallback( rFilter ),
366 maFragmentPath( rFragmentPath )
370 void CreateChartCallback::onXShapeCreated( const Reference< drawing::XShape >& rxShape ) const
372 OSL_ENSURE( maFragmentPath.getLength() > 0, "CreateChartCallback::onXShapeCreated - missing chart fragment" );
373 if( maFragmentPath.getLength() > 0 ) try
375 // set the chart2 OLE class ID at the OLE shape
376 PropertySet aShapeProp( rxShape );
377 aShapeProp.setProperty( PROP_CLSID, CREATE_OUSTRING( "12dcae26-281f-416f-a234-c3086127382e" ) );
379 // get the XModel interface of the embedded object from the OLE shape
380 Reference< frame::XModel > xDocModel;
381 aShapeProp.getProperty( xDocModel, PROP_Model );
383 // load the chart data from the XML fragment
384 chart::ChartSpaceModel aModel;
385 mrFilter.importFragment( new chart::ChartSpaceFragment( mrFilter, maFragmentPath, aModel ) );
387 // convert imported chart model to chart document
388 Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW );
389 mrFilter.getChartConverter().convertFromModel( mrFilter, aModel, xChartDoc );
391 catch( Exception& )
396 // ============================================================================
398 ChartGraphicDataContext::ChartGraphicDataContext( ContextHandler& rParent, const ShapePtr& rxShape ) :
399 ShapeContext( rParent, ShapePtr(), rxShape )
401 rxShape->setServiceName( "com.sun.star.drawing.OLE2Shape" );
404 Reference< XFastContextHandler > ChartGraphicDataContext::createFastChildContext( ::sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
405 throw (SAXException, RuntimeException)
407 if( nElement == C_TOKEN( chart ) )
409 AttributeList aAttribs( rxAttribs );
410 OUString aFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
411 CreateShapeCallbackRef xCallback( new CreateChartCallback( getFilter(), aFragmentPath ) );
412 mpShapePtr->setCreateShapeCallback( xCallback );
414 return 0;
417 // ============================================================================
419 } // namespace drawingml
420 } // namespace oox