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"
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
;
67 // ============================================================================
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
) )
83 xRet
.set( new Transform2DContext( *this, xAttribs
, *mpShapePtr
) );
86 xRet
.set( new BlipFillContext( *this, xAttribs
, mpShapePtr
->getGraphicProperties().maBlipProps
) );
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
);
104 xRet
.set( ShapeContext::createFastChildContext( aElementToken
, xAttribs
) );
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
126 case XML_xfrm
: // CT_Transform2D
127 xRet
.set( new Transform2DContext( *this, xAttribs
, *mpShapePtr
) );
129 case XML_graphic
: // CT_GraphicalObject
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
) );
146 OSL_TRACE( "OOX: Ignore graphicsData of %s", OUSTRING_TO_CSTR( sUri
) );
153 xRet
.set( ShapeContext::createFastChildContext( aElementToken
, xAttribs
) );
158 // ============================================================================
160 class CreateOleObjectCallback
: public CreateShapeCallback
163 explicit CreateOleObjectCallback( XmlFilterBase
& rFilter
, const ::boost::shared_ptr
< OleObjectInfo
>& rxOleObjectInfo
);
164 virtual OUString
onCreateXShape( const OUString
& rServiceName
, const awt::Rectangle
& rShapeRect
);
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
);
196 maShapeProps
[ PROP_Graphic
] <<= xGraphic
;
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
);
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" );
235 mxOleObjectInfo
->mbLinked
= pRelation
->mbExternal
;
236 if( pRelation
->mbExternal
)
238 mxOleObjectInfo
->maTargetLink
= getFilter().getAbsoluteUrl( pRelation
->maTarget
);
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 );
254 case PPT_TOKEN( embed
):
255 OSL_ENSURE( !mxOleObjectInfo
->mbLinked
, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
258 case PPT_TOKEN( link
):
259 OSL_ENSURE( mxOleObjectInfo
->mbLinked
, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
260 mxOleObjectInfo
->mbAutoUpdate
= aAttribs
.getBool( XML_updateAutomatic
, false );
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();
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
) );
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
) );
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
) );
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
) ) ;
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() ) );
345 xRet
.set( ShapeContext::createFastChildContext( aElementToken
, xAttribs
) );
350 // ============================================================================
352 class CreateChartCallback
: public CreateShapeCallback
355 explicit CreateChartCallback( XmlFilterBase
& rFilter
, const OUString
& rFragmentPath
);
356 virtual void onXShapeCreated( const Reference
< drawing::XShape
>& rxShape
) const;
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
);
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
);
417 // ============================================================================
419 } // namespace drawingml