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"
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
;
68 // ============================================================================
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
) )
84 xRet
.set( new Transform2DContext( *this, xAttribs
, *mpShapePtr
) );
87 xRet
.set( new BlipFillContext( *this, xAttribs
, mpShapePtr
->getGraphicProperties().maBlipProps
) );
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
);
105 xRet
.set( ShapeContext::createFastChildContext( aElementToken
, xAttribs
) );
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
127 case XML_xfrm
: // CT_Transform2D
128 xRet
.set( new Transform2DContext( *this, xAttribs
, *mpShapePtr
) );
130 case XML_graphic
: // CT_GraphicalObject
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
) );
147 OSL_TRACE( "OOX: Ignore graphicsData of %s", OUSTRING_TO_CSTR( sUri
) );
154 xRet
.set( ShapeContext::createFastChildContext( aElementToken
, xAttribs
) );
159 // ============================================================================
161 class CreateOleObjectCallback
: public CreateShapeCallback
164 explicit CreateOleObjectCallback( XmlFilterBase
& rFilter
, const ::boost::shared_ptr
< OleObjectInfo
>& rxOleObjectInfo
);
165 virtual OUString
onCreateXShape( const OUString
& rServiceName
, const awt::Rectangle
& rShapeRect
);
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
);
197 maShapeProps
[ PROP_Graphic
] <<= xGraphic
;
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
);
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" );
236 mxOleObjectInfo
->mbLinked
= pRelation
->mbExternal
;
237 if( pRelation
->mbExternal
)
239 mxOleObjectInfo
->maTargetLink
= getFilter().getAbsoluteUrl( pRelation
->maTarget
);
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 );
255 case PPT_TOKEN( embed
):
256 OSL_ENSURE( !mxOleObjectInfo
->mbLinked
, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
259 case PPT_TOKEN( link
):
260 OSL_ENSURE( mxOleObjectInfo
->mbLinked
, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
261 mxOleObjectInfo
->mbAutoUpdate
= aAttribs
.getBool( XML_updateAutomatic
, false );
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();
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
) );
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
) );
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
) );
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
) ) ;
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() ) );
346 xRet
.set( ShapeContext::createFastChildContext( aElementToken
, xAttribs
) );
351 // ============================================================================
353 class CreateChartCallback
: public CreateShapeCallback
356 explicit CreateChartCallback( XmlFilterBase
& rFilter
, const OUString
& rFragmentPath
);
357 virtual void onXShapeCreated( const Reference
< drawing::XShape
>& rxShape
) const;
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
);
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
);
418 // ============================================================================
420 } // namespace drawingml