1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "oox/drawingml/graphicshapecontext.hxx"
25 #include <osl/diagnose.h>
26 
27 #include "oox/drawingml/fillpropertiesgroupcontext.hxx"
28 #include "oox/drawingml/customshapeproperties.hxx"
29 #include "oox/drawingml/diagram/diagramfragmenthandler.hxx"
30 #include "oox/drawingml/table/tablecontext.hxx"
31 #include "oox/core/xmlfilterbase.hxx"
32 #include "oox/helper/attributelist.hxx"
33 #include "oox/helper/graphichelper.hxx"
34 #include "oox/helper/propertyset.hxx"
35 #include "oox/vml/vmldrawing.hxx"
36 #include "oox/vml/vmlshape.hxx"
37 #include "oox/vml/vmlshapecontainer.hxx"
38 #include "oox/drawingml/fillproperties.hxx"
39 #include "oox/drawingml/transform2dcontext.hxx"
40 
41 using ::rtl::OUString;
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::io;
44 using namespace ::com::sun::star::uno;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::beans;
47 using namespace ::com::sun::star::xml::sax;
48 using namespace ::oox::core;
49 
50 namespace oox {
51 namespace drawingml {
52 
53 // ============================================================================
54 // CT_Picture
55 
GraphicShapeContext(ContextHandler & rParent,ShapePtr pMasterShapePtr,ShapePtr pShapePtr)56 GraphicShapeContext::GraphicShapeContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
57 : ShapeContext( rParent, pMasterShapePtr, pShapePtr )
58 {
59 }
60 
createFastChildContext(sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)61 Reference< XFastContextHandler > GraphicShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
62 {
63 	Reference< XFastContextHandler > xRet;
64 
65     switch( getBaseToken( aElementToken ) )
66 	{
67 	// CT_ShapeProperties
68 	case XML_xfrm:
69         xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) );
70 		break;
71 	case XML_blipFill:
72         xRet.set( new BlipFillContext( *this, xAttribs, mpShapePtr->getGraphicProperties().maBlipProps ) );
73 		break;
74 	}
75 
76     if ((getNamespace( aElementToken ) == NMSP_vml) && mpShapePtr)
77     {
78         mpShapePtr->setServiceName("com.sun.star.drawing.CustomShape");
79         CustomShapePropertiesPtr pCstmShpProps
80             (mpShapePtr->getCustomShapeProperties());
81 
82         sal_uInt32 nType = getBaseToken( aElementToken );
83         OUString sType(GetShapeType(nType));
84 
85         if (sType.getLength() > 0)
86             pCstmShpProps->setShapePresetType(sType);
87     }
88 
89 	if( !xRet.is() )
90 		xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
91 
92 	return xRet;
93 }
94 
95 // ============================================================================
96 // CT_GraphicalObjectFrameContext
97 
GraphicalObjectFrameContext(ContextHandler & rParent,ShapePtr pMasterShapePtr,ShapePtr pShapePtr,bool bEmbedShapesInChart)98 GraphicalObjectFrameContext::GraphicalObjectFrameContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr, bool bEmbedShapesInChart ) :
99     ShapeContext( rParent, pMasterShapePtr, pShapePtr ),
100     mbEmbedShapesInChart( bEmbedShapesInChart )
101 {
102 }
103 
createFastChildContext(sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)104 Reference< XFastContextHandler > GraphicalObjectFrameContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
105 {
106 	Reference< XFastContextHandler > xRet;
107 
108 	switch( getBaseToken( aElementToken ) )
109 	{
110 	// CT_ShapeProperties
111 	case XML_nvGraphicFramePr:		// CT_GraphicalObjectFrameNonVisual
112 		break;
113 	case XML_xfrm:					// CT_Transform2D
114         xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) );
115 		break;
116 	case XML_graphic:				// CT_GraphicalObject
117 		xRet.set( this );
118 		break;
119 
120 		case XML_graphicData :			// CT_GraphicalObjectData
121 		{
122             OUString sUri( xAttribs->getOptionalValue( XML_uri ) );
123             if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/presentationml/2006/ole" ) )
124                 xRet.set( new OleObjectGraphicDataContext( *this, mpShapePtr ) );
125             else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ) )
126                 xRet.set( new DiagramGraphicDataContext( *this, mpShapePtr ) );
127             else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/chart" ) )
128                 xRet.set( new ChartGraphicDataContext( *this, mpShapePtr, mbEmbedShapesInChart ) );
129 			else if ( sUri.compareToAscii( "http://schemas.openxmlformats.org/drawingml/2006/table" ) == 0 )
130 				xRet.set( new table::TableContext( *this, mpShapePtr ) );
131 			else
132 			{
133 				OSL_TRACE( "OOX: Ignore graphicsData of %s", OUSTRING_TO_CSTR( sUri ) );
134 				return xRet;
135 			}
136 		}
137 		break;
138 	}
139 	if( !xRet.is() )
140 		xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
141 
142 	return xRet;
143 }
144 
145 // ============================================================================
146 
OleObjectGraphicDataContext(ContextHandler & rParent,ShapePtr xShape)147 OleObjectGraphicDataContext::OleObjectGraphicDataContext( ContextHandler& rParent, ShapePtr xShape ) :
148     ShapeContext( rParent, ShapePtr(), xShape ),
149     mrOleObjectInfo( xShape->setOleObjectType() )
150 {
151 }
152 
~OleObjectGraphicDataContext()153 OleObjectGraphicDataContext::~OleObjectGraphicDataContext()
154 {
155     /*  Register the OLE shape at the VML drawing, this prevents that the
156         related VML shape converts the OLE object by itself. */
157     if( mrOleObjectInfo.maShapeId.getLength() > 0 )
158         if( ::oox::vml::Drawing* pVmlDrawing = getFilter().getVmlDrawing() )
159             pVmlDrawing->registerOleObject( mrOleObjectInfo );
160 }
161 
createFastChildContext(sal_Int32 nElement,const Reference<XFastAttributeList> & xAttribs)162 Reference< XFastContextHandler > OleObjectGraphicDataContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
163 {
164 	Reference< XFastContextHandler > xRet;
165     AttributeList aAttribs( xAttribs );
166 
167     switch( nElement )
168 	{
169         case PPT_TOKEN( oleObj ):
170         {
171             mrOleObjectInfo.maShapeId = aAttribs.getXString( XML_spid, OUString() );
172             const Relation* pRelation = getRelations().getRelationFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
173             OSL_ENSURE( pRelation, "OleObjectGraphicDataContext::createFastChildContext - missing relation for OLE object" );
174             if( pRelation )
175             {
176                 mrOleObjectInfo.mbLinked = pRelation->mbExternal;
177                 if( pRelation->mbExternal )
178                 {
179                     mrOleObjectInfo.maTargetLink = getFilter().getAbsoluteUrl( pRelation->maTarget );
180                 }
181                 else
182                 {
183                     OUString aFragmentPath = getFragmentPathFromRelation( *pRelation );
184                     if( aFragmentPath.getLength() > 0 )
185                         getFilter().importBinaryData( mrOleObjectInfo.maEmbeddedData, aFragmentPath );
186                 }
187             }
188             mrOleObjectInfo.maName = aAttribs.getXString( XML_name, OUString() );
189             mrOleObjectInfo.maProgId = aAttribs.getXString( XML_progId, OUString() );
190             mrOleObjectInfo.mbShowAsIcon = aAttribs.getBool( XML_showAsIcon, false );
191             xRet.set( this );
192         }
193 		break;
194 
195         case PPT_TOKEN( embed ):
196             OSL_ENSURE( !mrOleObjectInfo.mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
197         break;
198 
199         case PPT_TOKEN( link ):
200             OSL_ENSURE( mrOleObjectInfo.mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
201             mrOleObjectInfo.mbAutoUpdate = aAttribs.getBool( XML_updateAutomatic, false );
202         break;
203 	}
204     return xRet;
205 }
206 
207 // ============================================================================
208 
DiagramGraphicDataContext(ContextHandler & rParent,ShapePtr pShapePtr)209 DiagramGraphicDataContext::DiagramGraphicDataContext( ContextHandler& rParent, ShapePtr pShapePtr )
210 : ShapeContext( rParent, ShapePtr(), pShapePtr )
211 {
212 	pShapePtr->setDiagramType();
213 }
214 
~DiagramGraphicDataContext()215 DiagramGraphicDataContext::~DiagramGraphicDataContext()
216 {
217 }
218 
loadDiagram()219 DiagramPtr DiagramGraphicDataContext::loadDiagram()
220 {
221 	DiagramPtr pDiagram( new Diagram() );
222     XmlFilterBase& rFilter = getFilter();
223 
224 	// data
225     OUString sDmPath = getFragmentPathFromRelId( msDm );
226 	if( sDmPath.getLength() > 0 )
227 	{
228 		DiagramDataPtr pData( new DiagramData() );
229 		pDiagram->setData( pData );
230         rFilter.importFragment( new DiagramDataFragmentHandler( rFilter, sDmPath, pData ) );
231 	}
232 	// layout
233     OUString sLoPath = getFragmentPathFromRelId( msLo );
234 	if( sLoPath.getLength() > 0 )
235 	{
236 		DiagramLayoutPtr pLayout( new DiagramLayout() );
237 		pDiagram->setLayout( pLayout );
238         rFilter.importFragment( new DiagramLayoutFragmentHandler( rFilter, sLoPath, pLayout ) );
239 	}
240 	// style
241     OUString sQsPath = getFragmentPathFromRelId( msQs );
242 	if( sQsPath.getLength() > 0 )
243 	{
244 		DiagramQStylesPtr pStyles( new DiagramQStyles() );
245 		pDiagram->setQStyles( pStyles );
246         rFilter.importFragment( new DiagramQStylesFragmentHandler( rFilter, sQsPath, pStyles ) );
247 	}
248 	// colors
249     OUString sCsPath = getFragmentPathFromRelId( msCs );
250 	if( sCsPath.getLength() > 0 )
251 	{
252 		DiagramColorsPtr pColors( new DiagramColors() );
253 		pDiagram->setColors( pColors );
254         rFilter.importFragment( new DiagramColorsFragmentHandler( rFilter, sCsPath, pColors ) ) ;
255 	}
256 
257 	return pDiagram;
258 }
259 
260 
createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)261 Reference< XFastContextHandler > DiagramGraphicDataContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
262 	throw (SAXException, RuntimeException)
263 {
264 	Reference< XFastContextHandler > xRet;
265 
266 	switch( aElementToken )
267 	{
268 	case DGM_TOKEN( relIds ):
269 	{
270 		msDm = xAttribs->getOptionalValue( R_TOKEN( dm ) );
271 		msLo = xAttribs->getOptionalValue( R_TOKEN( lo ) );
272 		msQs = xAttribs->getOptionalValue( R_TOKEN( qs ) );
273 		msCs = xAttribs->getOptionalValue( R_TOKEN( cs ) );
274 		DiagramPtr pDiagram = loadDiagram();
275 		pDiagram->addTo( mpShapePtr );
276 		OSL_TRACE("diagram added shape %s of type %s", OUSTRING_TO_CSTR( mpShapePtr->getName() ),
277 				  OUSTRING_TO_CSTR( mpShapePtr->getServiceName() ) );
278 		break;
279 	}
280 	default:
281 		break;
282 	}
283 
284 	if( !xRet.is() )
285 		xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
286 
287 	return xRet;
288 }
289 
290 // ============================================================================
291 
ChartGraphicDataContext(ContextHandler & rParent,const ShapePtr & rxShape,bool bEmbedShapes)292 ChartGraphicDataContext::ChartGraphicDataContext( ContextHandler& rParent, const ShapePtr& rxShape, bool bEmbedShapes ) :
293     ShapeContext( rParent, ShapePtr(), rxShape ),
294     mrChartShapeInfo( rxShape->setChartType( bEmbedShapes ) )
295 {
296 }
297 
createFastChildContext(::sal_Int32 nElement,const Reference<XFastAttributeList> & rxAttribs)298 Reference< XFastContextHandler > ChartGraphicDataContext::createFastChildContext( ::sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
299     throw (SAXException, RuntimeException)
300 {
301     if( nElement == C_TOKEN( chart ) )
302     {
303         AttributeList aAttribs( rxAttribs );
304         mrChartShapeInfo.maFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
305     }
306     return 0;
307 }
308 
309 // ============================================================================
310 
311 } // namespace drawingml
312 } // namespace oox
313 
314