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 "layoutnodecontext.hxx"
29 
30 #include "oox/helper/attributelist.hxx"
31 #include "oox/drawingml/diagram/diagram.hxx"
32 #include "oox/drawingml/shapecontext.hxx"
33 #include "diagramdefinitioncontext.hxx"
34 
35 using namespace ::oox::core;
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::xml::sax;
38 using ::rtl::OUString;
39 
40 namespace oox { namespace drawingml {
41 
42 class IfContext
43 	: public LayoutNodeContext
44 {
45 public:
46     IfContext( ContextHandler& rParent,
47 			   const Reference< XFastAttributeList >& xAttribs,
48 			   const LayoutAtomPtr & pNode )
49         : LayoutNodeContext( rParent, xAttribs, pNode )
50 		{
51 			ConditionAtomPtr pAtom( boost::dynamic_pointer_cast< ConditionAtom >(pNode) );
52 			OSL_ENSURE( pAtom, "Must pass a ConditionAtom" );
53 
54 			pAtom->iterator().loadFromXAttr( xAttribs );
55 			pAtom->cond().loadFromXAttr( xAttribs );
56 		}
57 };
58 
59 
60 
61 class AlgorithmContext
62     : public ContextHandler
63 {
64 public:
65     AlgorithmContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
66         : ContextHandler( rParent )
67 		, mnRevision( 0 )
68 		, mnType( 0 )
69 		, mpNode( pNode )
70 		{
71 			AttributeList aAttribs( xAttribs );
72 			mnRevision = aAttribs.getInteger( XML_rev, 0 );
73 			mnType = xAttribs->getOptionalValueToken( XML_type, 0 );
74 		}
75 
76 private:
77 	sal_Int32     mnRevision;
78 	sal_Int32     mnType;
79 	LayoutAtomPtr mpNode;
80 };
81 
82 
83 class ChooseContext
84     : public ContextHandler
85 {
86 public:
87     ChooseContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
88         : ContextHandler( rParent )
89 		, mbHasElse( false )
90 		, mpNode( pNode )
91 		{
92 			msName = xAttribs->getOptionalValue( XML_name );
93 		}
94 
95 	virtual Reference< XFastContextHandler > SAL_CALL
96 	createFastChildContext( ::sal_Int32 aElement,
97 							const Reference< XFastAttributeList >& xAttribs )
98 		throw (SAXException, RuntimeException)
99 		{
100 			Reference< XFastContextHandler > xRet;
101 
102 			switch( aElement )
103 			{
104 			case XML_if:
105 			{
106 				// CT_When
107 				LayoutAtomPtr pAtom( new ConditionAtom( false ) );
108 				mpNode->addChild( pAtom );
109                 xRet.set( new IfContext( *this, xAttribs, pAtom ) );
110 				break;
111 			}
112 			case XML_else:
113 				// CT_Otherwise
114 				if( !mbHasElse )
115 				{
116 					LayoutAtomPtr pAtom( new ConditionAtom( true ) );
117 					mpNode->addChild( pAtom );
118                     xRet.set( new IfContext( *this, xAttribs, pAtom ) );
119 					mbHasElse = true;
120 				}
121 				else
122 				{
123 					OSL_TRACE( "ignoring second else clause" );
124 				}
125 				break;
126 			default:
127 				break;
128 			}
129 
130 			if( !xRet.is() )
131 				xRet.set(this);
132 
133 			return xRet;
134 		}
135 private:
136 	bool     mbHasElse;
137 	OUString msName;
138 	LayoutAtomPtr mpNode;
139 };
140 
141 
142 
143 
144 class ForEachContext
145 	: public LayoutNodeContext
146 {
147 public:
148     ForEachContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
149         : LayoutNodeContext( rParent, xAttribs, pNode )
150 		{
151 			ForEachAtomPtr pAtom( boost::dynamic_pointer_cast< ForEachAtom >(pNode) );
152 			OSL_ENSURE( pAtom, "Must pass a ForEachAtom" );
153 			xAttribs->getOptionalValue( XML_ref );
154 
155 			pAtom->iterator().loadFromXAttr( xAttribs );
156 		}
157 };
158 
159 
160 // CT_LayoutVariablePropertySet
161 class LayoutVariablePropertySetContext
162     : public ContextHandler
163 {
164 public:
165     LayoutVariablePropertySetContext( ContextHandler& rParent, LayoutNode::VarMap & aVar )
166         : ContextHandler( rParent )
167 		, mVariables( aVar )
168 		{
169 		}
170 
171 	virtual ~LayoutVariablePropertySetContext()
172 		{
173 		}
174 
175 	virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs )
176 		throw (SAXException, RuntimeException)
177 		{
178 			Reference< XFastContextHandler > xRet;
179 
180             sal_Int32 nIdx =  LayoutNodeContext::tagToVarIdx( getBaseToken( aElement ) );
181 			if( nIdx != -1 )
182 			{
183 				mVariables[ nIdx ] = makeAny( xAttribs->getOptionalValue( XML_val ) );
184 			}
185 			if( !xRet.is() )
186 				xRet.set(this);
187 
188 			return xRet;
189 		}
190 private:
191 	LayoutNode::VarMap & mVariables;
192 };
193 
194 
195 // CT_LayoutNode
196 LayoutNodeContext::LayoutNodeContext( ContextHandler& rParent,
197 									  const Reference< XFastAttributeList >& xAttribs,
198 									  const LayoutAtomPtr &pNode )
199     : ContextHandler( rParent )
200 	, mpNode( pNode )
201 {
202 	OSL_ENSURE( pNode, "Node must NOT be NULL" );
203 	mpNode->setName( xAttribs->getOptionalValue( XML_name ) );
204 	// TODO shall we even bother?
205 	// b or t
206 //	sal_Int32 nChOrder = xAttributes->getOptionalValueToken( XML_chOrder, XML_b );
207 //	OUString sMoveWith = xAttributes->getOptionalValue( XML_moveWith );
208 //	OUString sStyleLbl = xAttributes->getOptionalValue( XML_styleLbl );
209 }
210 
211 
212 LayoutNodeContext::~LayoutNodeContext()
213 {
214 }
215 
216 void SAL_CALL LayoutNodeContext::endFastElement( ::sal_Int32 )
217 	throw (SAXException, RuntimeException)
218 {
219 
220 }
221 
222 /** convert the XML tag to a variable index in the array
223  * @param aTag the tag, wihout namespace
224  * @return the variable index. -1 is an error
225  */
226 sal_Int32 LayoutNodeContext::tagToVarIdx( sal_Int32 aTag )
227 {
228 	sal_Int32 nIdx = -1;
229 	switch( aTag )
230 	{
231 	case DGM_TOKEN( animLvl ):
232 		nIdx = LayoutNode::VAR_animLvl;
233 		break;
234 	case DGM_TOKEN( animOne ):
235 		nIdx = LayoutNode::VAR_animOne;
236 		break;
237 	case DGM_TOKEN( bulletEnabled ):
238 		nIdx = LayoutNode::VAR_bulletEnabled;
239 		break;
240 	case DGM_TOKEN( chMax ):
241 		nIdx = LayoutNode::VAR_chMax;
242 		break;
243 	case DGM_TOKEN( chPref ):
244 		nIdx = LayoutNode::VAR_chPref;
245 		break;
246 	case DGM_TOKEN( dir ):
247 		nIdx = LayoutNode::VAR_dir;
248 		break;
249 	case DGM_TOKEN( hierBranch ):
250 		nIdx = LayoutNode::VAR_hierBranch;
251 		break;
252 	case DGM_TOKEN( orgChart ):
253 		nIdx = LayoutNode::VAR_orgChart;
254 		break;
255 	case DGM_TOKEN( resizeHandles ):
256 		nIdx = LayoutNode::VAR_resizeHandles;
257 		break;
258 	default:
259 		break;
260 	}
261 	return nIdx;
262 }
263 
264 
265 Reference< XFastContextHandler > SAL_CALL
266 LayoutNodeContext::createFastChildContext( ::sal_Int32 aElement,
267 												  const Reference< XFastAttributeList >& xAttribs )
268 	throw (SAXException, RuntimeException)
269 {
270 	Reference< XFastContextHandler > xRet;
271 
272 	switch( aElement )
273 	{
274 	case DGM_TOKEN( layoutNode ):
275 	{
276 		LayoutNodePtr pNode( new LayoutNode() );
277 		mpNode->addChild( pNode );
278         xRet.set( new LayoutNodeContext( *this, xAttribs, pNode ) );
279 		break;
280 	}
281 	case DGM_TOKEN( shape ):
282 	{
283 		ShapePtr pShape( new Shape() );
284         xRet.set( new ShapeContext( *this, ShapePtr(), pShape ) );
285 		break;
286 	}
287 	case DGM_TOKEN( extLst ):
288         return xRet;
289 	case DGM_TOKEN( alg ):
290 	{
291 		// CT_Algorithm
292 		LayoutAtomPtr pAtom( new AlgAtom );
293 		mpNode->addChild( pAtom );
294         xRet.set( new AlgorithmContext( *this, xAttribs, pAtom ) );
295 		break;
296 	}
297 	case DGM_TOKEN( choose ):
298 	{
299 		// CT_Choose
300 		LayoutAtomPtr pAtom( new ChooseAtom );
301 		mpNode->addChild( pAtom );
302         xRet.set( new ChooseContext( *this, xAttribs, pAtom ) );
303  		break;
304 	}
305 	case DGM_TOKEN( forEach ):
306 	{
307 		// CT_ForEach
308 		LayoutAtomPtr pAtom( new ForEachAtom );
309 		mpNode->addChild( pAtom );
310         xRet.set( new ForEachContext( *this, xAttribs, pAtom ) );
311 		break;
312 	}
313 	case DGM_TOKEN( constrLst ):
314 		// CT_Constraints
315 		// TODO
316 		break;
317 	case DGM_TOKEN( presOf ):
318 	{
319 		// CT_PresentationOf
320 		// TODO
321 		xAttribs->getOptionalValue( XML_axis );
322 		xAttribs->getOptionalValue( XML_cnt );
323 		xAttribs->getOptionalValue( XML_hideLastTrans );
324 		xAttribs->getOptionalValue( XML_ptType );
325 		xAttribs->getOptionalValue( XML_st );
326 		xAttribs->getOptionalValue( XML_step );
327 		break;
328 	}
329 	case DGM_TOKEN( ruleLst ):
330 		// CT_Rules
331 		// TODO
332 		break;
333 	case DGM_TOKEN( varLst ):
334 	{
335 		LayoutNodePtr pNode( boost::dynamic_pointer_cast< LayoutNode >( mpNode ) );
336 		if( pNode )
337 		{
338             xRet.set( new LayoutVariablePropertySetContext( *this, pNode->variables() ) );
339 		}
340 		else
341 		{
342 			OSL_TRACE( "OOX: encountered a varLst in a non layoutNode context" );
343 		}
344 		break;
345 	}
346 	default:
347 		break;
348 	}
349 	if( !xRet.is() )
350 		xRet.set(this);
351 
352 	return xRet;
353 }
354 
355 
356 } }
357