merge the formfield patch from ooo-build
[ooovba.git] / oox / source / drawingml / graphicshapecontext.cxx
blobcd36e9569fdbfc8a9d517ebd239eaf70922b5127
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/customshapeproperties.hxx"
37 #include "oox/drawingml/diagram/diagramfragmenthandler.hxx"
38 #include "oox/drawingml/table/tablecontext.hxx"
39 #include "oox/core/namespaces.hxx"
40 #include "oox/core/xmlfilterbase.hxx"
41 #include "oox/helper/attributelist.hxx"
42 #include "oox/helper/propertyset.hxx"
43 #include "oox/vml/vmldrawing.hxx"
44 #include "oox/vml/vmlshape.hxx"
45 #include "oox/vml/vmlshapecontainer.hxx"
46 #include "oox/ole/oleobjecthelper.hxx"
47 #include "oox/drawingml/fillproperties.hxx"
48 #include "oox/drawingml/transform2dcontext.hxx"
49 #include "oox/drawingml/chart/chartconverter.hxx"
50 #include "oox/drawingml/chart/chartspacefragment.hxx"
51 #include "oox/drawingml/chart/chartspacemodel.hxx"
52 #include "properties.hxx"
53 #include "tokens.hxx"
55 using ::rtl::OUString;
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::io;
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::lang;
60 using namespace ::com::sun::star::beans;
61 using namespace ::com::sun::star::xml::sax;
62 using namespace ::oox::core;
63 using ::oox::vml::OleObjectInfo;
65 namespace oox {
66 namespace drawingml {
68 // ============================================================================
69 // CT_Picture
71 GraphicShapeContext::GraphicShapeContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
72 : ShapeContext( rParent, pMasterShapePtr, pShapePtr )
76 Reference< XFastContextHandler > GraphicShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
78 Reference< XFastContextHandler > xRet;
80 switch( getToken( aElementToken ) )
82 // CT_ShapeProperties
83 case XML_xfrm:
84 xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) );
85 break;
86 case XML_blipFill:
87 xRet.set( new BlipFillContext( *this, xAttribs, mpShapePtr->getGraphicProperties().maBlipProps ) );
88 break;
91 if (getNamespace( aElementToken ) == NMSP_VML && mpShapePtr)
93 mpShapePtr->setServiceName("com.sun.star.drawing.CustomShape");
94 CustomShapePropertiesPtr pCstmShpProps
95 (mpShapePtr->getCustomShapeProperties());
97 sal_uInt32 nType = aElementToken & (~ NMSP_MASK);
98 OUString sType(GetShapeType(nType));
100 if (sType.getLength() > 0)
101 pCstmShpProps->setShapePresetType(sType);
104 if( !xRet.is() )
105 xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
107 return xRet;
110 // ============================================================================
111 // CT_GraphicalObjectFrameContext
113 GraphicalObjectFrameContext::GraphicalObjectFrameContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
114 : ShapeContext( rParent, pMasterShapePtr, pShapePtr )
118 Reference< XFastContextHandler > GraphicalObjectFrameContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
120 Reference< XFastContextHandler > xRet;
122 switch( aElementToken &(~NMSP_MASK) )
124 // CT_ShapeProperties
125 case XML_nvGraphicFramePr: // CT_GraphicalObjectFrameNonVisual
126 break;
127 case XML_xfrm: // CT_Transform2D
128 xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) );
129 break;
130 case XML_graphic: // CT_GraphicalObject
131 xRet.set( this );
132 break;
134 case XML_graphicData : // CT_GraphicalObjectData
136 OUString sUri( xAttribs->getOptionalValue( XML_uri ) );
137 if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/presentationml/2006/ole" ) )
138 xRet.set( new OleObjectGraphicDataContext( *this, mpShapePtr ) );
139 else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ) )
140 xRet.set( new DiagramGraphicDataContext( *this, mpShapePtr ) );
141 else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/chart" ) )
142 xRet.set( new ChartGraphicDataContext( *this, mpShapePtr ) );
143 else if ( sUri.compareToAscii( "http://schemas.openxmlformats.org/drawingml/2006/table" ) == 0 )
144 xRet.set( new table::TableContext( *this, mpShapePtr ) );
145 else
147 OSL_TRACE( "OOX: Ignore graphicsData of %s", OUSTRING_TO_CSTR( sUri ) );
148 return xRet;
151 break;
153 if( !xRet.is() )
154 xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
156 return xRet;
159 // ============================================================================
161 class CreateOleObjectCallback : public CreateShapeCallback
163 public:
164 explicit CreateOleObjectCallback( XmlFilterBase& rFilter, const ::boost::shared_ptr< OleObjectInfo >& rxOleObjectInfo );
165 virtual OUString onCreateXShape( const OUString& rServiceName, const awt::Rectangle& rShapeRect );
167 private:
168 ::boost::shared_ptr< OleObjectInfo > mxOleObjectInfo;
171 // ----------------------------------------------------------------------------
173 CreateOleObjectCallback::CreateOleObjectCallback( XmlFilterBase& rFilter, const ::boost::shared_ptr< OleObjectInfo >& rxOleObjectInfo ) :
174 CreateShapeCallback( rFilter ),
175 mxOleObjectInfo( rxOleObjectInfo )
179 OUString CreateOleObjectCallback::onCreateXShape( const OUString&, const awt::Rectangle& rShapeRect )
181 awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
182 bool bSuccess = mrFilter.getOleObjectHelper().importOleObject( maShapeProps, *mxOleObjectInfo, aOleSize );
183 OUString aServiceName = bSuccess ? CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ) : CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" );
185 // get the path to the representation graphic
186 OUString aGraphicPath;
187 if( mxOleObjectInfo->maShapeId.getLength() > 0 )
188 if( ::oox::vml::Drawing* pVmlDrawing = mrFilter.getVmlDrawing() )
189 if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) )
190 aGraphicPath = pVmlShape->getGraphicPath();
192 // import and store the graphic
193 if( aGraphicPath.getLength() > 0 )
195 Reference< graphic::XGraphic > xGraphic = mrFilter.importEmbeddedGraphic( aGraphicPath );
196 if( xGraphic.is() )
197 maShapeProps[ PROP_Graphic ] <<= xGraphic;
200 return aServiceName;
203 // ============================================================================
205 OleObjectGraphicDataContext::OleObjectGraphicDataContext( ContextHandler& rParent, ShapePtr xShape ) :
206 ShapeContext( rParent, ShapePtr(), xShape ),
207 mxOleObjectInfo( new OleObjectInfo( true ) )
209 CreateShapeCallbackRef xCallback( new CreateOleObjectCallback( getFilter(), mxOleObjectInfo ) );
210 xShape->setCreateShapeCallback( xCallback );
213 OleObjectGraphicDataContext::~OleObjectGraphicDataContext()
215 /* Register the OLE shape at the VML drawing, this prevents that the
216 related VML shape converts the OLE object by itself. */
217 if( mxOleObjectInfo->maShapeId.getLength() > 0 )
218 if( ::oox::vml::Drawing* pVmlDrawing = getFilter().getVmlDrawing() )
219 pVmlDrawing->registerOleObject( *mxOleObjectInfo );
222 Reference< XFastContextHandler > OleObjectGraphicDataContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
224 Reference< XFastContextHandler > xRet;
225 AttributeList aAttribs( xAttribs );
227 switch( nElement )
229 case PPT_TOKEN( oleObj ):
231 mxOleObjectInfo->maShapeId = aAttribs.getXString( XML_spid, OUString() );
232 const Relation* pRelation = getRelations().getRelationFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
233 OSL_ENSURE( pRelation, "OleObjectGraphicDataContext::createFastChildContext - missing relation for OLE object" );
234 if( pRelation )
236 mxOleObjectInfo->mbLinked = pRelation->mbExternal;
237 if( pRelation->mbExternal )
239 mxOleObjectInfo->maTargetLink = getFilter().getAbsoluteUrl( pRelation->maTarget );
241 else
243 OUString aFragmentPath = getFragmentPathFromRelation( *pRelation );
244 if( aFragmentPath.getLength() > 0 )
245 getFilter().importBinaryData( mxOleObjectInfo->maEmbeddedData, aFragmentPath );
248 mxOleObjectInfo->maName = aAttribs.getXString( XML_name, OUString() );
249 mxOleObjectInfo->maProgId = aAttribs.getXString( XML_progId, OUString() );
250 mxOleObjectInfo->mbShowAsIcon = aAttribs.getBool( XML_showAsIcon, false );
251 xRet.set( this );
253 break;
255 case PPT_TOKEN( embed ):
256 OSL_ENSURE( !mxOleObjectInfo->mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
257 break;
259 case PPT_TOKEN( link ):
260 OSL_ENSURE( mxOleObjectInfo->mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
261 mxOleObjectInfo->mbAutoUpdate = aAttribs.getBool( XML_updateAutomatic, false );
262 break;
264 return xRet;
267 // ============================================================================
269 DiagramGraphicDataContext::DiagramGraphicDataContext( ContextHandler& rParent, ShapePtr pShapePtr )
270 : ShapeContext( rParent, ShapePtr(), pShapePtr )
272 pShapePtr->setServiceName( "com.sun.star.drawing.GroupShape" );
273 pShapePtr->setSubType( 0 );
276 DiagramGraphicDataContext::~DiagramGraphicDataContext()
280 DiagramPtr DiagramGraphicDataContext::loadDiagram()
282 DiagramPtr pDiagram( new Diagram() );
283 XmlFilterBase& rFilter = getFilter();
285 // data
286 OUString sDmPath = getFragmentPathFromRelId( msDm );
287 if( sDmPath.getLength() > 0 )
289 DiagramDataPtr pData( new DiagramData() );
290 pDiagram->setData( pData );
291 rFilter.importFragment( new DiagramDataFragmentHandler( rFilter, sDmPath, pData ) );
293 // layout
294 OUString sLoPath = getFragmentPathFromRelId( msLo );
295 if( sLoPath.getLength() > 0 )
297 DiagramLayoutPtr pLayout( new DiagramLayout() );
298 pDiagram->setLayout( pLayout );
299 rFilter.importFragment( new DiagramLayoutFragmentHandler( rFilter, sLoPath, pLayout ) );
301 // style
302 OUString sQsPath = getFragmentPathFromRelId( msQs );
303 if( sQsPath.getLength() > 0 )
305 DiagramQStylesPtr pStyles( new DiagramQStyles() );
306 pDiagram->setQStyles( pStyles );
307 rFilter.importFragment( new DiagramQStylesFragmentHandler( rFilter, sQsPath, pStyles ) );
309 // colors
310 OUString sCsPath = getFragmentPathFromRelId( msCs );
311 if( sCsPath.getLength() > 0 )
313 DiagramColorsPtr pColors( new DiagramColors() );
314 pDiagram->setColors( pColors );
315 rFilter.importFragment( new DiagramColorsFragmentHandler( rFilter, sCsPath, pColors ) ) ;
318 return pDiagram;
322 Reference< XFastContextHandler > DiagramGraphicDataContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
323 throw (SAXException, RuntimeException)
325 Reference< XFastContextHandler > xRet;
327 switch( aElementToken )
329 case NMSP_DIAGRAM|XML_relIds:
331 msDm = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_dm );
332 msLo = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_lo );
333 msQs = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_qs );
334 msCs = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_cs );
335 DiagramPtr pDiagram = loadDiagram();
336 pDiagram->addTo( mpShapePtr );
337 OSL_TRACE("diagram added shape %s of type %s", OUSTRING_TO_CSTR( mpShapePtr->getName() ),
338 OUSTRING_TO_CSTR( mpShapePtr->getServiceName() ) );
339 break;
341 default:
342 break;
345 if( !xRet.is() )
346 xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
348 return xRet;
351 // ============================================================================
353 class CreateChartCallback : public CreateShapeCallback
355 public:
356 explicit CreateChartCallback( XmlFilterBase& rFilter, const OUString& rFragmentPath );
357 virtual void onXShapeCreated( const Reference< drawing::XShape >& rxShape ) const;
359 private:
360 OUString maFragmentPath;
363 // ----------------------------------------------------------------------------
365 CreateChartCallback::CreateChartCallback( XmlFilterBase& rFilter, const OUString& rFragmentPath ) :
366 CreateShapeCallback( rFilter ),
367 maFragmentPath( rFragmentPath )
371 void CreateChartCallback::onXShapeCreated( const Reference< drawing::XShape >& rxShape ) const
373 OSL_ENSURE( maFragmentPath.getLength() > 0, "CreateChartCallback::onXShapeCreated - missing chart fragment" );
374 if( maFragmentPath.getLength() > 0 ) try
376 // set the chart2 OLE class ID at the OLE shape
377 PropertySet aShapeProp( rxShape );
378 aShapeProp.setProperty( PROP_CLSID, CREATE_OUSTRING( "12dcae26-281f-416f-a234-c3086127382e" ) );
380 // get the XModel interface of the embedded object from the OLE shape
381 Reference< frame::XModel > xDocModel;
382 aShapeProp.getProperty( xDocModel, PROP_Model );
384 // load the chart data from the XML fragment
385 chart::ChartSpaceModel aModel;
386 mrFilter.importFragment( new chart::ChartSpaceFragment( mrFilter, maFragmentPath, aModel ) );
388 // convert imported chart model to chart document
389 Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW );
390 mrFilter.getChartConverter().convertFromModel( mrFilter, aModel, xChartDoc );
392 catch( Exception& )
397 // ============================================================================
399 ChartGraphicDataContext::ChartGraphicDataContext( ContextHandler& rParent, const ShapePtr& rxShape ) :
400 ShapeContext( rParent, ShapePtr(), rxShape )
402 rxShape->setServiceName( "com.sun.star.drawing.OLE2Shape" );
405 Reference< XFastContextHandler > ChartGraphicDataContext::createFastChildContext( ::sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
406 throw (SAXException, RuntimeException)
408 if( nElement == C_TOKEN( chart ) )
410 AttributeList aAttribs( rxAttribs );
411 OUString aFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
412 CreateShapeCallbackRef xCallback( new CreateChartCallback( getFilter(), aFragmentPath ) );
413 mpShapePtr->setCreateShapeCallback( xCallback );
415 return 0;
418 // ============================================================================
420 } // namespace drawingml
421 } // namespace oox