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/timenode.hxx"
21 :
22 : #include <boost/bind.hpp>
23 :
24 : #include <com/sun/star/beans/XPropertySet.hpp>
25 : #include <com/sun/star/beans/NamedValue.hpp>
26 : #include <com/sun/star/container/XEnumerationAccess.hpp>
27 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 : #include <com/sun/star/frame/XModel.hpp>
29 : #include <com/sun/star/animations/XAnimateColor.hpp>
30 : #include <com/sun/star/animations/XAnimateMotion.hpp>
31 : #include <com/sun/star/animations/XAnimateTransform.hpp>
32 : #include <com/sun/star/animations/XCommand.hpp>
33 : #include <com/sun/star/animations/XIterateContainer.hpp>
34 : #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
35 : #include <com/sun/star/animations/XTimeContainer.hpp>
36 : #include <com/sun/star/animations/AnimationNodeType.hpp>
37 : #include <com/sun/star/animations/Event.hpp>
38 : #include <com/sun/star/animations/EventTrigger.hpp>
39 : #include <com/sun/star/presentation/EffectNodeType.hpp>
40 :
41 : #include "oox/helper/helper.hxx"
42 : #include "oox/core/xmlfilterbase.hxx"
43 :
44 : using ::rtl::OUString;
45 : using namespace ::oox::core;
46 : using namespace ::com::sun::star::beans;
47 : using namespace ::com::sun::star::container;
48 : using namespace ::com::sun::star::uno;
49 : using namespace ::com::sun::star::lang;
50 : using namespace ::com::sun::star::animations;
51 : using namespace ::com::sun::star::frame;
52 : using namespace ::com::sun::star::presentation;
53 :
54 : namespace oox { namespace ppt {
55 :
56 0 : OUString TimeNode::getServiceName( sal_Int16 nNodeType )
57 : {
58 0 : OUString sServiceName;
59 0 : switch( nNodeType )
60 : {
61 : case AnimationNodeType::PAR:
62 : // sServiceName = CREATE_OUSTRING("com.sun.star.animations.IterateContainer");
63 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.ParallelTimeContainer");
64 0 : break;
65 : case AnimationNodeType::SEQ:
66 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.SequenceTimeContainer");
67 0 : break;
68 : case AnimationNodeType::ANIMATE:
69 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.Animate");
70 0 : break;
71 : case AnimationNodeType::ANIMATECOLOR:
72 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateColor");
73 0 : break;
74 : case AnimationNodeType::TRANSITIONFILTER:
75 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.TransitionFilter");
76 0 : break;
77 : case AnimationNodeType::ANIMATEMOTION:
78 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateMotion");
79 0 : break;
80 : case AnimationNodeType::ANIMATETRANSFORM:
81 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateTransform");
82 0 : break;
83 : case AnimationNodeType::COMMAND:
84 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.Command");
85 0 : break;
86 : case AnimationNodeType::SET:
87 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateSet");
88 0 : break;
89 : case AnimationNodeType::AUDIO:
90 0 : sServiceName = CREATE_OUSTRING("com.sun.star.animations.Audio");
91 0 : break;
92 : default:
93 : OSL_TRACE( "OOX: uhandled type %x", nNodeType );
94 0 : break;
95 : }
96 0 : return sServiceName;
97 : }
98 :
99 :
100 :
101 4 : TimeNode::TimeNode( sal_Int16 nNodeType )
102 : : mnNodeType( nNodeType )
103 4 : , mbHasEndSyncValue( false )
104 : {
105 4 : }
106 :
107 :
108 8 : TimeNode::~TimeNode()
109 : {
110 8 : }
111 :
112 : // BEGIN CUT&PASTE from sd/source/filter/ppt/pptinanimations.hxx
113 : // --------------------------------------------------------------------
114 0 : static void fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
115 : {
116 : try
117 : {
118 0 : bool bFirst = true;
119 0 : Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
120 0 : Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
121 0 : while( xE->hasMoreElements() )
122 : {
123 : // click node
124 0 : Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
125 :
126 0 : Event aEvent;
127 0 : aEvent.Trigger = EventTrigger::ON_NEXT;
128 0 : aEvent.Repeat = 0;
129 0 : xClickNode->setBegin( makeAny( aEvent ) );
130 :
131 0 : if( bFirst )
132 : {
133 0 : bFirst = false;
134 0 : Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
135 0 : Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW );
136 0 : if( xE2->hasMoreElements() )
137 : {
138 : // with node
139 0 : xE2->nextElement() >>= xEA2;
140 0 : if( xEA2.is() )
141 0 : xE2.query( xEA2->createEnumeration() );
142 : else
143 0 : xE2.clear();
144 :
145 0 : if( xE2.is() && xE2->hasMoreElements() )
146 : {
147 0 : Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
148 0 : const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
149 0 : const NamedValue* p = aUserData.getConstArray();
150 0 : sal_Int32 nLength = aUserData.getLength();
151 0 : while( nLength-- )
152 : {
153 0 : if ( p->Name == "node-type" )
154 : {
155 0 : sal_Int16 nNodeType = 0;
156 0 : p->Value >>= nNodeType;
157 0 : if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK )
158 : {
159 : // first effect does not start on click, so correct
160 : // first click nodes begin to 0s
161 0 : xClickNode->setBegin( makeAny( (double)0.0 ) );
162 : break;
163 : }
164 : }
165 0 : p++;
166 0 : }
167 : }
168 0 : }
169 : }
170 0 : }
171 : }
172 0 : catch( Exception& e )
173 : {
174 : (void)e;
175 : OSL_TRACE("fixMainSequenceTiming(), exception caught!" );
176 : }
177 0 : }
178 :
179 : // --------------------------------------------------------------------
180 :
181 0 : static void fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
182 : {
183 : try
184 : {
185 0 : Any aBegin( xNode->getBegin() );
186 0 : Any aEmpty;
187 0 : xNode->setBegin( aEmpty );
188 :
189 0 : Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
190 0 : Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
191 0 : while( xE->hasMoreElements() )
192 : {
193 : // click node
194 0 : Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
195 0 : xClickNode->setBegin( aBegin );
196 0 : }
197 : }
198 0 : catch( Exception& e )
199 : {
200 : (void)e;
201 : OSL_TRACE("fixInteractiveSequenceTiming(), exception caught!" );
202 : }
203 0 : }
204 :
205 : // END CUT&PASTE
206 :
207 0 : void TimeNode::addNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& rxNode, const SlidePersistPtr & pSlide )
208 : {
209 : try {
210 0 : OUString sServiceName = getServiceName( mnNodeType );
211 0 : Reference< XAnimationNode > xNode = createAndInsert( rFilter, sServiceName, rxNode );
212 0 : setNode( rFilter, xNode, pSlide );
213 : }
214 0 : catch( const Exception& e )
215 : {
216 : OSL_TRACE( "OOX: exception raised in TimeNode::addNode() - %s",
217 : OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
218 : }
219 0 : }
220 :
221 0 : void TimeNode::setNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& xNode, const SlidePersistPtr & pSlide )
222 : {
223 : OSL_ENSURE( xNode.is(), "null node passed" );
224 :
225 : try {
226 0 : if( !msId.isEmpty() )
227 : {
228 0 : pSlide->getAnimNodesMap()[ msId ] = xNode;
229 : }
230 :
231 0 : if( mpTarget )
232 : {
233 0 : sal_Int16 nSubType(0);
234 0 : maNodeProperties[ NP_TARGET ] = mpTarget->convert( pSlide, nSubType );
235 0 : if( mpTarget->mnType == XML_spTgt )
236 : {
237 0 : maNodeProperties[ NP_SUBITEM ] <<= nSubType;
238 : }
239 : }
240 :
241 0 : if( !maStCondList.empty() )
242 : {
243 0 : Any aAny = AnimationCondition::convertList( pSlide, maStCondList );
244 0 : if( aAny.hasValue() )
245 : {
246 0 : xNode->setBegin( aAny );
247 0 : }
248 :
249 : }
250 0 : if( !maEndCondList.empty() )
251 : {
252 0 : Any aAny = AnimationCondition::convertList( pSlide, maEndCondList );
253 0 : if( aAny.hasValue() )
254 : {
255 0 : xNode->setEnd( aAny );
256 0 : }
257 : }
258 : #if 0 // FIXME even the binary filter has this disabled.
259 : if( !maNextCondList.empty() )
260 : {
261 : Any aAny = AnimationCondition::convertList( pSlide, maNextCondList );
262 : if( aAny.hasValue() )
263 : {
264 : xNode->setNext( aAny );
265 : }
266 : }
267 : if( !maPrevCondList.empty() )
268 : {
269 : Any aAny = AnimationCondition::convertList( pSlide, maPrevCondList );
270 : if( aAny.hasValue() )
271 : {
272 : xNode->setPrev( aAny );
273 : }
274 : }
275 : #endif
276 0 : if( mbHasEndSyncValue )
277 : {
278 0 : Any aValue = maEndSyncValue.convert( pSlide );
279 0 : xNode->setEndSync(aValue);
280 : }
281 :
282 0 : if( !maUserData.empty() )
283 : {
284 0 : Sequence< NamedValue > aUserDataSeq( static_cast< sal_Int32 >( maUserData.size() ) );
285 0 : NamedValue* pValues = aUserDataSeq.getArray();
286 0 : for( UserDataMap::const_iterator aIt = maUserData.begin(), aEnd = maUserData.end(); aIt != aEnd; ++aIt, ++pValues )
287 : {
288 0 : pValues->Name = aIt->first;
289 0 : pValues->Value = aIt->second;
290 : }
291 0 : maNodeProperties[ NP_USERDATA ] <<= aUserDataSeq;
292 : }
293 :
294 0 : Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
295 0 : Reference< XAnimateColor > xAnimateColor( xNode, UNO_QUERY );
296 0 : Reference< XAnimateMotion > xAnimateMotion( xNode, UNO_QUERY );
297 0 : Reference< XAnimateTransform > xAnimateTransform( xNode, UNO_QUERY );
298 0 : Reference< XCommand > xCommand( xNode, UNO_QUERY );
299 0 : Reference< XIterateContainer > xIterateContainer( xNode, UNO_QUERY );
300 0 : sal_Int16 nInt16 = 0;
301 0 : sal_Bool bBool = sal_False;
302 0 : double fDouble = 0;
303 0 : OUString sString;
304 0 : Sequence< NamedValue > aSeq;
305 :
306 0 : for( int i = 0; i < _NP_SIZE; i++)
307 : {
308 0 : Any & aValue( maNodeProperties[ i ] );
309 0 : if( aValue.hasValue() )
310 : {
311 0 : switch( i )
312 : {
313 : case NP_TO:
314 0 : if( xAnimate.is() )
315 0 : xAnimate->setTo( aValue );
316 0 : break;
317 : case NP_FROM:
318 0 : if( xAnimate.is() )
319 0 : xAnimate->setFrom( aValue );
320 0 : break;
321 : case NP_BY:
322 0 : if( xAnimate.is() )
323 0 : xAnimate->setBy( aValue );
324 0 : break;
325 : case NP_TARGET:
326 0 : if( xAnimate.is() )
327 0 : xAnimate->setTarget( aValue );
328 0 : break;
329 : case NP_SUBITEM:
330 0 : if( xAnimate.is() )
331 : {
332 0 : if( aValue >>= nInt16 )
333 0 : xAnimate->setSubItem( nInt16 );
334 : else
335 : {
336 : OSL_TRACE( "any >>= failed %d", __LINE__ );
337 : }
338 : }
339 0 : break;
340 : case NP_ATTRIBUTENAME:
341 0 : if( xAnimate.is() )
342 : {
343 0 : if( aValue >>= sString )
344 0 : xAnimate->setAttributeName( sString );
345 : else
346 : {
347 : OSL_TRACE( "any >>= failed %d", __LINE__ );
348 : }
349 : }
350 0 : break;
351 : case NP_CALCMODE:
352 0 : if( xAnimate.is() )
353 : {
354 0 : if( aValue >>= nInt16 )
355 0 : xAnimate->setCalcMode( nInt16 );
356 : else
357 : {
358 : OSL_TRACE( "any >>= failed %d", __LINE__ );
359 : }
360 : }
361 0 : break;
362 : case NP_KEYTIMES:
363 0 : if( xAnimate.is() )
364 : {
365 0 : Sequence<double> aKeyTimes;
366 0 : if( aValue >>= aKeyTimes )
367 0 : xAnimate->setKeyTimes(aKeyTimes);
368 : else
369 : {
370 : OSL_TRACE( "any >>= failed %d", __LINE__ );
371 0 : }
372 : }
373 0 : break;
374 : case NP_VALUES:
375 0 : if( xAnimate.is() )
376 : {
377 0 : Sequence<Any> aValues;
378 0 : if( aValue >>= aValues )
379 0 : xAnimate->setValues(aValues);
380 : else
381 : {
382 : OSL_TRACE( "any >>= failed %d", __LINE__ );
383 0 : }
384 : }
385 0 : break;
386 : case NP_FORMULA:
387 0 : if( xAnimate.is() )
388 : {
389 0 : if( aValue >>= sString )
390 0 : xAnimate->setFormula(sString);
391 : else
392 : {
393 : OSL_TRACE( "any >>= failed %d", __LINE__ );
394 : }
395 : }
396 0 : break;
397 : case NP_COLORINTERPOLATION:
398 0 : if( xAnimateColor.is() )
399 : {
400 0 : if( aValue >>= nInt16 )
401 0 : xAnimateColor->setColorInterpolation( nInt16 );
402 : else
403 : {
404 : OSL_TRACE( "any >>= failed %d", __LINE__ );
405 : }
406 : }
407 0 : break;
408 : case NP_DIRECTION:
409 0 : if( xAnimateColor.is() )
410 : {
411 0 : if( aValue >>= bBool )
412 0 : xAnimateColor->setDirection( bBool );
413 : else
414 : {
415 : OSL_TRACE( "any >>= failed %d", __LINE__ );
416 : }
417 : }
418 0 : break;
419 : case NP_PATH:
420 0 : if( xAnimateMotion.is() )
421 0 : xAnimateMotion->setPath( aValue );
422 0 : break;
423 : case NP_TRANSFORMTYPE:
424 0 : if( xAnimateTransform.is() )
425 : {
426 0 : if( aValue >>= nInt16 )
427 0 : xAnimateTransform->setTransformType( nInt16 );
428 : else
429 : {
430 : OSL_TRACE( "any >>= failed %d", __LINE__ );
431 : }
432 : }
433 0 : break;
434 : case NP_USERDATA:
435 0 : if( aValue >>= aSeq )
436 0 : xNode->setUserData( aSeq );
437 : else
438 : {
439 : OSL_TRACE( "any >>= failed %d", __LINE__ );
440 : }
441 0 : break;
442 : case NP_ACCELERATION:
443 0 : if( aValue >>= fDouble )
444 0 : xNode->setAcceleration( fDouble );
445 : else
446 : {
447 : OSL_TRACE( "any >>= failed %d", __LINE__ );
448 : }
449 0 : break;
450 : case NP_DECELERATE:
451 0 : if( aValue >>= fDouble )
452 0 : xNode->setDecelerate( fDouble );
453 : else
454 : {
455 : OSL_TRACE( "any >>= failed %d", __LINE__ );
456 : }
457 0 : break;
458 : case NP_AUTOREVERSE:
459 0 : if( aValue >>= bBool )
460 0 : xNode->setAutoReverse( bBool );
461 : else
462 : {
463 : OSL_TRACE( "any >>= failed %d", __LINE__ );
464 : }
465 0 : break;
466 : case NP_DURATION:
467 0 : xNode->setDuration( aValue );
468 0 : break;
469 : case NP_FILL:
470 0 : if( aValue >>= nInt16 )
471 0 : xNode->setFill( nInt16 );
472 : else
473 : {
474 : OSL_TRACE( "any >>= failed %d", __LINE__ );
475 : }
476 0 : break;
477 : case NP_REPEATCOUNT:
478 0 : xNode->setRepeatCount( aValue );
479 0 : break;
480 : case NP_REPEATDURATION:
481 0 : xNode->setRepeatDuration( aValue );
482 0 : break;
483 : case NP_RESTART:
484 0 : if( aValue >>= nInt16 )
485 0 : xNode->setRestart( nInt16 );
486 : else
487 : {
488 : OSL_TRACE( "any >>= failed %d", __LINE__ );
489 : }
490 0 : break;
491 : case NP_COMMAND:
492 0 : if( xCommand.is() )
493 : {
494 0 : if( aValue >>= nInt16 )
495 0 : xCommand->setCommand( nInt16 );
496 : else
497 : {
498 : OSL_TRACE( "any >>= failed %d", __LINE__ );
499 : }
500 : }
501 0 : break;
502 : case NP_PARAMETER:
503 0 : if( xCommand.is() )
504 0 : xCommand->setParameter( aValue );
505 0 : break;
506 : case NP_ITERATETYPE:
507 0 : if( xIterateContainer.is() )
508 : {
509 0 : if( aValue >>= nInt16 )
510 0 : xIterateContainer->setIterateType( nInt16 );
511 : else
512 : {
513 : OSL_TRACE( "any >>= failed %d", __LINE__ );
514 : }
515 : }
516 0 : break;
517 : case NP_ITERATEINTERVAL:
518 0 : if( xIterateContainer.is() )
519 : {
520 0 : if( aValue >>= fDouble )
521 0 : xIterateContainer->setIterateInterval( fDouble );
522 : else
523 : {
524 : OSL_TRACE( "any >>= failed %d", __LINE__ );
525 : }
526 : }
527 0 : break;
528 : default:
529 : OSL_TRACE( "ERR-OOX: unknown prop index %d", i );
530 0 : break;
531 : }
532 : }
533 : }
534 :
535 0 : if( mnNodeType == AnimationNodeType::TRANSITIONFILTER )
536 : {
537 :
538 0 : Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
539 0 : maTransitionFilter.setTransitionFilterProperties( xFilter );
540 : }
541 :
542 : std::for_each( maChildren.begin(), maChildren.end(),
543 : boost::bind(&TimeNode::addNode, _1, boost::cref(rFilter), boost::ref(xNode),
544 0 : boost::ref(pSlide) ) );
545 :
546 0 : switch( mnNodeType )
547 : {
548 : case AnimationNodeType::SEQ:
549 : {
550 0 : sal_Int16 nEnum = 0;
551 0 : if( maUserData[ CREATE_OUSTRING( "node-type" ) ] >>= nEnum )
552 : {
553 0 : if( nEnum == EffectNodeType::MAIN_SEQUENCE )
554 : {
555 0 : fixMainSequenceTiming( xNode );
556 : }
557 0 : else if( nEnum == EffectNodeType::INTERACTIVE_SEQUENCE )
558 : {
559 0 : fixInteractiveSequenceTiming( xNode );
560 : }
561 : }
562 : break;
563 : }
564 : case AnimationNodeType::PAR:
565 : // some other cut&paste... from AnimationImporter::importAnimationContainer()
566 0 : break;
567 0 : }
568 : }
569 0 : catch( const Exception& e )
570 : {
571 : OSL_TRACE( "OOX: exception raised in TimeNode::setNode() - %s",
572 : OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
573 : }
574 0 : }
575 :
576 :
577 0 : Reference< XAnimationNode > TimeNode::createAndInsert(
578 : const XmlFilterBase& rFilter,
579 : const OUString& rServiceName,
580 : const Reference< XAnimationNode >& rxNode )
581 : {
582 : try {
583 0 : Reference< XAnimationNode > xNode ( rFilter.getServiceFactory()->createInstance( rServiceName ), UNO_QUERY_THROW );
584 0 : Reference< XTimeContainer > xParentContainer( rxNode, UNO_QUERY_THROW );
585 :
586 0 : xParentContainer->appendChild( xNode );
587 0 : return xNode;
588 : }
589 0 : catch( const Exception& e )
590 : {
591 : OSL_TRACE( "OOX: exception raised in TimeNode::createAndInsert() trying to create a service %s = %s",
592 : OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ).getStr(),
593 : OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
594 : }
595 :
596 0 : return Reference< XAnimationNode >();
597 : }
598 :
599 :
600 4 : void TimeNode::setId( sal_Int32 nId )
601 : {
602 4 : msId = OUString::valueOf(nId);
603 4 : }
604 :
605 0 : void TimeNode::setTo( const Any & aTo )
606 : {
607 0 : maNodeProperties[ NP_TO ] = aTo;
608 0 : }
609 :
610 :
611 0 : void TimeNode::setFrom( const Any & aFrom )
612 : {
613 0 : maNodeProperties[ NP_FROM ] = aFrom;
614 0 : }
615 :
616 0 : void TimeNode::setBy( const Any & aBy )
617 : {
618 0 : maNodeProperties[ NP_BY ] = aBy;
619 0 : }
620 :
621 :
622 51 : } }
623 :
624 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|