Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "oox/ppt/timenodelistcontext.hxx"
21 :
22 : #include "comphelper/anytostring.hxx"
23 : #include "cppuhelper/exc_hlp.hxx"
24 : #include <osl/diagnose.h>
25 : #include <rtl/math.hxx>
26 :
27 : #include <com/sun/star/animations/XTimeContainer.hpp>
28 : #include <com/sun/star/animations/XAnimationNode.hpp>
29 : #include <com/sun/star/animations/XAnimateColor.hpp>
30 : #include <com/sun/star/animations/XAnimateSet.hpp>
31 : #include <com/sun/star/animations/XAnimateTransform.hpp>
32 : #include <com/sun/star/animations/AnimationTransformType.hpp>
33 : #include <com/sun/star/animations/AnimationCalcMode.hpp>
34 : #include <com/sun/star/animations/AnimationColorSpace.hpp>
35 : #include <com/sun/star/animations/AnimationNodeType.hpp>
36 : #include <com/sun/star/animations/XCommand.hpp>
37 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 : #include <com/sun/star/presentation/EffectCommands.hpp>
39 : #include <com/sun/star/beans/NamedValue.hpp>
40 :
41 : #include "oox/helper/attributelist.hxx"
42 : #include "oox/core/xmlfilterbase.hxx"
43 : #include "oox/drawingml/drawingmltypes.hxx"
44 : #include "oox/drawingml/colorchoicecontext.hxx"
45 : #include "oox/ppt/slidetransition.hxx"
46 :
47 : #include "animvariantcontext.hxx"
48 : #include "commonbehaviorcontext.hxx"
49 : #include "conditioncontext.hxx"
50 : #include "commontimenodecontext.hxx"
51 : #include "timeanimvaluecontext.hxx"
52 : #include "animationtypes.hxx"
53 :
54 : using namespace ::oox::core;
55 : using namespace ::oox::drawingml;
56 : using namespace ::com::sun::star;
57 : using namespace ::com::sun::star::uno;
58 : using namespace ::com::sun::star::lang;
59 : using namespace ::com::sun::star::animations;
60 : using namespace ::com::sun::star::presentation;
61 : using namespace ::com::sun::star::xml::sax;
62 : using ::com::sun::star::beans::NamedValue;
63 :
64 : namespace oox { namespace ppt {
65 :
66 : struct AnimColor
67 : {
68 0 : AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
69 0 : : colorSpace( cs ), one( o ), two( t ), three( th )
70 : {
71 0 : }
72 :
73 0 : Any get()
74 : {
75 : sal_Int32 nColor;
76 0 : Sequence< double > aHSL( 3 );
77 0 : Any aColor;
78 :
79 0 : switch( colorSpace )
80 : {
81 : case AnimationColorSpace::HSL:
82 0 : aHSL[ 0 ] = double(one) / 100000;
83 0 : aHSL[ 1 ] = double(two) / 100000;
84 0 : aHSL[ 2 ] = double(three) / 100000;
85 0 : aColor = Any(aHSL);
86 0 : break;
87 : case AnimationColorSpace::RGB:
88 0 : nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
89 0 : | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
90 0 : | ( ( ( three * 128 ) / 1000 ) & 0xff );
91 0 : aColor = Any(nColor);
92 0 : break;
93 : default:
94 0 : nColor = 0;
95 0 : aColor = Any( nColor );
96 0 : break;
97 : }
98 0 : return aColor;
99 : }
100 :
101 : sal_Int16 colorSpace;
102 : sal_Int32 one;
103 : sal_Int32 two;
104 : sal_Int32 three;
105 : };
106 :
107 :
108 : /** CT_TLMediaNodeAudio
109 : CT_TLMediaNodeVideo */
110 0 : class MediaNodeContext
111 : : public TimeNodeContext
112 : {
113 : public:
114 0 : MediaNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
115 : const Reference< XFastAttributeList >& xAttribs,
116 : const TimeNodePtr & pNode )
117 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
118 : , mbIsNarration( false )
119 0 : , mbFullScrn( false )
120 : {
121 0 : AttributeList attribs( xAttribs );
122 :
123 0 : switch( aElement )
124 : {
125 : case PPT_TOKEN( audio ):
126 0 : mbIsNarration = attribs.getBool( XML_isNarration, false );
127 0 : break;
128 : case PPT_TOKEN( video ):
129 0 : mbFullScrn = attribs.getBool( XML_fullScrn, false );
130 0 : break;
131 : default:
132 0 : break;
133 0 : }
134 0 : }
135 :
136 0 : virtual void onEndElement() SAL_OVERRIDE
137 : {
138 0 : sal_Int32 aElement = getCurrentElement();
139 : if( aElement == PPT_TOKEN( audio ) )
140 : {
141 : // TODO deal with mbIsNarration
142 : }
143 : else if( aElement == PPT_TOKEN( video ) )
144 : {
145 : // TODO deal with mbFullScrn
146 : }
147 0 : }
148 :
149 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
150 : {
151 0 : switch ( aElementToken )
152 : {
153 : case PPT_TOKEN( cBhvr ):
154 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
155 : default:
156 0 : break;
157 : }
158 :
159 0 : return this;
160 : }
161 :
162 : private:
163 : bool mbIsNarration;
164 : bool mbFullScrn;
165 : };
166 :
167 :
168 : /** CT_TLSetBehavior
169 : */
170 : class SetTimeNodeContext
171 : : public TimeNodeContext
172 : {
173 : public:
174 0 : SetTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
175 : const Reference< XFastAttributeList >& xAttribs,
176 : const TimeNodePtr & pNode )
177 0 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
178 : {
179 :
180 0 : }
181 :
182 0 : virtual ~SetTimeNodeContext() throw ()
183 0 : {
184 0 : if( maTo.hasValue() )
185 : {
186 : // TODO
187 : // HACK !!! discard and refactor
188 0 : OUString aString;
189 0 : if( maTo >>= aString )
190 : {
191 : OSL_TRACE( "Magic conversion %s", OUSTRING_TO_CSTR( aString ) );
192 0 : maTo = makeAny( aString == "visible" ? sal_True : sal_False );
193 0 : if( !maTo.has<sal_Bool>() )
194 : OSL_TRACE( "conversion failed" );
195 : }
196 0 : mpNode->setTo( maTo );
197 : }
198 :
199 0 : }
200 :
201 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
202 : {
203 0 : switch ( aElementToken )
204 : {
205 : case PPT_TOKEN( cBhvr ):
206 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
207 : case PPT_TOKEN( to ):
208 : // CT_TLAnimVariant
209 0 : return new AnimVariantContext( *this, aElementToken, maTo );
210 : default:
211 0 : break;
212 : }
213 :
214 0 : return this;
215 : }
216 : private:
217 : Any maTo;
218 : };
219 :
220 : /** CT_TLCommandBehavior
221 : */
222 : class CmdTimeNodeContext
223 : : public TimeNodeContext
224 : {
225 : public:
226 0 : CmdTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
227 : const Reference< XFastAttributeList >& xAttribs,
228 : const TimeNodePtr & pNode )
229 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
230 0 : , maType(0)
231 : {
232 0 : switch ( aElement )
233 : {
234 : case PPT_TOKEN( cmd ):
235 0 : msCommand = xAttribs->getOptionalValue( XML_cmd );
236 0 : maType = xAttribs->getOptionalValueToken( XML_type, 0 );
237 0 : break;
238 : default:
239 0 : break;
240 : }
241 0 : }
242 :
243 0 : virtual ~CmdTimeNodeContext() throw ()
244 0 : {
245 0 : }
246 :
247 0 : virtual void onEndElement() SAL_OVERRIDE
248 : {
249 0 : if( isCurrentElement( PPT_TOKEN( cmd ) ) )
250 : {
251 : try {
252 : // see sd/source/filter/ppt/pptinanimations.cxx
253 : // in AnimationImporter::importCommandContainer()
254 : // REFACTOR?
255 : // a good chunk of this code has been copied verbatim *sigh*
256 0 : sal_Int16 nCommand = EffectCommands::CUSTOM;
257 0 : NamedValue aParamValue;
258 :
259 0 : switch( maType )
260 : {
261 : case XML_verb:
262 0 : aParamValue.Name = "Verb";
263 : // TODO make sure msCommand has what we want
264 0 : aParamValue.Value <<= msCommand.toInt32();
265 0 : nCommand = EffectCommands::VERB;
266 0 : break;
267 : case XML_evt:
268 : case XML_call:
269 0 : if ( msCommand == "onstopaudio" )
270 : {
271 0 : nCommand = EffectCommands::STOPAUDIO;
272 : }
273 0 : else if ( msCommand == "play" )
274 : {
275 0 : nCommand = EffectCommands::PLAY;
276 : }
277 0 : else if( msCommand.equalsAscii( "playFrom" ) )
278 : {
279 0 : const OUString aMediaTime( msCommand.copy( 9, msCommand.getLength() - 10 ) );
280 : rtl_math_ConversionStatus eStatus;
281 0 : double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
282 0 : if( eStatus == rtl_math_ConversionStatus_Ok )
283 : {
284 0 : aParamValue.Name = "MediaTime";
285 0 : aParamValue.Value <<= fMediaTime;
286 : }
287 0 : nCommand = EffectCommands::PLAY;
288 : }
289 0 : else if ( msCommand == "togglePause" )
290 : {
291 0 : nCommand = EffectCommands::TOGGLEPAUSE;
292 : }
293 0 : else if ( msCommand == "stop" )
294 : {
295 0 : nCommand = EffectCommands::STOP;
296 : }
297 0 : break;
298 : }
299 0 : mpNode->getNodeProperties()[ NP_COMMAND ] = makeAny((sal_Int16)nCommand);
300 0 : if( nCommand == EffectCommands::CUSTOM )
301 : {
302 : OSL_TRACE("OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
303 0 : aParamValue.Name = "UserDefined";
304 0 : aParamValue.Value <<= msCommand;
305 : }
306 0 : if( aParamValue.Value.hasValue() )
307 : {
308 0 : Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
309 0 : mpNode->getNodeProperties()[ NP_PARAMETER ] = makeAny( aParamSeq );
310 0 : }
311 : }
312 0 : catch( RuntimeException& )
313 : {
314 : OSL_TRACE( "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
315 : }
316 : }
317 0 : }
318 :
319 :
320 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
321 : {
322 0 : switch ( aElementToken )
323 : {
324 : case PPT_TOKEN( cBhvr ):
325 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
326 : default:
327 0 : break;
328 : }
329 :
330 0 : return this;
331 : }
332 :
333 : private:
334 : OUString msCommand;
335 : sal_Int32 maType;
336 : };
337 :
338 :
339 : /** CT_TLTimeNodeSequence
340 : */
341 : class SequenceTimeNodeContext
342 : : public TimeNodeContext
343 : {
344 : public:
345 0 : SequenceTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
346 : const Reference< XFastAttributeList >& xAttribs,
347 : const TimeNodePtr & pNode )
348 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
349 : , mnNextAc(0)
350 0 : , mnPrevAc(0)
351 : {
352 0 : AttributeList attribs(xAttribs);
353 0 : mbConcurrent = attribs.getBool( XML_concurrent, false );
354 0 : mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
355 0 : mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
356 0 : }
357 :
358 0 : virtual ~SequenceTimeNodeContext() throw()
359 0 : {
360 0 : }
361 :
362 :
363 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
364 : {
365 0 : switch ( aElementToken )
366 : {
367 : case PPT_TOKEN( cTn ):
368 0 : return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
369 : case PPT_TOKEN( nextCondLst ):
370 : return new CondListContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode,
371 0 : mpNode->getNextCondition() );
372 : case PPT_TOKEN( prevCondLst ):
373 : return new CondListContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode,
374 0 : mpNode->getPrevCondition() );
375 : default:
376 0 : break;
377 : }
378 :
379 0 : return this;
380 : }
381 : private:
382 : bool mbConcurrent;
383 : sal_Int32 mnNextAc, mnPrevAc;
384 : };
385 :
386 :
387 : /** CT_TLTimeNodeParallel
388 : * CT_TLTimeNodeExclusive
389 : */
390 0 : class ParallelExclTimeNodeContext
391 : : public TimeNodeContext
392 : {
393 : public:
394 0 : ParallelExclTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
395 : const Reference< XFastAttributeList >& xAttribs,
396 : const TimeNodePtr & pNode )
397 0 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
398 : {
399 0 : }
400 :
401 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
402 : {
403 0 : switch ( aElementToken )
404 : {
405 : case PPT_TOKEN( cTn ):
406 0 : return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
407 : default:
408 0 : break;
409 : }
410 :
411 0 : return this;
412 : }
413 :
414 : protected:
415 :
416 : };
417 :
418 :
419 : /** CT_TLAnimateColorBehavior */
420 : class AnimColorContext
421 : : public TimeNodeContext
422 : {
423 : public:
424 0 : AnimColorContext( FragmentHandler2& rParent, sal_Int32 aElement,
425 : const Reference< XFastAttributeList >& xAttribs,
426 : const TimeNodePtr & pNode ) throw()
427 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
428 0 : , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
429 0 : , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
430 : , mbHasByColor( false )
431 0 : , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
432 : {
433 0 : }
434 0 : virtual ~AnimColorContext() throw()
435 0 : {
436 0 : }
437 :
438 0 : virtual void onEndElement() SAL_OVERRIDE
439 : {
440 : //xParentNode
441 0 : if( isCurrentElement( mnElement ) )
442 : {
443 0 : NodePropertyMap & pProps(mpNode->getNodeProperties());
444 0 : pProps[ NP_DIRECTION ] = makeAny( mnDir == XML_cw );
445 0 : pProps[ NP_COLORINTERPOLATION ] = makeAny( mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB );
446 0 : const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
447 0 : if( maToClr.isUsed() )
448 0 : mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) );
449 0 : if( maFromClr.isUsed() )
450 0 : mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) );
451 0 : if( mbHasByColor )
452 0 : mpNode->setBy( m_byColor.get() );
453 : }
454 0 : }
455 :
456 :
457 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
458 : {
459 0 : switch ( aElementToken )
460 : {
461 : case PPT_TOKEN( hsl ):
462 : // CT_TLByHslColorTransform
463 : {
464 0 : if( mbHasByColor )
465 : {
466 0 : m_byColor.colorSpace = AnimationColorSpace::HSL;
467 0 : m_byColor.one = rAttribs.getInteger( XML_h, 0 );
468 0 : m_byColor.two = rAttribs.getInteger( XML_s, 0 );
469 0 : m_byColor.three = rAttribs.getInteger( XML_l, 0 );
470 : }
471 0 : return this;
472 : }
473 : case PPT_TOKEN( rgb ):
474 : {
475 0 : if( mbHasByColor )
476 : {
477 : // CT_TLByRgbColorTransform
478 0 : m_byColor.colorSpace = AnimationColorSpace::RGB;
479 0 : m_byColor.one = rAttribs.getInteger( XML_r, 0 );
480 0 : m_byColor.two = rAttribs.getInteger( XML_g, 0 );
481 0 : m_byColor.three = rAttribs.getInteger( XML_b, 0 );
482 : }
483 0 : return this;
484 : }
485 : case PPT_TOKEN( by ):
486 : // CT_TLByAnimateColorTransform
487 0 : mbHasByColor = true;
488 0 : return this;
489 : case PPT_TOKEN( cBhvr ):
490 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
491 : case PPT_TOKEN( to ):
492 : // CT_Color
493 0 : return new ColorContext( *this, maToClr );
494 : case PPT_TOKEN( from ):
495 : // CT_Color
496 0 : return new ColorContext( *this, maFromClr );
497 :
498 : default:
499 0 : break;
500 : }
501 :
502 0 : return this;
503 : }
504 :
505 :
506 : private:
507 : sal_Int32 mnColorSpace;
508 : sal_Int32 mnDir;
509 : bool mbHasByColor;
510 : AnimColor m_byColor;
511 : oox::drawingml::Color maToClr;
512 : oox::drawingml::Color maFromClr;
513 : };
514 :
515 :
516 : /** CT_TLAnimateBehavior */
517 : class AnimContext
518 : : public TimeNodeContext
519 : {
520 : public:
521 0 : AnimContext( FragmentHandler2& rParent, sal_Int32 aElement,
522 : const Reference< XFastAttributeList >& xAttribs,
523 : const TimeNodePtr & pNode ) throw()
524 0 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
525 : {
526 0 : NodePropertyMap & aProps( pNode->getNodeProperties() );
527 0 : sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
528 0 : if(nCalcMode)
529 : {
530 0 : sal_Int16 nEnum = 0;
531 0 : switch(nCalcMode)
532 : {
533 : case XML_discrete:
534 0 : nEnum = AnimationCalcMode::DISCRETE;
535 0 : break;
536 : case XML_lin:
537 0 : nEnum = AnimationCalcMode::LINEAR;
538 0 : break;
539 : case XML_fmla:
540 : default:
541 : // TODO what value is good ?
542 0 : nEnum = AnimationCalcMode::DISCRETE;
543 0 : break;
544 : }
545 0 : aProps[ NP_CALCMODE ] = makeAny(nEnum);
546 : }
547 0 : OUString aStr;
548 0 : aStr = xAttribs->getOptionalValue( XML_from );
549 0 : if( !aStr.isEmpty() )
550 : {
551 0 : pNode->setFrom( makeAny( aStr ) );
552 : }
553 0 : aStr = xAttribs->getOptionalValue( XML_by );
554 0 : if( !aStr.isEmpty() )
555 : {
556 0 : pNode->setBy( makeAny( aStr ) );
557 : }
558 0 : aStr = xAttribs->getOptionalValue( XML_to );
559 0 : if( !aStr.isEmpty() )
560 : {
561 0 : pNode->setTo( makeAny( aStr ) );
562 : }
563 0 : mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
564 0 : }
565 :
566 :
567 0 : virtual ~AnimContext() throw ()
568 0 : {
569 0 : ::std::list< TimeAnimationValue >::iterator iter, end;
570 0 : int nKeyTimes = maTavList.size();
571 0 : if( nKeyTimes > 0)
572 : {
573 : int i;
574 0 : Sequence< double > aKeyTimes( nKeyTimes );
575 0 : Sequence< Any > aValues( nKeyTimes );
576 :
577 0 : NodePropertyMap & aProps( mpNode->getNodeProperties() );
578 0 : end = maTavList.end();
579 0 : for(iter = maTavList.begin(), i=0; iter != end; ++iter,++i)
580 : {
581 : // TODO what to do if it is Timing_INFINITE ?
582 0 : Any aTime = GetTimeAnimateValueTime( iter->msTime );
583 0 : aTime >>= aKeyTimes[i];
584 0 : aValues[i] = iter->maValue;
585 :
586 0 : OUString aTest;
587 0 : iter->maValue >>= aTest;
588 0 : if( !aTest.isEmpty() )
589 : {
590 0 : aValues[i] = iter->maValue;
591 : }
592 : else
593 : {
594 0 : aProps[ NP_FORMULA ] <<= iter->msFormula;
595 : }
596 0 : }
597 0 : aProps[ NP_VALUES ] <<= aValues;
598 0 : aProps[ NP_KEYTIMES ] <<= aKeyTimes;
599 : }
600 0 : }
601 :
602 :
603 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
604 : {
605 0 : switch ( aElementToken )
606 : {
607 : case PPT_TOKEN( cBhvr ):
608 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
609 : case PPT_TOKEN( tavLst ):
610 0 : return new TimeAnimValueListContext ( *this, rAttribs.getFastAttributeList(), maTavList );
611 : default:
612 0 : break;
613 : }
614 :
615 0 : return this;
616 : }
617 : private:
618 : sal_Int32 mnValueType;
619 : TimeAnimationValueList maTavList;
620 : };
621 :
622 :
623 : /** CT_TLAnimateScaleBehavior */
624 : class AnimScaleContext
625 : : public TimeNodeContext
626 : {
627 : public:
628 0 : AnimScaleContext( FragmentHandler2& rParent, sal_Int32 aElement,
629 : const Reference< XFastAttributeList >& xAttribs,
630 : const TimeNodePtr & pNode ) throw()
631 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
632 0 : , mbZoomContents( false )
633 : {
634 0 : AttributeList attribs( xAttribs );
635 : // TODO what to do with mbZoomContents
636 0 : mbZoomContents = attribs.getBool( XML_zoomContents, false );
637 0 : pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
638 0 : = makeAny((sal_Int16)AnimationTransformType::SCALE);
639 0 : }
640 :
641 0 : virtual ~AnimScaleContext( ) throw( )
642 0 : {
643 0 : }
644 :
645 0 : virtual void onEndElement() SAL_OVERRIDE
646 : {
647 0 : if( isCurrentElement( mnElement ) )
648 : {
649 0 : if( maTo.hasValue() )
650 : {
651 0 : mpNode->setTo( maTo );
652 : }
653 0 : if( maBy.hasValue() )
654 : {
655 0 : mpNode->setBy( maBy );
656 : }
657 0 : if( maFrom.hasValue() )
658 : {
659 0 : mpNode->setFrom( maFrom );
660 : }
661 : }
662 0 : }
663 :
664 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
665 : {
666 0 : switch ( aElementToken )
667 : {
668 : case PPT_TOKEN( cBhvr ):
669 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
670 : case PPT_TOKEN( to ):
671 : {
672 : // CT_TLPoint
673 0 : awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
674 0 : maTo <<= p.X;
675 0 : maTo <<= p.Y;
676 0 : return this;
677 : }
678 : case PPT_TOKEN( from ):
679 : {
680 : // CT_TLPoint
681 0 : awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
682 0 : maFrom <<= p.X;
683 0 : maFrom <<= p.Y;
684 0 : return this;
685 : }
686 : case PPT_TOKEN( by ):
687 : {
688 : // CT_TLPoint
689 0 : awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
690 0 : maBy <<= p.X;
691 0 : maBy <<= p.Y;
692 0 : return this;
693 : }
694 : default:
695 0 : break;
696 : }
697 :
698 0 : return this;
699 : }
700 : private:
701 : Any maBy;
702 : Any maFrom;
703 : Any maTo;
704 : bool mbZoomContents;
705 : };
706 :
707 :
708 : /** CT_TLAnimateRotationBehavior */
709 : class AnimRotContext
710 : : public TimeNodeContext
711 : {
712 : public:
713 0 : AnimRotContext( FragmentHandler2& rParent, sal_Int32 aElement,
714 : const Reference< XFastAttributeList >& xAttribs,
715 : const TimeNodePtr & pNode ) throw()
716 0 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
717 : {
718 0 : AttributeList attribs( xAttribs );
719 :
720 0 : pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
721 0 : = makeAny((sal_Int16)AnimationTransformType::ROTATE);
722 : // see also DFF_msofbtAnimateRotationData in
723 : // sd/source/filter/ppt/pptinanimations.cxx
724 0 : if(attribs.hasAttribute( XML_by ) )
725 : {
726 0 : sal_Int32 nBy = attribs.getInteger( XML_by, 0 );
727 0 : pNode->setBy( makeAny( (double) nBy ) );
728 : }
729 0 : if(attribs.hasAttribute( XML_from ) )
730 : {
731 0 : sal_Int32 nFrom = attribs.getInteger( XML_from, 0 );
732 0 : pNode->setFrom( makeAny( (double) nFrom ) );
733 : }
734 0 : if(attribs.hasAttribute( XML_to ) )
735 : {
736 0 : sal_Int32 nTo = attribs.getInteger( XML_to, 0 );
737 0 : pNode->setTo( makeAny( (double) nTo ) );
738 0 : }
739 0 : }
740 :
741 0 : virtual ~AnimRotContext( ) throw( )
742 0 : {
743 0 : }
744 :
745 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
746 : {
747 0 : switch ( aElementToken )
748 : {
749 : case PPT_TOKEN( cBhvr ):
750 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
751 : default:
752 0 : break;
753 : }
754 :
755 0 : return this;
756 : }
757 : };
758 :
759 :
760 :
761 : /** CT_TLAnimateMotionBehavior */
762 : class AnimMotionContext
763 : : public TimeNodeContext
764 : {
765 : public:
766 0 : AnimMotionContext( FragmentHandler2& rParent, sal_Int32 aElement,
767 : const Reference< XFastAttributeList >& xAttribs,
768 : const TimeNodePtr & pNode ) throw()
769 0 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
770 : {
771 0 : pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
772 0 : = makeAny((sal_Int16)AnimationTransformType::TRANSLATE);
773 :
774 0 : AttributeList attribs( xAttribs );
775 0 : sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
776 0 : if( nOrigin != 0 )
777 : {
778 0 : switch(nOrigin)
779 : {
780 : case XML_layout:
781 : case XML_parent:
782 0 : break;
783 : }
784 : // TODO
785 : }
786 :
787 0 : OUString aStr = xAttribs->getOptionalValue( XML_path );
788 : // E can appear inside a number, so we only check for its presence at the end
789 0 : aStr = aStr.trim();
790 0 : if (aStr.endsWith("E"))
791 0 : aStr = aStr.copy(0, aStr.getLength() - 1);
792 0 : aStr = aStr.trim();
793 0 : pNode->getNodeProperties()[ NP_PATH ] = makeAny(aStr);
794 0 : mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
795 0 : msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
796 0 : mnAngle = attribs.getInteger( XML_rAng, 0 );
797 : // TODO make sure the units are right. Likely not.
798 0 : }
799 :
800 0 : virtual ~AnimMotionContext( ) throw()
801 0 : {
802 0 : }
803 :
804 :
805 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
806 : {
807 0 : switch ( aElementToken )
808 : {
809 : case PPT_TOKEN( cBhvr ):
810 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
811 : case PPT_TOKEN( to ):
812 : {
813 : // CT_TLPoint
814 0 : awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
815 0 : Any rAny;
816 0 : rAny <<= p.X;
817 0 : rAny <<= p.Y;
818 0 : mpNode->setTo( rAny );
819 0 : return this;
820 : }
821 : case PPT_TOKEN( from ):
822 : {
823 : // CT_TLPoint
824 0 : awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
825 0 : Any rAny;
826 0 : rAny <<= p.X;
827 0 : rAny <<= p.Y;
828 0 : mpNode->setFrom( rAny );
829 0 : return this;
830 : }
831 : case PPT_TOKEN( by ):
832 : {
833 : // CT_TLPoint
834 0 : awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
835 0 : Any rAny;
836 0 : rAny <<= p.X;
837 0 : rAny <<= p.Y;
838 0 : mpNode->setBy( rAny );
839 0 : return this;
840 : }
841 : case PPT_TOKEN( rCtr ):
842 : {
843 : // CT_TLPoint
844 0 : awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
845 : // TODO push
846 : (void)p;
847 0 : return this;
848 : }
849 : default:
850 0 : break;
851 : }
852 :
853 0 : return this;
854 : }
855 : private:
856 : OUString msPtsTypes;
857 : sal_Int32 mnPathEditMode;
858 : sal_Int32 mnAngle;
859 : };
860 :
861 :
862 : /** CT_TLAnimateEffectBehavior */
863 : class AnimEffectContext
864 : : public TimeNodeContext
865 : {
866 : public:
867 0 : AnimEffectContext( FragmentHandler2& rParent, sal_Int32 aElement,
868 : const Reference< XFastAttributeList >& xAttribs,
869 : const TimeNodePtr & pNode ) throw()
870 0 : : TimeNodeContext( rParent, aElement, xAttribs, pNode )
871 : {
872 0 : sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
873 0 : OUString sFilter = xAttribs->getOptionalValue( XML_filter );
874 : // TODO
875 : // OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
876 :
877 0 : if( !sFilter.isEmpty() )
878 : {
879 0 : SlideTransition aFilter( sFilter );
880 0 : aFilter.setMode( nDir == XML_out ? false : true );
881 0 : pNode->setTransitionFilter( aFilter );
882 0 : }
883 0 : }
884 :
885 :
886 0 : virtual ~AnimEffectContext( ) throw()
887 0 : {
888 0 : }
889 :
890 :
891 0 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
892 : {
893 0 : switch ( aElementToken )
894 : {
895 : case PPT_TOKEN( cBhvr ):
896 0 : return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
897 : case PPT_TOKEN( progress ):
898 0 : return new AnimVariantContext( *this, aElementToken, maProgress );
899 : // TODO handle it.
900 : default:
901 0 : break;
902 : }
903 :
904 0 : return this;
905 : }
906 : private:
907 : Any maProgress;
908 : OUString msFilter;
909 : OUString msPrList;
910 : };
911 :
912 :
913 :
914 0 : TimeNodeContext * TimeNodeContext::makeContext(
915 : FragmentHandler2& rParent, sal_Int32 aElement,
916 : const Reference< XFastAttributeList >& xAttribs,
917 : const TimeNodePtr & pNode )
918 : {
919 0 : TimeNodeContext *pCtx = NULL;
920 0 : switch( aElement )
921 : {
922 : case PPT_TOKEN( animClr ):
923 0 : pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
924 0 : break;
925 : case PPT_TOKEN( par ):
926 0 : pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
927 0 : break;
928 : case PPT_TOKEN( seq ):
929 0 : pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
930 0 : break;
931 : case PPT_TOKEN( excl ):
932 0 : pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
933 0 : break;
934 : case PPT_TOKEN( anim ):
935 0 : pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
936 0 : break;
937 : case PPT_TOKEN( animEffect ):
938 0 : pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
939 0 : break;
940 : case PPT_TOKEN( animMotion ):
941 0 : pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
942 0 : break;
943 : case PPT_TOKEN( animRot ):
944 0 : pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
945 0 : break;
946 : case PPT_TOKEN( animScale ):
947 0 : pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
948 0 : break;
949 : case PPT_TOKEN( cmd ):
950 0 : pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
951 0 : break;
952 : case PPT_TOKEN( set ):
953 0 : pCtx = new SetTimeNodeContext( rParent, aElement, xAttribs, pNode );
954 0 : break;
955 : case PPT_TOKEN( audio ):
956 : case PPT_TOKEN( video ):
957 0 : pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
958 0 : break;
959 : default:
960 0 : break;
961 : }
962 0 : return pCtx;
963 : }
964 :
965 :
966 0 : TimeNodeContext::TimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
967 : const Reference< XFastAttributeList >& /*xAttribs*/,
968 : const TimeNodePtr & pNode ) throw()
969 : : FragmentHandler2( rParent )
970 : , mnElement( aElement )
971 0 : , mpNode( pNode )
972 : {
973 0 : }
974 :
975 :
976 0 : TimeNodeContext::~TimeNodeContext( ) throw()
977 : {
978 :
979 0 : }
980 :
981 :
982 0 : TimeNodeListContext::TimeNodeListContext( FragmentHandler2& rParent, TimeNodePtrList & aList )
983 : throw()
984 : : FragmentHandler2( rParent )
985 0 : , maList( aList )
986 : {
987 0 : }
988 :
989 :
990 0 : TimeNodeListContext::~TimeNodeListContext( ) throw()
991 : {
992 0 : }
993 :
994 :
995 0 : ::oox::core::ContextHandlerRef TimeNodeListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
996 : {
997 : sal_Int16 nNodeType;
998 :
999 0 : switch( aElementToken )
1000 : {
1001 : case PPT_TOKEN( par ):
1002 0 : nNodeType = AnimationNodeType::PAR;
1003 0 : break;
1004 : case PPT_TOKEN( seq ):
1005 0 : nNodeType = AnimationNodeType::SEQ;
1006 0 : break;
1007 : case PPT_TOKEN( excl ):
1008 : // TODO pick the right type. We choose parallel for now as
1009 : // there does not seem to be an "Exclusive"
1010 0 : nNodeType = AnimationNodeType::PAR;
1011 0 : break;
1012 : case PPT_TOKEN( anim ):
1013 0 : nNodeType = AnimationNodeType::ANIMATE;
1014 0 : break;
1015 : case PPT_TOKEN( animClr ):
1016 0 : nNodeType = AnimationNodeType::ANIMATECOLOR;
1017 0 : break;
1018 : case PPT_TOKEN( animEffect ):
1019 0 : nNodeType = AnimationNodeType::TRANSITIONFILTER;
1020 0 : break;
1021 : case PPT_TOKEN( animMotion ):
1022 0 : nNodeType = AnimationNodeType::ANIMATEMOTION;
1023 0 : break;
1024 : case PPT_TOKEN( animRot ):
1025 : case PPT_TOKEN( animScale ):
1026 0 : nNodeType = AnimationNodeType::ANIMATETRANSFORM;
1027 0 : break;
1028 : case PPT_TOKEN( cmd ):
1029 0 : nNodeType = AnimationNodeType::COMMAND;
1030 0 : break;
1031 : case PPT_TOKEN( set ):
1032 0 : nNodeType = AnimationNodeType::SET;
1033 0 : break;
1034 : case PPT_TOKEN( audio ):
1035 0 : nNodeType = AnimationNodeType::AUDIO;
1036 0 : break;
1037 : case PPT_TOKEN( video ):
1038 0 : nNodeType = AnimationNodeType::AUDIO;
1039 : OSL_TRACE( "OOX: video requested, gave Audio instead" );
1040 0 : break;
1041 :
1042 : default:
1043 0 : nNodeType = AnimationNodeType::CUSTOM;
1044 : OSL_TRACE( "OOX: uhandled token %x", aElementToken );
1045 0 : break;
1046 : }
1047 :
1048 0 : TimeNodePtr pNode(new TimeNode(nNodeType));
1049 0 : maList.push_back( pNode );
1050 0 : FragmentHandler2 * pContext = TimeNodeContext::makeContext( *this, aElementToken, rAttribs.getFastAttributeList(), pNode );
1051 :
1052 0 : return pContext ? pContext : this;
1053 : }
1054 :
1055 :
1056 0 : } }
1057 :
1058 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|