1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/drawingml/diagram/datamodelcontext.hxx"
29 #include "oox/helper/attributelist.hxx"
30 #include "oox/drawingml/fillpropertiesgroupcontext.hxx"
31 #include "oox/drawingml/shapepropertiescontext.hxx"
32 #include "oox/drawingml/textbodycontext.hxx"
33 
34 using namespace ::oox::core;
35 using namespace ::com::sun::star::xml::sax;
36 using namespace ::com::sun::star::uno;
37 using ::rtl::OUString;
38 
39 namespace oox { namespace drawingml {
40 
41 // CL_Cxn
42 class CxnContext
43     : public ContextHandler
44 {
45 public:
46     CxnContext( ContextHandler& rParent,
47 				const Reference< XFastAttributeList >& xAttribs,
48 				const dgm::ConnectionPtr & pConnection )
49         : ContextHandler( rParent )
50 		, mpConnection( pConnection )
51 		{
52 			sal_Int32 nType = xAttribs->getOptionalValueToken( XML_type, XML_parOf );
53 			pConnection->mnType = nType;
54 			pConnection->msModelId = xAttribs->getOptionalValue( XML_modelId );
55 			pConnection->msSourceId = xAttribs->getOptionalValue( XML_srcId );
56 			pConnection->msDestId  = xAttribs->getOptionalValue( XML_destId );
57 			pConnection->msPresId  = xAttribs->getOptionalValue( XML_presId );
58 			pConnection->msSibTransId  = xAttribs->getOptionalValue( XML_sibTransId );
59 			AttributeList attribs( xAttribs );
60 			pConnection->mnSourceOrder = attribs.getInteger( XML_srcOrd, 0 );
61 			pConnection->mnDestOrder = attribs.getInteger( XML_destOrd, 0 );
62 		}
63 
64     virtual Reference< XFastContextHandler > SAL_CALL
65 	createFastChildContext( sal_Int32 aElementToken,
66 							const Reference< XFastAttributeList >& /*xAttribs*/ )
67 		throw (SAXException, RuntimeException)
68 		{
69 			Reference< XFastContextHandler > xRet;
70 
71 			switch( aElementToken )
72 			{
73 			case DGM_TOKEN( extLst ):
74                 return xRet;
75 			default:
76 				break;
77 			}
78 			if( !xRet.is() )
79 				xRet.set( this );
80 			return xRet;
81 		}
82 private:
83 	dgm::ConnectionPtr mpConnection;
84 };
85 
86 
87 // CT_CxnList
88 class CxnListContext
89     : public ContextHandler
90 {
91 public:
92     CxnListContext( ContextHandler& rParent,  dgm::Connections & aConnections )
93         : ContextHandler( rParent )
94 		, maConnections( aConnections )
95 		{
96 		}
97     virtual Reference< XFastContextHandler > SAL_CALL
98 	createFastChildContext( sal_Int32 aElementToken,
99 							const Reference< XFastAttributeList >& xAttribs )
100 		throw (SAXException, RuntimeException)
101 		{
102 			Reference< XFastContextHandler > xRet;
103 
104 			switch( aElementToken )
105 			{
106 			case DGM_TOKEN( cxn ):
107 			{
108 				dgm::ConnectionPtr pConnection( new dgm::Connection() );
109 				maConnections.push_back( pConnection );
110                 xRet.set( new CxnContext( *this, xAttribs, pConnection ) );
111 				break;
112 			}
113 			default:
114 				break;
115 			}
116 			if( !xRet.is() )
117 				xRet.set( this );
118 			return xRet;
119 		}
120 
121 private:
122 	dgm::Connections  & maConnections;
123 };
124 
125 
126 
127 // CL_Pt
128 class PtContext
129     : public ContextHandler
130 {
131 public:
132     PtContext( ContextHandler& rParent,
133 			   const Reference< XFastAttributeList >& xAttribs,
134 			   const dgm::PointPtr & pPoint)
135         : ContextHandler( rParent )
136 		, mpPoint( pPoint )
137 		{
138 			mpPoint->setModelId( xAttribs->getOptionalValue( XML_modelId ) );
139 			//
140 			// the default type is XML_node
141 			sal_Int32 nType  = xAttribs->getOptionalValueToken( XML_type, XML_node );
142 			mpPoint->setType( nType );
143 
144 			// ignore the cxnId unless it is this type. See 5.15.3.1.3 in Primer
145 			if( ( nType == XML_parTrans ) || ( nType == XML_sibTrans ) )
146 			{
147 				mpPoint->setCnxId( xAttribs->getOptionalValue( XML_cxnId ) );
148 			}
149 		}
150 
151 
152     virtual Reference< XFastContextHandler > SAL_CALL
153 	createFastChildContext( sal_Int32 aElementToken,
154 							const Reference< XFastAttributeList >& /*xAttribs*/ )
155 		throw (SAXException, RuntimeException)
156 		{
157 			Reference< XFastContextHandler > xRet;
158 
159 			switch( aElementToken )
160 			{
161 			case DGM_TOKEN( extLst ):
162                 return xRet;
163 			case DGM_TOKEN( prSet ):
164 				// TODO
165 				// CT_ElemPropSet
166 				break;
167 			case DGM_TOKEN( spPr ):
168 				OSL_TRACE( "shape props for point");
169                 xRet = new ShapePropertiesContext( *this, *mpPoint->getShape() );
170 				break;
171 			case DGM_TOKEN( t ):
172 			{
173 				OSL_TRACE( "shape text body for point");
174                 TextBodyPtr xTextBody( new TextBody );
175                 mpPoint->getShape()->setTextBody( xTextBody );
176                 xRet = new TextBodyContext( *this, *xTextBody );
177 				break;
178 			}
179 			default:
180 				break;
181 			}
182 			if( !xRet.is() )
183 				xRet.set( this );
184 			return xRet;
185 		}
186 
187 private:
188 	dgm::PointPtr mpPoint;
189 };
190 
191 
192 
193 // CT_PtList
194 class PtListContext
195     : public ContextHandler
196 {
197 public:
198     PtListContext( ContextHandler& rParent,  dgm::Points & aPoints)
199         : ContextHandler( rParent )
200 		, maPoints( aPoints )
201 		{
202 		}
203     virtual Reference< XFastContextHandler > SAL_CALL
204 	createFastChildContext( sal_Int32 aElementToken,
205 							const Reference< XFastAttributeList >& xAttribs )
206 		throw (SAXException, RuntimeException)
207 		{
208 			Reference< XFastContextHandler > xRet;
209 
210 			switch( aElementToken )
211 			{
212 			case DGM_TOKEN( pt ):
213 			{
214 				// CT_Pt
215 				dgm::PointPtr pPoint( new dgm::Point() );
216 				maPoints.push_back( pPoint );
217                 xRet.set( new PtContext( *this, xAttribs, pPoint ) );
218 				break;
219 			}
220 			default:
221 				break;
222 			}
223 			if( !xRet.is() )
224 				xRet.set( this );
225 			return xRet;
226 		}
227 
228 private:
229 	dgm::Points  & maPoints;
230 };
231 
232 // CT_BackgroundFormatting
233 class BackgroundFormattingContext
234     : public ContextHandler
235 {
236 public:
237     BackgroundFormattingContext( ContextHandler& rParent, DiagramDataPtr & pModel )
238         : ContextHandler( rParent )
239 		, mpDataModel( pModel )
240 		{
241 			OSL_ENSURE( pModel, "the data model MUST NOT be NULL" );
242 		}
243 
244     virtual Reference< XFastContextHandler > SAL_CALL
245 	createFastChildContext( sal_Int32 aElementToken,
246 							const Reference< XFastAttributeList >& xAttribs )
247 		throw (SAXException, RuntimeException)
248 		{
249 			Reference< XFastContextHandler > xRet;
250 
251 			switch( aElementToken )
252 			{
253 			case A_TOKEN( blipFill ):
254 			case A_TOKEN( gradFill ):
255 			case A_TOKEN( grpFill ):
256 			case A_TOKEN( noFill ):
257 			case A_TOKEN( pattFill ):
258 			case A_TOKEN( solidFill ):
259 				// EG_FillProperties
260                 xRet.set( FillPropertiesContext::createFillContext(
261                     *this, aElementToken, xAttribs, *mpDataModel->getFillProperties() ) );
262 				break;
263 			case A_TOKEN( effectDag ):
264 			case A_TOKEN( effectLst ):
265 				// TODO
266 				// EG_EffectProperties
267 				break;
268 			default:
269 				break;
270 			}
271 			if( !xRet.is() )
272 				xRet.set( this );
273 			return xRet;
274 		}
275 private:
276 	DiagramDataPtr mpDataModel;
277 };
278 
279 
280 
281 DataModelContext::DataModelContext( ContextHandler& rParent,
282 									const DiagramDataPtr & pDataModel )
283     : ContextHandler( rParent )
284 	, mpDataModel( pDataModel )
285 {
286 	OSL_ENSURE( pDataModel, "Data Model must not be NULL" );
287 }
288 
289 
290 DataModelContext::~DataModelContext()
291 {
292 	// some debug
293 	mpDataModel->dump();
294 }
295 
296 
297 Reference< XFastContextHandler > SAL_CALL
298 DataModelContext::createFastChildContext( ::sal_Int32 aElement,
299 										  const Reference< XFastAttributeList >& /*xAttribs*/ )
300 	throw ( SAXException, RuntimeException)
301 {
302 	Reference< XFastContextHandler > xRet;
303 
304 	switch( aElement )
305 	{
306 	case DGM_TOKEN( cxnLst ):
307 		// CT_CxnList
308         xRet.set( new CxnListContext( *this, mpDataModel->getConnections() ) );
309 		break;
310 	case DGM_TOKEN( ptLst ):
311 		// CT_PtList
312         xRet.set( new PtListContext( *this, mpDataModel->getPoints() ) );
313 		break;
314 	case DGM_TOKEN( bg ):
315 		// CT_BackgroundFormatting
316         xRet.set( new BackgroundFormattingContext( *this, mpDataModel ) );
317 		break;
318 	case DGM_TOKEN( whole ):
319 		// CT_WholeE2oFormatting
320 		// TODO
321         return xRet;
322 	case DGM_TOKEN( extLst ):
323         return xRet;
324 	default:
325 		break;
326 	}
327 
328 	if( !xRet.is() )
329 		xRet.set( this );
330 
331 	return xRet;
332 }
333 
334 } }
335