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