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