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