LibreOffice Module sd (master) 1
pptinanimations.cxx
Go to the documentation of this file.
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 <com/sun/star/animations/XAnimationNodeSupplier.hpp>
21#include <com/sun/star/animations/AnimationFill.hpp>
22#include <com/sun/star/animations/AnimationRestart.hpp>
23#include <com/sun/star/animations/Timing.hpp>
24#include <com/sun/star/animations/Event.hpp>
25#include <com/sun/star/animations/AnimationEndSync.hpp>
26#include <com/sun/star/animations/Command.hpp>
27#include <com/sun/star/animations/EventTrigger.hpp>
28#include <com/sun/star/animations/AnimationNodeType.hpp>
29#include <com/sun/star/animations/AnimationTransformType.hpp>
30#include <com/sun/star/animations/AnimationCalcMode.hpp>
31#include <com/sun/star/animations/AnimationValueType.hpp>
32#include <com/sun/star/animations/AnimationAdditiveMode.hpp>
33#include <com/sun/star/animations/XIterateContainer.hpp>
34#include <com/sun/star/animations/XAnimateSet.hpp>
35#include <com/sun/star/animations/XAnimationNode.hpp>
36#include <com/sun/star/animations/XAudio.hpp>
37#include <com/sun/star/animations/XCommand.hpp>
38#include <com/sun/star/animations/XTransitionFilter.hpp>
39#include <com/sun/star/animations/XAnimateColor.hpp>
40#include <com/sun/star/animations/XAnimateMotion.hpp>
41#include <com/sun/star/animations/XAnimateTransform.hpp>
42#include <com/sun/star/animations/ValuePair.hpp>
43#include <com/sun/star/animations/AnimationColorSpace.hpp>
44#include <com/sun/star/presentation/EffectNodeType.hpp>
45#include <com/sun/star/presentation/EffectPresetClass.hpp>
46#include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
47#include <com/sun/star/presentation/EffectCommands.hpp>
48#include <com/sun/star/beans/NamedValue.hpp>
49#include <com/sun/star/container/XEnumerationAccess.hpp>
50#include <com/sun/star/drawing/XDrawPage.hpp>
51#include <com/sun/star/io/WrongFormatException.hpp>
52#include <com/sun/star/presentation/ParagraphTarget.hpp>
53#include <com/sun/star/presentation/TextAnimationType.hpp>
57#include <rtl/ustrbuf.hxx>
58#include <rtl/math.hxx>
59#include <sal/log.hxx>
60#include <tools/debug.hxx>
61#include <osl/diagnose.h>
62#include <o3tl/string_view.hxx>
63
64#include <svx/svdotext.hxx>
65#include <editeng/outlobj.hxx>
66#include <editeng/editobj.hxx>
67#include <animations.hxx>
68#include "pptanimations.hxx"
69#include "pptinanimations.hxx"
70#include "pptatom.hxx"
71#include "pptin.hxx"
72#include <randomnode.hxx>
73
74#include <algorithm>
75#include <memory>
76
77using ::com::sun::star::beans::NamedValue;
78using ::com::sun::star::container::XEnumerationAccess;
79using ::com::sun::star::container::XEnumeration;
80
81using namespace ::com::sun::star::uno;
82using namespace ::com::sun::star::drawing;
83using namespace ::com::sun::star::animations;
84using namespace ::com::sun::star::presentation;
85
86namespace ppt
87{
88
90{
91 rIn.ReadInt32( rNode.mnU1 );
92 rIn.ReadInt32( rNode.mnRestart );
93 rIn.ReadInt32( rNode.mnGroupType );
94 rIn.ReadInt32( rNode.mnFill );
95 rIn.ReadInt32( rNode.mnU3 );
96 rIn.ReadInt32( rNode.mnU4 );
97 rIn.ReadInt32( rNode.mnDuration );
98 rIn.ReadInt32( rNode.mnNodeType );
99
100 return rIn;
101}
102
103bool PropertySet::hasProperty( sal_Int32 nProperty ) const
104{
105 return maProperties.find( nProperty ) != maProperties.end();
106}
107
108Any PropertySet::getProperty( sal_Int32 nProperty ) const
109{
110 PropertySetMap_t::const_iterator aIter( maProperties.find( nProperty ) );
111 if( aIter != maProperties.end() )
112 return (*aIter).second;
113 else
114 return Any();
115}
116
118: mpPPTImport( pPPTImport ), mrStCtrl( rStCtrl )
119{
120}
121
122int AnimationImporter::import( const Reference< XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd )
123{
124 int nNodes = 0;
125
126#ifdef DBG_ANIM_LOG
127 static int ppt_anim_debug_stream_number = 1;
128 OUString ppt_anim_debug_filename("ppt-animation-import-debug-output-");
129 ppt_anim_debug_filename += OUString::number(ppt_anim_debug_stream_number++);
130 ppt_anim_debug_filename += ".xml";
131 mpFile = fopen( OUStringToOString( ppt_anim_debug_filename, RTL_TEXTENCODING_UTF8).getStr() , "w+" );
132#endif
133 dump("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
134
135 Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY );
136 if( xNodeSupplier.is() )
137 {
138 mxRootNode = xNodeSupplier->getAnimationNode();
139 if( mxRootNode.is() )
140 {
141 Reference< XAnimationNode > xParent;
142
143 std::unique_ptr<Atom> pAtom(Atom::import( rProgTagContentHd, mrStCtrl ));
144 if( pAtom )
145 {
146 nNodes = importAnimationContainer( pAtom.get(), xParent );
147 }
148
149 std::for_each( maAfterEffectNodes.begin(), maAfterEffectNodes.end(),
151 }
152 }
153
154#ifdef DBG_ANIM_LOG
155 fclose( mpFile );
156#endif
157
158 return nNodes;
159}
160
161Reference< XAnimationNode > AnimationImporter::createNode( const Atom* pAtom, const AnimationNode& rNode )
162{
163 const char* pServiceName = nullptr;
164
165 switch( rNode.mnGroupType )
166 {
169 pServiceName = "com.sun.star.animations.IterateContainer";
170 else
171 pServiceName = "com.sun.star.animations.ParallelTimeContainer";
172 break;
174 pServiceName = "com.sun.star.animations.SequenceTimeContainer";
175 break;
177 {
178 switch( rNode.mnNodeType )
179 {
182 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
183 pServiceName = "com.sun.star.animations.AnimateSet";
184 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
185 pServiceName = "com.sun.star.animations.AnimateColor";
186 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
187 pServiceName = "com.sun.star.animations.AnimateTransform";
188 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
189 pServiceName = "com.sun.star.animations.AnimateTransform";
190 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
191 pServiceName = "com.sun.star.animations.AnimateMotion";
192 else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) )
193 pServiceName = "com.sun.star.animations.TransitionFilter";
194 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
195 pServiceName = "com.sun.star.animations.Command";
196 else
197 pServiceName = "com.sun.star.animations.Animate";
198 break;
199 }
200 break;
201 }
203 pServiceName = "com.sun.star.animations.Audio";
204 break;
205
206 default:
207 pServiceName = "com.sun.star.animations.Animate";
208 break;
209 }
210
211 Reference< XAnimationNode > xNode;
212 if( pServiceName )
213 {
214 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
215 const OUString aServiceName( OUString::createFromAscii(pServiceName) );
216 Reference< XInterface > xFac( xContext->getServiceManager()->createInstanceWithContext(aServiceName, xContext) );
217 xNode.set(xFac , UNO_QUERY );
218 }
219
220 DBG_ASSERT( xNode.is(), "sd::AnimationImporter::createNode(), node creation failed!" );
221 return xNode;
222}
223
224static bool is_random( const AnimationNode& rNode, const PropertySet& rSet, sal_Int32& rPresetClass )
225{
227 return false;
228
229 if( !rSet.hasProperty( DFF_ANIM_PRESET_ID ) || !rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) )
230 return false;
231
232 sal_Int32 nPresetId = 0;
233 if( !(rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId) || (nPresetId != 24) )
234 return false;
235
236 sal_Int32 nPresetClass = 0;
237 if( !(rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass) )
238 return false;
239
240 switch( nPresetClass )
241 {
242 case DFF_ANIM_PRESS_CLASS_ENTRANCE: rPresetClass = EffectPresetClass::ENTRANCE; return true;
243 case DFF_ANIM_PRESS_CLASS_EXIT: rPresetClass = EffectPresetClass::EXIT; return true;
244 }
245 return false;
246}
247
248int AnimationImporter::importAnimationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xParent )
249{
250 int nNodes = 0;
251 if( pAtom->seekToContent() )
252 {
253 AnimationNode aNode;
254 const Atom* pAnimationNodeAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimNode );
255 if( pAnimationNodeAtom && pAnimationNodeAtom->seekToContent() )
256 mrStCtrl >> aNode;
257
258 PropertySet aSet;
259 const Atom* pAnimationPropertySetAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimPropertySet );
260 if( pAnimationPropertySetAtom )
261 importPropertySetContainer( pAnimationPropertySetAtom, aSet );
262
263 Reference< XAnimationNode > xNode;
264
265 if( xParent.is() )
266 {
267 sal_Int32 nPresetClass;
268 if( is_random( aNode, aSet, nPresetClass ) )
269 {
270 // create a random animation node with the given preset class
271 xNode.set( sd::RandomAnimationNode_createInstance( static_cast<sal_Int16>(nPresetClass) ), UNO_QUERY );
272 }
273
274 if( !xNode.is() )
275 {
276 // create a node for the given atom
277 xNode = createNode( pAtom, aNode );
278 }
279 }
280 else
281 {
282 // if we have no parent we fill the root node
283 xNode = mxRootNode;
284 }
285
286 // import if we have a node and it's not random
287 if( xNode.is() )
288 {
289 fillNode( xNode, aNode, aSet );
290
291 switch( aNode.mnGroupType )
292 {
294 {
295 dump( "<par" );
296 dump( aNode );
297 dump( aSet );
298 nNodes += importTimeContainer( pAtom, xNode );
299 dump( "</par>\n" );
300
301 // for iteration containers, map target from children to iteration
302 Reference< XIterateContainer > xIter( xNode, UNO_QUERY );
303 if( xIter.is() )
304 {
305 double fDuration = 0.0;
306 Any aTarget, aEmpty;
307 Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
308 if( xEnumerationAccess.is() )
309 {
310 Reference< XEnumeration > xEnumeration = xEnumerationAccess->createEnumeration();
311 if( xEnumeration.is() )
312 {
313 while( xEnumeration->hasMoreElements() )
314 {
315 Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
316 if( xChildNode.is() )
317 {
318 double fChildBegin = 0.0;
319 double fChildDuration = 0.0;
320 xChildNode->getBegin() >>= fChildBegin;
321 xChildNode->getDuration() >>= fChildDuration;
322
323 fChildDuration += fChildBegin;
324 if( fChildDuration > fDuration )
325 fDuration = fChildDuration;
326
327 if( !aTarget.hasValue() )
328 aTarget = xChildNode->getTarget();
329
330 xChildNode->setTarget( aEmpty );
331 }
332 }
333 }
334 }
335
336 xIter->setTarget( aTarget );
337
338 double fIterateInterval = xIter->getIterateInterval() * fDuration / 100;
339 xIter->setIterateInterval( fIterateInterval );
340 }
341 }
342 break;
343
345 {
346 dump( "<seq" );
347 dump( aNode );
348 dump( aSet );
349 nNodes += importTimeContainer( pAtom, xNode );
350 dump( "</seq>\n" );
351
352 if( aSet.hasProperty( DFF_ANIM_NODE_TYPE ) )
353 {
354 sal_Int32 nPPTNodeType = 0;
355 if( aSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType )
356 {
357 switch(nPPTNodeType)
358 {
361 break;
364 break;
365 }
366 }
367 }
368 }
369 break;
370
372 {
373#ifdef DBG_ANIM_LOG
374 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
375 {
376 dump( "<set" );
377 }
378 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
379 {
380 dump( "<animateColor" );
381 }
382 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
383 {
384 dump( "<animateScale" );
385 }
386 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
387 {
388 dump( "<animateRotation" );
389 }
390 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
391 {
392 dump( "<animateMotion" );
393 }
394 else if( pAtom->hasChildAtom( DFF_msofbtAnimate ) )
395 {
396 dump( "<animate" );
397 }
398 else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) )
399 {
400 dump( "<animateFilter" );
401 }
402 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
403 {
404 dump( "<command" );
405 }
406 else
407 {
408 OSL_FAIL( "unknown node atom!" );
409 dump_atom_header( pAtom, true, false );
410 dump_atom( pAtom );
411 dump_atom_header( pAtom, false, false );
412 break;
413 }
414 dump( aNode );
415 dump( aSet );
416#endif
417 int nANCNodes = importAnimationNodeContainer( pAtom, xNode );
418 if( !convertAnimationNode( xNode, xParent ) )
419 xNode = nullptr;
420 else
421 nNodes += nANCNodes;
422 dump( "/>\n");
423
424 }
425 break;
426
428 {
429 dump( "<audio" );
430 dump( aNode );
431 dump( aSet );
432 nNodes += importAudioContainer( pAtom, xNode );
433 dump( "</audio>\n" );
434 }
435 break;
436
437 default:
438 OSL_FAIL( "unknown group atom!" );
439
440 dump_atom_header( pAtom, true, false );
441 dump_atom( pAtom );
442 dump_atom_header( pAtom, false, false );
443 break;
444
445 }
446 }
447
448 if( xParent.is() && xNode.is() )
449 {
450 Reference< XTimeContainer > xParentContainer( xParent, UNO_QUERY );
451 DBG_ASSERT( xParentContainer.is(), "parent is no container, then why do I have a child here?" );
452 if( xParentContainer.is() )
453 {
454 xParentContainer->appendChild( xNode );
455 }
456 }
457 }
458
459 return nNodes;
460}
461
462bool AnimationImporter::convertAnimationNode( const Reference< XAnimationNode >& xNode, const Reference< XAnimationNode >& xParent )
463{
464 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
465 if( !xAnimate.is() )
466 return true;
467
468 if( !xAnimate->getTarget().hasValue() )
469 return false;
470
471 const sal_Int16 nNodeType = xNode->getType();
472
473 if( nNodeType == AnimationNodeType::TRANSITIONFILTER )
474 return true;
475
476 OUString aAttributeName( xAnimate->getAttributeName() );
477
478 if( (nNodeType == AnimationNodeType::SET) && aAttributeName == "fill.on" )
479 return false;
480
482
484
485 if( (nNodeType == AnimationNodeType::ANIMATEMOTION) ||
486 (nNodeType == AnimationNodeType::ANIMATETRANSFORM) )
487 {
488 aAttributeName.clear();
489 }
490 else
491 {
492 while( p->mpMSName )
493 {
494 if( aAttributeName.equalsAscii( p->mpMSName ) )
495 break;
496
497 p++;
498 }
499
500 DBG_ASSERT( p->mpMSName || aAttributeName.isEmpty(), "sd::AnimationImporter::convertAnimationNode(), unknown attribute!" );
501#ifdef DBG_ANIM_LOG
502 if( p->mpMSName == 0 ) dump( "<error text=\"sd::AnimationImporter::convertAnimationNode(), unknown attribute!\"/>\n" );
503#endif
504
505 eAttribute = p->meAttribute;
506
507 if( p->mpAPIName )
508 aAttributeName = OUString::createFromAscii( p->mpAPIName );
509 }
510
511 xAnimate->setAttributeName( aAttributeName );
512
514 {
515 Any aAny( xAnimate->getFrom() );
516 if( aAny.hasValue() )
517 {
518 if(oox::ppt::convertAnimationValue(eAttribute, aAny))
519 xAnimate->setFrom( aAny );
520 }
521
522 aAny = xAnimate->getBy();
523 if( aAny.hasValue() )
524 {
525 if(oox::ppt::convertAnimationValue(eAttribute, aAny))
526 xAnimate->setBy( aAny );
527 }
528
529 aAny = xAnimate->getTo();
530 if( aAny.hasValue() )
531 {
532 if(oox::ppt::convertAnimationValue(eAttribute, aAny))
533 xAnimate->setTo( aAny );
534 }
535
536 Sequence< Any > aValues( xAnimate->getValues() );
537 if( aValues.hasElements() )
538 {
539 for( Any& rValue : asNonConstRange(aValues) )
540 oox::ppt::convertAnimationValue(eAttribute, rValue);
541
542 xAnimate->setValues( aValues );
543 }
544
545 OUString aFormula( xAnimate->getFormula() );
546 if( !aFormula.isEmpty() )
547 {
548 if(oox::ppt::convertMeasure(aFormula))
549 xAnimate->setFormula( aFormula );
550 }
551 }
552
553 // check for after-effect
554 Sequence< NamedValue > aUserData( xNode->getUserData() );
555 NamedValue* pLastValue = aUserData.getArray();
556 sal_Int32 nRemoved = 0;
557
558 bool bAfterEffect = false;
559 sal_Int32 nMasterRel = 0;
560 for( const NamedValue& rValue : std::as_const(aUserData) )
561 {
562 if ( rValue.Name == "after-effect" )
563 {
564 rValue.Value >>= bAfterEffect;
565 nRemoved++;
566 }
567 else if ( rValue.Name == "master-rel" )
568 {
569 rValue.Value >>= nMasterRel;
570 nRemoved++;
571 }
572 else
573 {
574 if( nRemoved )
575 *pLastValue = rValue;
576 pLastValue++;
577 }
578 }
579
580 if( nRemoved )
581 {
582 aUserData.realloc( aUserData.getLength() - nRemoved );
583 xNode->setUserData( aUserData );
584 }
585
586 // if it's an after effect node, add it to the list for
587 // later processing
588 // after effect nodes are not inserted at their import
589 // position, so return false in this case
590 if( bAfterEffect )
591 {
592 if( nMasterRel != 2 )
593 {
594 Event aEvent;
595
596 aEvent.Source <<= xParent;
597 aEvent.Trigger = EventTrigger::END_EVENT;
598 aEvent.Repeat = 0;
599
600 xNode->setBegin( Any( aEvent ) );
601 }
602
603 // add to after effect nodes for later processing
604 sd::AfterEffectNode aNode( xNode, xParent, nMasterRel == 2 );
605 maAfterEffectNodes.push_back( aNode );
606 return false;
607 }
608
609 return true;
610}
611
612void AnimationImporter::fillNode( Reference< XAnimationNode > const & xNode, const AnimationNode& rNode, const PropertySet& rSet )
613{
614 bool bAfterEffect = false;
615
616 // attribute Restart
617 if( rNode.mnRestart )
618 {
619 sal_Int16 nRestart = AnimationRestart::DEFAULT;
620 switch( rNode.mnRestart )
621 {
622 case 1: nRestart = AnimationRestart::ALWAYS; break;
623 case 2: nRestart = AnimationRestart::WHEN_NOT_ACTIVE; break;
624 case 3: nRestart = AnimationRestart::NEVER; break;
625 }
626 xNode->setRestart( nRestart );
627 }
628
629 // attribute Fill
630 if( rNode.mnFill )
631 {
632 sal_Int16 nFill = AnimationFill::DEFAULT;
633 switch( rNode.mnFill )
634 {
635 case 1: nFill = AnimationFill::REMOVE; break;
636 case 2: nFill = AnimationFill::FREEZE; break;
637 case 3: nFill = AnimationFill::HOLD; break;
638 case 4: nFill = AnimationFill::TRANSITION; break;
639 }
640 xNode->setFill( nFill );
641 }
642
643 // attribute Duration
644 if( rNode.mnDuration )
645 {
646 Any aDuration;
647 if( rNode.mnDuration > 0 )
648 {
649 aDuration <<= rNode.mnDuration / 1000.0;
650 }
651 else if( rNode.mnDuration < 0 )
652 {
653 aDuration <<= Timing_INDEFINITE;
654 }
655 xNode->setDuration( aDuration );
656 }
657
658 // TODO: DFF_ANIM_PATH_EDIT_MODE
659
660 // set user data
661 Sequence< NamedValue > aUserData;
662
663 // attribute Type
664 if( rSet.hasProperty( DFF_ANIM_NODE_TYPE ) )
665 {
666 sal_Int32 nPPTNodeType = 0;
667 if( rSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType )
668 {
669 sal_Int16 nNodeType = css::presentation::EffectNodeType::DEFAULT;
670 switch( nPPTNodeType )
671 {
672 case DFF_ANIM_NODE_TYPE_CLICK_PARALLEL: [[fallthrough]];
673 case DFF_ANIM_NODE_TYPE_ON_CLICK: nNodeType = css::presentation::EffectNodeType::ON_CLICK; break;
674 case DFF_ANIM_NODE_TYPE_WITH_GROUP: [[fallthrough]];
675 case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: nNodeType = css::presentation::EffectNodeType::WITH_PREVIOUS; break;
676 case DFF_ANIM_NODE_TYPE_AFTER_GROUP: [[fallthrough]];
677 case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: nNodeType = css::presentation::EffectNodeType::AFTER_PREVIOUS; break;
678 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: nNodeType = css::presentation::EffectNodeType::MAIN_SEQUENCE; break;
679 case DFF_ANIM_NODE_TYPE_TIMING_ROOT: nNodeType = css::presentation::EffectNodeType::TIMING_ROOT; break;
680 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:nNodeType = css::presentation::EffectNodeType::INTERACTIVE_SEQUENCE; break;
681 }
682
683 sal_Int32 nSize = aUserData.getLength();
684 aUserData.realloc(nSize+1);
685 auto pUserData = aUserData.getArray();
686 pUserData[nSize].Name = "node-type";
687 pUserData[nSize].Value <<= nNodeType;
688 }
689 }
690
691 if( rSet.hasProperty( DFF_ANIM_GROUP_ID ) )
692 {
693 sal_Int32 nGroupId;
694 if( rSet.getProperty( DFF_ANIM_GROUP_ID ) >>= nGroupId )
695 {
696 sal_Int32 nSize = aUserData.getLength();
697 aUserData.realloc(nSize+1);
698 auto pUserData = aUserData.getArray();
699 pUserData[nSize].Name = "group-id";
700 pUserData[nSize].Value <<= nGroupId;
701 }
702 }
703
704 sal_Int16 nEffectPresetClass = EffectPresetClass::CUSTOM;
705 sal_Int32 nPresetId = 0;
706
707 if( rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) )
708 {
709 sal_Int32 nPresetClass = 0;
710 if ( rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass )
711 {
712 switch( nPresetClass )
713 {
714 case DFF_ANIM_PRESS_CLASS_ENTRANCE: nEffectPresetClass = EffectPresetClass::ENTRANCE; break;
715 case DFF_ANIM_PRESS_CLASS_EXIT: nEffectPresetClass = EffectPresetClass::EXIT; break;
716 case DFF_ANIM_PRESS_CLASS_EMPHASIS: nEffectPresetClass = EffectPresetClass::EMPHASIS; break;
717 case DFF_ANIM_PRESS_CLASS_MOTIONPATH: nEffectPresetClass = EffectPresetClass::MOTIONPATH; break;
718 case DFF_ANIM_PRESS_CLASS_OLE_ACTION: nEffectPresetClass = EffectPresetClass::OLEACTION; break;
719 case DFF_ANIM_PRESS_CLASS_MEDIACALL: nEffectPresetClass = EffectPresetClass::MEDIACALL; break;
720 }
721 sal_Int32 nSize = aUserData.getLength();
722 aUserData.realloc(nSize+1);
723 auto pUserData = aUserData.getArray();
724 pUserData[nSize].Name = "preset-class";
725 pUserData[nSize].Value <<= nEffectPresetClass;
726 }
727 }
728
729 if( rSet.hasProperty( DFF_ANIM_PRESET_ID ) )
730 {
731 if( rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId )
732 {
733 sal_Int32 nSize = aUserData.getLength();
734 aUserData.realloc(nSize+1);
735 auto pUserData = aUserData.getArray();
736 pUserData[nSize].Name = "preset-id";
737
739 while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) )
740 p++;
741
742 if( p->mpStrPresetId )
743 {
744 pUserData[nSize].Value <<= OUString::createFromAscii( p->mpStrPresetId );
745 }
746 else
747 {
748 OUStringBuffer sBuffer( "ppt_" );
749 switch( nEffectPresetClass )
750 {
751 case EffectPresetClass::ENTRANCE: sBuffer.append( "entrance_" ); break;
752 case EffectPresetClass::EXIT: sBuffer.append( "exit_" ); break;
753 case EffectPresetClass::EMPHASIS: sBuffer.append( "emphasis_" ); break;
754 case EffectPresetClass::MOTIONPATH: sBuffer.append( "motionpath_" ); break;
755 case EffectPresetClass::OLEACTION: sBuffer.append( "oleaction_" ); break;
756 case EffectPresetClass::MEDIACALL: sBuffer.append( "mediacall_" ); break;
757 }
758 sBuffer.append( nPresetId );
759
760 pUserData[nSize].Value <<= sBuffer.makeStringAndClear();
761 }
762 }
763 }
764
765 if( rSet.hasProperty( DFF_ANIM_PRESET_SUB_TYPE ) )
766 {
767 sal_Int32 nPresetSubType = 0;
768 if( rSet.getProperty( DFF_ANIM_PRESET_SUB_TYPE ) >>= nPresetSubType )
769 {
770 if( nPresetSubType )
771 {
772 sal_Int32 nSize = aUserData.getLength();
773 aUserData.realloc(nSize+1);
774 auto pUserData = aUserData.getArray();
775 pUserData[nSize].Name = "preset-sub-type";
776 pUserData[nSize].Value <<= oox::ppt::getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType );
777 }
778 }
779 }
780
781 if( rSet.hasProperty( DFF_ANIM_AFTEREFFECT ) )
782 {
783 if( rSet.getProperty( DFF_ANIM_AFTEREFFECT ) >>= bAfterEffect )
784 {
785 sal_Int32 nSize = aUserData.getLength();
786 aUserData.realloc(nSize+1);
787 auto pUserData = aUserData.getArray();
788 pUserData[nSize].Name = "after-effect";
789 pUserData[nSize].Value <<= bAfterEffect;
790 }
791 }
792
793 if( bAfterEffect && rSet.hasProperty( DFF_ANIM_MASTERREL ) )
794 {
795 sal_Int32 nMasterRel = 2;
796 if( rSet.getProperty( DFF_ANIM_MASTERREL ) >>= nMasterRel )
797 {
798 sal_Int32 nSize = aUserData.getLength();
799 aUserData.realloc(nSize+1);
800 auto pUserData = aUserData.getArray();
801 pUserData[nSize].Name = "master-rel";
802 pUserData[nSize].Value <<= nMasterRel;
803 }
804 }
805
806 xNode->setUserData( aUserData );
807
808 // TODO: DFF_ANIM_ID
809 if( rSet.hasProperty( DFF_ANIM_ID ) )
810 {
811 OUString aString;
812 rSet.getProperty( DFF_ANIM_ID ) >>= aString;
813 //if( !aString.isEmpty() )
814 //{
815 //}
816 }
817
818 // TODO: DFF_ANIM_EVENT_FILTER
819 if( rSet.hasProperty( DFF_ANIM_EVENT_FILTER ) )
820 {
821 OUString aString;
822 rSet.getProperty( DFF_ANIM_EVENT_FILTER ) >>= aString;
823 //if( !aString.isEmpty() )
824 //{
825 //}
826 }
827
828 // DFF_ANIM_TIMEFILTER
829 if( rSet.hasProperty( DFF_ANIM_TIMEFILTER ) )
830 {
831 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
832 if( xAnim.is() )
833 {
834 OUString aString;
835 rSet.getProperty( DFF_ANIM_TIMEFILTER ) >>= aString;
836 if( !aString.isEmpty() )
837 {
838 sal_Int32 nElements = 1; // a non empty string has at least one value
839
840 sal_Int32 fromIndex = 0;
841 while(true)
842 {
843 fromIndex = aString.indexOf( ';', fromIndex );
844 if( fromIndex == -1 )
845 break;
846
847 fromIndex++;
848 nElements++;
849 }
850
851 Sequence< TimeFilterPair > aTimeFilter( nElements );
852
853 TimeFilterPair* pValues = aTimeFilter.getArray();
854 sal_Int32 nIndex = 0;
855 while( (nElements--) && (nIndex >= 0) )
856 {
857 const std::u16string_view aToken( o3tl::getToken(aString, 0, ';', nIndex ) );
858
859 size_t nPos = aToken.find( ',' );
860 if( nPos != std::u16string_view::npos )
861 {
862 pValues->Time = o3tl::toDouble(aToken.substr( 0, nPos ));
863 pValues->Progress = o3tl::toDouble(aToken.substr( nPos+1 ));
864 }
865 pValues++;
866 }
867
868 xAnim->setTimeFilter( aTimeFilter );
869 }
870 }
871 }
872
873// TODO: DFF_ANIM_ENDAFTERSLIDE / DFF_ANIM_VOLUME handling. git history has sample code
874 Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
875 if( !xColor.is() )
876 return;
877
878 if( rSet.hasProperty( DFF_ANIM_DIRECTION ) )
879 {
880 bool bDirection = false;
881 if( rSet.getProperty( DFF_ANIM_DIRECTION ) >>= bDirection )
882 xColor->setDirection( !bDirection );
883 }
884
885 if( rSet.hasProperty( DFF_ANIM_COLORSPACE ) )
886 {
887 sal_Int32 nColorSpace = 0;
888 rSet.getProperty( DFF_ANIM_COLORSPACE ) >>= nColorSpace;
889 xColor->setColorInterpolation( (nColorSpace == 0) ? AnimationColorSpace::RGB : AnimationColorSpace::HSL );
890 }
891}
892
893int AnimationImporter::importTimeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
894{
895 int nNodes = 0;
896
897 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!");
898 if( pAtom && xNode.is() )
899 {
900 importAnimationEvents( pAtom, xNode );
901 importAnimationValues( pAtom, xNode );
902 importAnimationActions( pAtom, xNode );
903
904 dump(">\n");
905
906 // import sub containers
907 const Atom* pChildAtom = pAtom->findFirstChildAtom();
908
909 while( pChildAtom )
910 {
911 switch( pChildAtom->getType() )
912 {
918 break;
919
921 {
922 if( pChildAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
923 {
924 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
925 Reference< XAnimationNode > xChildNode( Command::create(xContext), UNO_QUERY_THROW );
926 nNodes += importAnimationNodeContainer( pChildAtom, xChildNode );
927 Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY );
928 if( xParentContainer.is() && xChildNode.is() )
929 xParentContainer->appendChild( xChildNode );
930 }
931 else
932 {
933 nNodes += importAnimationContainer( pChildAtom, xNode );
934 }
935 }
936 break;
938 {
939 nNodes += importAnimationContainer( pChildAtom, xNode );
940 }
941 break;
943 {
944 if( pChildAtom->seekToContent() )
945 {
946 float fInterval(0.0);
947 sal_Int32 nTextUnitEffect(0), nU1(0), nU2(0), nU3(0);
948
949 mrStCtrl.ReadFloat( fInterval ).ReadInt32( nTextUnitEffect ).ReadInt32( nU1 ).ReadInt32( nU2 ).ReadInt32( nU3 );
950
951 Reference< XIterateContainer > xIter( xNode, UNO_QUERY );
952 if( xIter.is() )
953 {
954 sal_Int16 nIterateType = TextAnimationType::BY_PARAGRAPH;
955 switch( nTextUnitEffect )
956 {
957 case 1: nIterateType = TextAnimationType::BY_WORD; break;
958 case 2: nIterateType = TextAnimationType::BY_LETTER; break;
959 }
960 xIter->setIterateType( nIterateType );
961 xIter->setIterateInterval( static_cast<double>(fInterval) );
962 }
963
964 nNodes++;
965
966 dump( "<iterate" );
967 dump( " iterateType=\"%s\"", (nTextUnitEffect == 0) ? "byElement" : (nTextUnitEffect == 1) ? "byWord" : "byLetter" );
968 dump( " iterateInterval=\"%g\"", fInterval );
969 dump( " u1=\"%ld\"", nU1 );
970 dump( " u2=\"%ld\"", nU2 );
971 dump( " u3=\"%ld\"/>\n", nU3 );
972 }
973 }
974 break;
975
976 case 0xf136:
977 {
978#ifdef DBG_ANIM_LOG
979 sal_uInt32 nU1, nU2;
981
982 fprintf( mpFile, "<unknown_0xf136 nU1=\"%" SAL_PRIdINT32 "\" nU2=\"%" SAL_PRIdINT32 "\"/>\n", nU1, nU2 );
983#endif
984 }
985 break;
986
987 default:
988 {
989 dump_atom_header( pChildAtom, true, false );
990 dump_atom( pChildAtom );
991 dump_atom_header( pChildAtom, false, false );
992 }
993 break;
994 }
995
996 pChildAtom = Atom::findNextChildAtom( pChildAtom );
997 }
998 }
999
1000 return nNodes;
1001}
1002
1003int AnimationImporter::importAnimationNodeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1004{
1005 int nNodes = 0;
1006
1007 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationNodeContainer()!");
1008 if( pAtom && xNode.is() )
1009 {
1010 importAnimationEvents( pAtom, xNode );
1011 importAnimationValues( pAtom, xNode );
1012 importAnimationActions( pAtom, xNode );
1013
1014 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1015
1016 while( pChildAtom )
1017 {
1018 nNodes ++;
1019 switch( pChildAtom->getType() )
1020 {
1021 case DFF_msofbtAnimNode:
1026 break;
1027
1029 importAnimateFilterContainer( pChildAtom, xNode );
1030 break;
1031
1033 importAnimateSetContainer( pChildAtom, xNode );
1034 break;
1035
1036 case DFF_msofbtAnimate:
1037 importAnimateContainer( pChildAtom, xNode );
1038 break;
1039
1041 importAnimateScaleContainer( pChildAtom, xNode );
1042 break;
1043
1045 importAnimateColorContainer( pChildAtom, xNode );
1046 break;
1047
1049 importAnimateRotationContainer( pChildAtom, xNode );
1050 break;
1051
1053 importAnimateMotionContainer( pChildAtom, xNode );
1054 break;
1055
1057 importCommandContainer( pChildAtom, xNode );
1058 break;
1059
1060 default:
1061 {
1062 nNodes --;
1063 dump_atom_header( pChildAtom, true, false );
1064 dump_atom( pChildAtom );
1065 dump_atom_header( pChildAtom, false, false );
1066 }
1067 break;
1068 }
1069
1070 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1071 }
1072 }
1073
1074 return nNodes;
1075}
1076
1077void AnimationImporter::importAnimateFilterContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1078{
1079 Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
1080
1081 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateFilter && xFilter.is(), "invalid call to ppt::AnimationImporter::importAnimateFilterContainer()!");
1082 if( !(pAtom && xFilter.is()) )
1083 return;
1084
1085 sal_uInt32 nBits = 0;
1086
1087 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1088
1089 while( pChildAtom )
1090 {
1091 if( !pChildAtom->isContainer() )
1092 {
1093 if( !pChildAtom->seekToContent() )
1094 break;
1095 }
1096
1097 switch( pChildAtom->getType() )
1098 {
1100 {
1101 sal_uInt32 transition(0);
1102 mrStCtrl.ReadUInt32( nBits );
1103 mrStCtrl.ReadUInt32( transition );
1104
1105 if( nBits & 1 )
1106 xFilter->setMode( transition == 0 );
1107
1108 dump( " transition=\"%s\"", (transition == 0) ? "in" : "out" );
1109 }
1110 break;
1111
1113 {
1114 if( (nBits & 2 ) && ( pChildAtom->getInstance() == 1 ) )
1115 {
1116 Any aAny;
1117 if ( importAttributeValue( pChildAtom, aAny ) )
1118 {
1119 OUString filter;
1120 aAny >>= filter;
1121
1122 dump( " filter=\"%s\"", filter );
1123
1125 if( pTransition )
1126 {
1127 xFilter->setTransition( pTransition->mnType );
1128 xFilter->setSubtype( pTransition->mnSubType );
1129 xFilter->setDirection( pTransition->mbDirection );
1130 }
1131 else
1132 {
1133 OSL_FAIL( "unknown transition!" );
1134 }
1135 }
1136 }
1137 }
1138 break;
1139
1141 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1142 break;
1143
1144 default:
1145 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1146 break;
1147
1148 }
1149
1150 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1151 }
1152}
1153
1154void AnimationImporter::importAnimateAttributeTargetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1155{
1156 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateTarget, "invalid call to ppt::AnimationImporter::importAnimateAttributeTargetContainer()!");
1157
1158 Any aTarget;
1159
1160 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
1161
1162 bool bWrongContext = false;
1163
1164 if( pAtom )
1165 {
1166 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1167
1168 while( pChildAtom )
1169 {
1170 if( !pChildAtom->isContainer() )
1171 {
1172 if( !pChildAtom->seekToContent() )
1173 break;
1174 }
1175
1176 switch( pChildAtom->getType() )
1177 {
1179 {
1180 PropertySet aSet;
1181 importPropertySetContainer( pChildAtom, aSet );
1183 {
1184 OUString aContext;
1185 if( aSet.getProperty( DFF_ANIM_RUNTIMECONTEXT ) >>= aContext )
1186 {
1187 if( aContext != "PPT" )
1188 bWrongContext = true;
1189 }
1190 }
1191
1192 dump( aSet );
1193 }
1194 break;
1195
1197 {
1198 if( xAnimate.is() )
1199 {
1200 sal_uInt32 nBits(0);
1201 sal_uInt32 nAdditive(0);
1202 sal_uInt32 nAccumulate(0);
1203 sal_uInt32 nTransformType(0);
1204
1205 mrStCtrl.ReadUInt32( nBits ).ReadUInt32( nAdditive ).ReadUInt32( nAccumulate ).ReadUInt32( nTransformType );
1206
1207 // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype
1208 // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none
1209 // nAccumulate 0 = none, 1 = always
1210 // nTransformType 0: "property" else "image"
1211
1212 if( nBits & 3 && xAnimate.is() )
1213 {
1214 if( nBits & 1 )
1215 {
1216 sal_Int16 nTemp = AnimationAdditiveMode::BASE;
1217 switch( nAdditive )
1218 {
1219 case 1: nTemp = AnimationAdditiveMode::SUM; break;
1220 case 2: nTemp = AnimationAdditiveMode::REPLACE; break;
1221 case 3: nTemp = AnimationAdditiveMode::MULTIPLY; break;
1222 case 4: nTemp = AnimationAdditiveMode::NONE; break;
1223 }
1224 xAnimate->setAdditive( nTemp );
1225 }
1226
1227 if( nBits & 2 )
1228 {
1229 xAnimate->setAccumulate( nAccumulate == 0 );
1230 }
1231 }
1232#ifdef DBG_ANIM_LOG
1233 if( nBits & 1 )
1234 fprintf( mpFile, " additive=\"%s\"", (nAdditive == 0) ? "base" : (nAdditive == 2) ? "replace" : (nAdditive == 1) ? "sum" : (nAdditive == 3 ) ? "multiply" : (nAdditive == 4) ? "none" : "unknown" );
1235
1236 if( nBits & 2 )
1237 fprintf( mpFile, " accumulate=\"%s\"", (nAccumulate == 0) ? "none" : "always" );
1238
1239 if( nBits & 8 )
1240 fprintf( mpFile, " transformType=\"%s\"", (nTransformType == 0) ? "property" : "image" );
1241#endif
1242 }
1243 }
1244 break;
1245
1247 {
1248 if( xAnimate.is() )
1249 {
1250 OUString aAttributeName;
1251 importAttributeNamesContainer( pChildAtom, aAttributeName );
1252 if( xAnimate.is() )
1253 xAnimate->setAttributeName( aAttributeName );
1254 dump( " attributeName=\"%s\"", aAttributeName );
1255 }
1256 }
1257 break;
1258
1260 {
1261 sal_Int16 nSubType;
1262 importTargetElementContainer( pChildAtom, aTarget, nSubType );
1263 if( xAnimate.is() )
1264 xAnimate->setSubItem( nSubType );
1265
1266 dump( " target=\"" );
1267 dump_target( aTarget );
1268 dump( "\"" );
1269 }
1270 break;
1271
1272 default:
1273 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1274 break;
1275 }
1276
1277 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1278 }
1279 }
1280
1281 if( bWrongContext )
1282 aTarget.clear();
1283
1284 if( xAnimate.is() )
1285 xAnimate->setTarget( aTarget );
1286 else
1287 {
1288 Reference< XCommand > xCommand( xNode, UNO_QUERY );
1289 if( xCommand.is() )
1290 xCommand->setTarget( aTarget );
1291 }
1292}
1293
1294sal_Int16 AnimationImporter::implGetColorSpace( sal_Int32 nMode, sal_Int32 /*nA*/, sal_Int32 /*nB*/, sal_Int32 /*nC*/ )
1295{
1296 switch( nMode )
1297 {
1298 case 2: // index
1299 default:
1300 case 0: // rgb
1301 return AnimationColorSpace::RGB;
1302
1303 case 1: // hsl
1304 return AnimationColorSpace::HSL;
1305 }
1306}
1307
1308Any AnimationImporter::implGetColorAny( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC )
1309{
1310 switch( nMode )
1311 {
1312 case 0: // rgb
1313 {
1314 dump( "rgb(%ld", nA );
1315 dump( ",%ld", nB );
1316 dump( ",%ld)", nC );
1317 Color aColor( static_cast<sal_uInt8>(nA), static_cast<sal_uInt8>(nB), static_cast<sal_uInt8>(nC) );
1318 return Any( static_cast<sal_Int32>(aColor.GetRGBColor()) );
1319 }
1320 case 1: // hsl
1321 {
1322 dump( "hsl(%ld", nA );
1323 dump( ",%ld", nB );
1324 dump( ",%ld)", nC );
1325 Sequence< double > aHSL{ nA * 360.0/255.0,
1326 nB / 255.0,
1327 nC / 255.0 };
1328 return Any( aHSL );
1329 }
1330
1331 case 2: // index
1332 {
1333 Color aColor;
1334 mpPPTImport->GetColorFromPalette(static_cast<sal_uInt16>(nA), aColor );
1335 dump( "index(%ld", nA );
1336 dump( " [%ld", static_cast<sal_Int32>(aColor.GetRed()) );
1337 dump( ",%ld", static_cast<sal_Int32>(aColor.GetGreen()) );
1338 dump( ",%ld])", static_cast<sal_Int32>(aColor.GetBlue()) );
1339 return Any( static_cast<sal_Int32>(aColor.GetRGBColor()) );
1340 }
1341
1342 default:
1343 {
1344 dump( "unknown_%ld(", nMode );
1345 dump( "%ld", nA );
1346 dump( ",%ld", nB );
1347 dump( ",%ld)", nC );
1348 OSL_FAIL( "ppt::implGetColorAny(), unhandled color type" );
1349
1350 Any aAny;
1351 return aAny;
1352 }
1353 }
1354}
1355
1356void AnimationImporter::importAnimateColorContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1357{
1358 Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
1359
1360 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateColor && xColor.is(), "invalid call to ppt::AnimationImporter::importAnimateColorContainer()!");
1361 if( !(pAtom && xColor.is()) )
1362 return;
1363
1364 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1365
1366 while( pChildAtom )
1367 {
1368 if( !pChildAtom->isContainer() )
1369 {
1370 if( !pChildAtom->seekToContent() )
1371 break;
1372 }
1373
1374 switch( pChildAtom->getType() )
1375 {
1377 {
1378 sal_uInt32 nBits;
1379 sal_Int32 nByMode, nByA, nByB, nByC;
1380 sal_Int32 nFromMode, nFromA, nFromB, nFromC;
1381 sal_Int32 nToMode, nToA, nToB, nToC;
1382 mrStCtrl.ReadUInt32( nBits );
1383 mrStCtrl.ReadInt32( nByMode ).ReadInt32( nByA ).ReadInt32( nByB ).ReadInt32( nByC );
1384 mrStCtrl.ReadInt32( nFromMode ).ReadInt32( nFromA ).ReadInt32( nFromB ).ReadInt32( nFromC );
1385 mrStCtrl.ReadInt32( nToMode ).ReadInt32( nToA ).ReadInt32( nToB ).ReadInt32( nToC );
1386
1387 if (!mrStCtrl.good())
1388 {
1389 SAL_WARN("filter.ms", "DFF_msofbtAnimateColorData: short read");
1390 break;
1391 }
1392
1393 if( nBits & 1 )
1394 {
1395 dump( " by=\"" );
1396 xColor->setBy( implGetColorAny( nByMode, nByA, nByB, nByC ) );
1397 xColor->setColorInterpolation( implGetColorSpace( nByMode, nByA, nByB, nByC ) );
1398 dump( "\"");
1399 }
1400
1401 if( nBits & 2 )
1402 {
1403 dump( " from=\"" );
1404 xColor->setFrom( implGetColorAny( nFromMode, nFromA, nFromB, nFromC ) );
1405 xColor->setColorInterpolation( implGetColorSpace( nFromMode, nFromA, nFromB, nFromC ) );
1406 dump( "\"");
1407 }
1408
1409 if( nBits & 4 )
1410 {
1411 dump( " to=\"" );
1412 xColor->setTo( implGetColorAny( nToMode, nToA, nToB, nToC ) );
1413 xColor->setColorInterpolation( implGetColorSpace( nToMode, nToA, nToB, nToC ) );
1414 dump( "\"");
1415 }
1416 }
1417 break;
1418
1420 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1421 break;
1422
1423 default:
1424 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1425 break;
1426 }
1427
1428 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1429 }
1430}
1431
1432void AnimationImporter::importAnimateSetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1433{
1434 Reference< XAnimateSet > xSet( xNode, UNO_QUERY );
1435
1436 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateSet && xSet.is(), "invalid call to ppt::AnimationImporter::importAnimateSetContainer()!");
1437 if( !(pAtom && xSet.is()) )
1438 return;
1439
1440 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1441
1442 while( pChildAtom )
1443 {
1444 if( !pChildAtom->isContainer() )
1445 {
1446 if( !pChildAtom->seekToContent() )
1447 break;
1448 }
1449
1450 switch( pChildAtom->getType() )
1451 {
1453 {
1454 sal_Int32 nU1, nU2;
1455 mrStCtrl.ReadInt32( nU1 ).ReadInt32( nU2 );
1456
1457 dump( " set_1=\"%ld\"", nU1 );
1458 dump( " set_2=\"%ld\"", nU2 );
1459 }
1460 break;
1461
1463 {
1464 Any aTo;
1465 if ( importAttributeValue( pChildAtom, aTo ) )
1466 {
1467 xSet->setTo( aTo );
1468
1469 dump( " value=\"" );
1470 dump( aTo );
1471 dump( "\"" );
1472 }
1473 }
1474 break;
1475
1477 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1478 break;
1479
1480 default:
1481 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1482 break;
1483 }
1484
1485 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1486 }
1487}
1488
1489void AnimationImporter::importAnimateContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1490{
1491 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
1492
1493 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimate && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateContainer()!");
1494 if( !(pAtom && xAnim.is()) )
1495 return;
1496
1497 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1498
1499 while( pChildAtom )
1500 {
1501 if( !pChildAtom->isContainer() )
1502 {
1503 if( !pChildAtom->seekToContent() )
1504 break;
1505 }
1506
1507 switch( pChildAtom->getType() )
1508 {
1510 {
1511 sal_uInt32 nCalcmode(0), nBits(0), nValueType(0);
1512 mrStCtrl.ReadUInt32( nCalcmode ).ReadUInt32( nBits ).ReadUInt32( nValueType );
1513
1514 if( nBits & 0x08 )
1515 {
1516 sal_Int16 n = (nCalcmode == 1) ? AnimationCalcMode::LINEAR : /* (nCalcmode == 2) ? AnimationCalcMode::FORMULA : */ AnimationCalcMode::DISCRETE;
1517 xAnim->setCalcMode( n );
1518 dump( " calcmode=\"%s\"", (nCalcmode == 0) ? "discrete" : (nCalcmode == 1) ? "linear" : (nCalcmode == 2) ? "formula" : "unknown" );
1519 }
1520
1521 if( nBits & 0x30 )
1522 {
1523 sal_Int16 n = (nValueType == 1) ? AnimationValueType::NUMBER : (nValueType == 2 ) ? AnimationValueType::COLOR : AnimationValueType::STRING;
1524 xAnim->setValueType( n );
1525 dump( " valueType=\"%s\"", (nValueType == 0) ? "string" : (nValueType == 1) ? "number" : (nValueType == 2) ? "color" : "unknown" );
1526 }
1527 }
1528 break;
1529
1531 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1532 break;
1533
1535 importAnimateKeyPoints( pChildAtom, xNode );
1536 break;
1537
1539 {
1540 Any a;
1541 if ( importAttributeValue( pChildAtom, a ) )
1542 {
1543 switch( pChildAtom->getInstance() )
1544 {
1545 case 1: xAnim->setBy( a ); dump( " by=\"" ); break;
1546 case 2: xAnim->setFrom( a ); dump( " from=\"" ); break;
1547 case 3: xAnim->setTo( a ); dump( " to=\"" ); break;
1548 default:
1549 dump( " unknown_value=\"" );
1550 }
1551
1552 dump( a );
1553 dump( "\"" );
1554 }
1555 }
1556 break;
1557 default:
1558 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1559 break;
1560 }
1561
1562 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1563 }
1564}
1565
1566void AnimationImporter::importAnimateMotionContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1567{
1568 Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY );
1569
1570 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateMotion && xMotion.is(), "invalid call to ppt::AnimationImporter::importAnimateMotionContainer()!");
1571 if( !(pAtom && xMotion.is()) )
1572 return;
1573
1574 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1575
1576 while( pChildAtom )
1577 {
1578 if( !pChildAtom->isContainer() )
1579 {
1580 if( !pChildAtom->seekToContent() )
1581 break;
1582 }
1583
1584 switch( pChildAtom->getType() )
1585 {
1587 {
1588 sal_uInt32 nBits, nOrigin;
1589 float fByX, fByY, fFromX, fFromY, fToX, fToY;
1590
1591 mrStCtrl.ReadUInt32( nBits ).ReadFloat( fByX ).ReadFloat( fByY ).ReadFloat( fFromX ).ReadFloat( fFromY ).ReadFloat( fToX ).ReadFloat( fToY ).ReadUInt32( nOrigin );
1592
1593#ifdef DBG_ANIM_LOG
1594 if( nBits & 1 )
1595 fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY );
1596
1597 if( nBits & 2 )
1598 fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY );
1599
1600 if( nBits & 4 )
1601 fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY );
1602
1603 if( nBits & 8 )
1604 fprintf( mpFile, " origin=\"%s\"", (nOrigin == 1) ? "parent" : (nOrigin == 2) ? "layout" : "unknown" );
1605
1606#endif
1607 }
1608 break;
1609
1611 {
1612 Any aPath;
1613 if ( importAttributeValue( pChildAtom, aPath ) )
1614 {
1615 OUString aStr;
1616 if ( aPath >>= aStr )
1617 {
1618 // E can appear inside a number, so we only check for its presence at the end
1619 aStr = aStr.trim();
1620 if (aStr.endsWith("E"))
1621 aStr = aStr.copy(0, aStr.getLength() - 1);
1622 aStr = aStr.trim();
1623 aPath <<= aStr;
1624 xMotion->setPath( aPath );
1625 dump( " path=\"" );
1626 dump( aPath );
1627 dump( "\"" );
1628 }
1629 }
1630 }
1631 break;
1632
1634 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1635 break;
1636
1637 default:
1638 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1639 break;
1640 }
1641
1642 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1643 }
1644}
1645
1646void AnimationImporter::importCommandContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1647{
1648 Reference< XCommand > xCommand( xNode, UNO_QUERY );
1649 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimCommand && xCommand.is(), "invalid call to ppt::AnimationImporter::importCommandContainer()!");
1650 if( !(pAtom && xCommand.is()) )
1651 return;
1652
1653 sal_Int32 nBits = 0;
1654 Any aValue;
1655
1656 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1657
1658 while( pChildAtom )
1659 {
1660 if( !pChildAtom->isContainer() )
1661 {
1662 if( !pChildAtom->seekToContent() )
1663 break;
1664 }
1665
1666 switch( pChildAtom->getType() )
1667 {
1669 {
1670 sal_Int32 nCommandType;
1671 // looks like U1 is a bitset, bit 1 enables the type and bit 2 enables
1672 // a propertyvalue that follows
1673 mrStCtrl.ReadInt32( nBits );
1674 mrStCtrl.ReadInt32( nCommandType );
1675
1676 if( nBits & 1 )
1677 {
1678 dump( " type=\"%s\"", (nCommandType == 0) ? "event" : ( nCommandType == 1) ? "call" : "verb" );
1679 }
1680 }
1681 break;
1682
1684 {
1685 if ( importAttributeValue( pChildAtom, aValue ) )
1686 {
1687 if( nBits & 2 )
1688 {
1689 dump( " cmd=\"" );
1690 dump( aValue );
1691 dump( "\"" );
1692 }
1693 }
1694 }
1695 break;
1696
1698 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1699 break;
1700
1701 default:
1702 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1703 break;
1704 }
1705
1706 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1707 }
1708
1709 if( !(nBits & 3) )
1710 return;
1711
1712 OUString aParam;
1713 aValue >>= aParam;
1714
1715 sal_Int16 nCommand = EffectCommands::CUSTOM;
1716
1717 NamedValue aParamValue;
1718
1719 if ( aParam == "onstopaudio" )
1720 {
1721 nCommand = EffectCommands::STOPAUDIO;
1722 }
1723 else if ( aParam == "play" )
1724 {
1725 nCommand = EffectCommands::PLAY;
1726 }
1727 else if( aParam.startsWith( "playFrom" ) )
1728 {
1729 const std::u16string_view aMediaTime( aParam.subView( 9, aParam.getLength() - 10 ) );
1730 rtl_math_ConversionStatus eStatus;
1731 double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, u'.', u',', &eStatus );
1732 if( eStatus == rtl_math_ConversionStatus_Ok )
1733 {
1734 aParamValue.Name = "MediaTime";
1735 aParamValue.Value <<= fMediaTime;
1736 }
1737 nCommand = EffectCommands::PLAY;
1738 }
1739 else if ( aParam == "togglePause" )
1740 {
1741 nCommand = EffectCommands::TOGGLEPAUSE;
1742 }
1743 else if ( aParam == "stop" )
1744 {
1745 nCommand = EffectCommands::STOP;
1746 }
1747
1748 xCommand->setCommand( nCommand );
1749 if( nCommand == EffectCommands::CUSTOM )
1750 {
1751 OSL_FAIL("sd::AnimationImporter::importCommandContainer(), unknown command!");
1752 aParamValue.Name = "UserDefined";
1753 aParamValue.Value <<= aParam;
1754 }
1755
1756 if( aParamValue.Value.hasValue() )
1757 {
1758 Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
1759 xCommand->setParameter( Any( aParamSeq ) );
1760 }
1761}
1762
1763int AnimationImporter::importAudioContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1764{
1765 int nNodes = 0;
1766
1767 Reference< XAudio > xAudio( xNode, UNO_QUERY );
1768 DBG_ASSERT( pAtom && xAudio.is() &&
1769 ( (pAtom->getType() == DFF_msofbtAnimGroup) ||
1770 (pAtom->getType() == DFF_msofbtAnimSubGoup) ), "invalid call to ppt::AnimationImporter::importAudioContainer()!");
1771 if( pAtom && xAudio.is() )
1772 {
1773 importAnimationEvents( pAtom, xNode );
1774 importAnimationValues( pAtom, xNode );
1775 importAnimationActions( pAtom, xNode );
1776
1777 dump(">\n");
1778
1779 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1780
1781 while( pChildAtom )
1782 {
1783 if( !pChildAtom->isContainer() )
1784 {
1785 if( !pChildAtom->seekToContent() )
1786 break;
1787 }
1788
1789 switch( pChildAtom->getType() )
1790 {
1791 case DFF_msofbtAnimNode:
1796 break;
1797
1799 {
1800 Any aValue;
1801 if ( importAttributeValue( pChildAtom, aValue ) )
1802 {
1803 nNodes ++;
1804 dump( " value=\"" );
1805 dump( aValue );
1806 dump( "\"" );
1807 }
1808 }
1809 break;
1810
1812 {
1813 sal_Int16 nSubType;
1814 Any aSource;
1815 importTargetElementContainer( pChildAtom, aSource, nSubType );
1816 if( xAudio.is() ) {
1817 xAudio->setSource( aSource );
1818 nNodes ++;
1819 }
1820 }
1821 break;
1822
1823 default:
1824 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1825 break;
1826 }
1827
1828 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1829 }
1830
1831 // TODO: What to do with them?
1832 Any aEmpty;
1833 xAudio->setBegin( aEmpty );
1834 xAudio->setEnd( aEmpty );
1835 }
1836
1837 return nNodes;
1838}
1839
1840void AnimationImporter::importAnimateScaleContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1841{
1842 Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
1843
1844 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateScale && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateScaleContainer()!");
1845 if( !(pAtom && xTransform.is()) )
1846 return;
1847
1848 xTransform->setTransformType( AnimationTransformType::SCALE );
1849
1850 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1851
1852 while( pChildAtom )
1853 {
1854 if( !pChildAtom->isContainer() )
1855 {
1856 if( !pChildAtom->seekToContent() )
1857 break;
1858 }
1859
1860 switch( pChildAtom->getType() )
1861 {
1863 {
1864 sal_uInt32 nBits(0), nZoomContents(0);
1865 float fByX(0.0), fByY(0.0), fFromX(0.0), fFromY(0.0), fToX(0.0), fToY(0.0);
1866
1867 // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool)
1868 mrStCtrl.ReadUInt32( nBits ).ReadFloat( fByX ).ReadFloat( fByY ).ReadFloat( fFromX ).ReadFloat( fFromY ).ReadFloat( fToX ).ReadFloat( fToY ).ReadUInt32( nZoomContents );
1869
1870 ValuePair aPair;
1871 // 'from' value
1872 if( nBits & 2 )
1873 {
1874 aPair.First <<= static_cast<double>(fFromX) / 100.0;
1875 aPair.Second <<= static_cast<double>(fFromY) / 100.0;
1876 xTransform->setFrom( Any( aPair ) );
1877 }
1878
1879 // 'to' value
1880 if( nBits & 4 )
1881 {
1882 aPair.First <<= static_cast<double>(fToX) / 100.0;
1883 aPair.Second <<= static_cast<double>(fToY) / 100.0;
1884 xTransform->setTo( Any( aPair ) );
1885 }
1886
1887 // 'by' value
1888 if( nBits & 1 )
1889 {
1890 aPair.First <<= static_cast<double>(fByX) / 100.0;
1891 aPair.Second <<= static_cast<double>(fByY) / 100.0;
1892
1893 if( nBits & 2 )
1894 {
1895 // 'from' value given, import normally
1896 xTransform->setBy( Any( aPair ) );
1897 }
1898 else
1899 {
1900 // mapping 'by' to 'to', if no 'from' is
1901 // given. This is due to a non-conformity in
1902 // PPT, which exports animateScale effects
1903 // with a sole 'by' value, but with the
1904 // semantics of a sole 'to' animation
1905 xTransform->setTo( Any( aPair ) );
1906 }
1907 }
1908
1909#ifdef DBG_ANIM_LOG
1910 if( nBits & 1 )
1911 fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY );
1912
1913 if( nBits & 2 )
1914 fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY );
1915
1916 if( nBits & 4 )
1917 fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY );
1918
1919 if( nBits & 8 )
1920 fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" );
1921#endif
1922 }
1923 break;
1924
1926 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1927 break;
1928
1929 default:
1930 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1931 break;
1932 }
1933
1934 pChildAtom = Atom::findNextChildAtom( pChildAtom );
1935 }
1936}
1937
1938void AnimationImporter::importAnimateRotationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1939{
1940 Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
1941
1942 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateRotation && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateRotationContainer()!");
1943 if( !(pAtom && xTransform.is()) )
1944 return;
1945
1946 xTransform->setTransformType( AnimationTransformType::ROTATE );
1947
1948 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1949
1950 while( pChildAtom )
1951 {
1952 if( !pChildAtom->isContainer() )
1953 {
1954 if( !pChildAtom->seekToContent() )
1955 break;
1956 }
1957
1958 switch( pChildAtom->getType() )
1959 {
1961 {
1962 sal_uInt32 nBits(0), nU1(0);
1963 float fBy(0.0), fFrom(0.0), fTo(0.0);
1964
1965 // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool)
1966 mrStCtrl.ReadUInt32( nBits ).ReadFloat( fBy ).ReadFloat( fFrom ).ReadFloat( fTo ).ReadUInt32( nU1 );
1967
1968 if( nBits & 1 )
1969 xTransform->setBy( Any( static_cast<double>(fBy) ) );
1970
1971 if( nBits & 2 )
1972 xTransform->setFrom( Any( static_cast<double>(fFrom) ) );
1973
1974 if( nBits & 4 )
1975 xTransform->setTo( Any( static_cast<double>(fTo) ) );
1976
1977#ifdef DBG_ANIM_LOG
1978 if( nBits & 1 )
1979 fprintf( mpFile, " by=\"%g\"", (double)fBy );
1980
1981 if( nBits & 2 )
1982 fprintf( mpFile, " from=\"%g\"", (double)fFrom );
1983
1984 if( nBits & 4 )
1985 fprintf( mpFile, " to=\"%g\"", (double)fTo );
1986
1987 if( nU1 )
1988 fprintf( mpFile, " rotation_1=\"%" SAL_PRIdINT32 "\"", nU1 );
1989#endif
1990 }
1991 break;
1992
1994 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1995 break;
1996
1997 default:
1998 dump( " unknown_atom=\"%ld\"", static_cast<sal_Int32>(pChildAtom->getType()) );
1999 break;
2000 }
2001
2002 pChildAtom = Atom::findNextChildAtom( pChildAtom );
2003 }
2004}
2005
2006void AnimationImporter::importAttributeNamesContainer( const Atom* pAtom, OUString& rAttributeNames )
2007{
2008 OUStringBuffer aNames;
2009
2010 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateAttributeNames), "invalid call to ppt::AnimationImporter::importAttributeName()!" );
2011 if( pAtom )
2012 {
2013 const Atom* pAttributeValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAttributeValue );
2014
2015 while( pAttributeValueAtom )
2016 {
2017 Any aAny;
2018 if ( importAttributeValue( pAttributeValueAtom, aAny ) )
2019 {
2020 OUString aName;
2021 if( aAny >>= aName )
2022 {
2023 if( !aNames.isEmpty() )
2024 aNames.append( ';' );
2025
2026 aNames.append( aName );
2027 }
2028 }
2029 else
2030 {
2031 OSL_FAIL( "error during ppt::AnimationImporter::importAttributeName()!" );
2032 }
2033
2034 pAttributeValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimAttributeValue, pAttributeValueAtom );
2035 }
2036 }
2037
2038 rAttributeNames = aNames.makeStringAndClear();
2039}
2040
2041void AnimationImporter::importAnimationValues( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2042{
2043 DBG_ASSERT( pAtom, "invalid call to ppt::AnimationImporter::importAnimationValues()!" );
2044
2045 if( !pAtom )
2046 return;
2047
2048 const Atom* pValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimValue );
2049
2050 while( pValueAtom && pValueAtom->seekToContent() )
2051 {
2052 sal_uInt32 nType(0);
2054 switch( nType )
2055 {
2056 case 0:
2057 {
2058 float fRepeat(0.0);
2059 mrStCtrl.ReadFloat( fRepeat );
2060 xNode->setRepeatCount( (fRepeat < (float(3.40282346638528860e+38))) ? Any( static_cast<double>(fRepeat) ) : Any( Timing_INDEFINITE ) );
2061
2062#ifdef DBG_ANIM_LOG
2063 if( (fRepeat < ((float)3.40282346638528860e+38)) )
2064 {
2065 dump( " repeat=\"%g\"", (double)fRepeat );
2066 }
2067 else
2068 {
2069 dump( " repeat=\"indefinite\"" );
2070 }
2071#endif
2072 }
2073 break;
2074
2075 case 3:
2076 {
2077 float faccelerate(0.0);
2078 mrStCtrl.ReadFloat( faccelerate );
2079 xNode->setAcceleration( faccelerate );
2080 dump( " accelerate=\"%g\"", static_cast<double>(faccelerate) );
2081 }
2082 break;
2083
2084 case 4:
2085 {
2086 float fdecelerate(0.0);
2087 mrStCtrl.ReadFloat( fdecelerate );
2088 xNode->setDecelerate( fdecelerate );
2089 dump( " decelerate=\"%g\"", static_cast<double>(fdecelerate) );
2090 }
2091 break;
2092
2093 case 5:
2094 {
2095 sal_Int32 nAutoreverse(0);
2096 mrStCtrl.ReadInt32( nAutoreverse );
2097 xNode->setAutoReverse( nAutoreverse != 0 );
2098 dump( " autoreverse=\"%#lx\"", nAutoreverse );
2099 }
2100 break;
2101
2102 default:
2103 {
2104 sal_uInt32 nUnknown;
2105 mrStCtrl.ReadUInt32( nUnknown );
2106#ifdef DBG_ANIM_LOG
2107 fprintf(mpFile, " attribute_%d=\"%#lx\"", nType, nUnknown );
2108#endif
2109 }
2110 break;
2111 }
2112
2113 pValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimValue, pValueAtom );
2114 }
2115}
2116
2117void AnimationImporter::importAnimateKeyPoints( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2118{
2119 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
2120
2121 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimKeyPoints && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateKeyPoints()!" );
2122
2123 if( !(pAtom && xAnim.is()) )
2124 return;
2125
2126 // first count keytimes
2127 const Atom* pIter = nullptr;
2128 int nKeyTimes = 0;
2129
2130 while( (pIter = pAtom->findNextChildAtom( DFF_msofbtAnimKeyTime, pIter )) != nullptr )
2131 nKeyTimes++;
2132
2133 Sequence< double > aKeyTimes( nKeyTimes );
2134 auto aKeyTimesRange = asNonConstRange(aKeyTimes);
2135 Sequence< Any > aValues( nKeyTimes );
2136 auto aValuesRange = asNonConstRange(aValues);
2137 OUString aFormula;
2138
2140 bool bToNormalize = false;
2141 for( int nKeyTime = 0; (nKeyTime < nKeyTimes) && pIter; nKeyTime++ )
2142 {
2143 if( pIter->seekToContent() )
2144 {
2145 sal_Int32 nTemp(0);
2146 mrStCtrl.ReadInt32(nTemp);
2147 double fTemp = static_cast<double>(nTemp) / 1000.0;
2148 aKeyTimesRange[nKeyTime] = fTemp;
2149 if( fTemp == -1 )
2150 bToNormalize = true;
2151
2152 const Atom* pValue = Atom::findNextChildAtom(pIter);
2153 if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue )
2154 {
2155 Any aValue1, aValue2;
2156 if( importAttributeValue( pValue, aValue1 ) )
2157 {
2158 pValue = Atom::findNextChildAtom(pValue);
2159 if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue )
2160 {
2161 // Any occurrence of the formula becomes the formula of the whole list.
2162 if (importAttributeValue(pValue, aValue2) && aFormula.isEmpty())
2163 aValue2 >>= aFormula;
2164 }
2165 aValuesRange[nKeyTime] = aValue1;
2166 }
2167 }
2168 }
2169 pIter = pAtom->findNextChildAtom(DFF_msofbtAnimKeyTime, pIter);
2170 }
2171
2172#ifdef DBG_ANIM_LOG
2173 dump( " keyTimes=\"" );
2174 for( int i=0; i<nKeyTimes; ++i )
2175 dump( "%f;", aKeyTimes[i] );
2176
2177 if( !aFormula.isEmpty() )
2178 {
2179 dump( "formula=\"%s", aFormula );
2180 }
2181
2182 dump( "\" values=\"" );
2183 double nVal;
2184 OUString aStr;
2185 for( int i=0; i<nKeyTimes; ++i )
2186 {
2187 if( i != 0 )
2188 dump( ";" );
2189
2190 if( aValues[i] >>= aStr )
2191 dump( "%s",
2193 RTL_TEXTENCODING_ASCII_US ).getStr() );
2194 else if( aValues[i] >>= nVal )
2195 dump( "%f", nVal );
2196 else
2197 {
2198 ValuePair aValuePair;
2199
2200 if( aValues[i] >>= aValuePair )
2201 {
2202 if( aValuePair.First >>= aStr )
2203 dump( "%s",
2205 RTL_TEXTENCODING_ASCII_US ).getStr() );
2206 else if( aValuePair.First >>= nVal )
2207 dump( "%f", nVal );
2208 else
2209 dump( "%X", (sal_Int64)&aValuePair.First );
2210
2211 if( aValuePair.Second >>= aStr )
2212 dump( ",%s",
2214 RTL_TEXTENCODING_ASCII_US ).getStr() );
2215 else if( aValuePair.Second >>= nVal )
2216 dump( ",%f", nVal );
2217 else
2218 dump( ",%X", (sal_Int64)&aValuePair.Second );
2219 }
2220 }
2221 }
2222 dump( "\"" );
2223#endif
2224 if( bToNormalize && nKeyTimes >= 2 )
2225 {
2226 // if TimeAnimationValueList contains time -1000, key points must be evenly distributed between 0 and 1 ([MS-PPT] 2.8.31)
2227 for( int nKeyTime = 0; nKeyTime < nKeyTimes; ++nKeyTime )
2228 {
2229 aKeyTimesRange[nKeyTime] = static_cast<double>(nKeyTime) / static_cast<double>(nKeyTimes - 1);
2230 }
2231 }
2232
2233 if (aValues.getLength() != aKeyTimes.getLength())
2234 throw css::io::WrongFormatException();
2235
2236 xAnim->setKeyTimes( aKeyTimes );
2237 xAnim->setValues( aValues );
2238 xAnim->setFormula( aFormula );
2239}
2240
2241bool AnimationImporter::importAttributeValue( const Atom* pAtom, Any& rAny )
2242{
2243 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimAttributeValue, "invalid call to ppt::AnimationImporter::importAttributeValue()!" );
2244
2245 bool bOk = false;
2246
2247 if( pAtom && pAtom->seekToContent() )
2248 {
2249 sal_uInt32 nRecLen = pAtom->getLength();
2250 if ( nRecLen >= 1 )
2251 {
2252 sal_Int8 nType(0);
2254 switch( nType )
2255 {
2257 {
2258 if ( nRecLen == 2 )
2259 {
2260 sal_uInt8 nByte(0);
2261 mrStCtrl.ReadUChar( nByte );
2262 rAny <<= nByte;
2263
2264 bOk = true;
2265 }
2266 }
2267 break;
2268
2270 {
2271 if ( nRecLen == 5 )
2272 {
2273 sal_uInt32 nInt32(0);
2274 mrStCtrl.ReadUInt32( nInt32 );
2275 rAny <<= nInt32;
2276
2277 bOk = true;
2278 }
2279 }
2280 break;
2281
2283 {
2284 if( nRecLen == 5 )
2285 {
2286 float fFloat(0.0);
2287 mrStCtrl.ReadFloat( fFloat );
2288 rAny <<= static_cast<double>(fFloat);
2289
2290 bOk = true;
2291 }
2292 }
2293 break;
2294
2296 {
2297 if ( ( nRecLen & 1 ) && ( nRecLen > 1 ) )
2298 {
2299 OUString aOUString = SvxMSDffManager::MSDFFReadZString( mrStCtrl, nRecLen - 1, true );
2300 rAny <<= aOUString;
2301
2302 bOk = true;
2303 }
2304 }
2305 break;
2306 }
2307 }
2308 }
2309
2310 DBG_ASSERT( bOk, "invalid value inside ppt::AnimationImporter::importAttributeValue()!" );
2311 return bOk;
2312}
2313
2314void AnimationImporter::importAnimationEvents( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2315{
2316 DBG_ASSERT( xNode.is() && pAtom, "invalid call to ppt::AnimationImporter::importAnimationEvents()!" );
2317
2318 Any aBegin, aEnd, aNext, aPrev;
2319
2320 const Atom* pEventAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimEvent );
2321 while( pEventAtom )
2322 {
2323 Any* pEvents = nullptr;
2324
2325 switch( pEventAtom->getInstance() )
2326 {
2327 case 1: pEvents = &aBegin; break;
2328 case 2: pEvents = &aEnd; break;
2329 case 3: pEvents = &aNext; break;
2330 case 4: pEvents = &aPrev; break;
2331 }
2332
2333 if( pEvents )
2334 {
2335 Event aEvent;
2336 aEvent.Trigger = EventTrigger::NONE;
2337 aEvent.Repeat = 0;
2338
2339 const Atom* pChildAtom = pEventAtom->findFirstChildAtom();
2340
2341 while( pChildAtom && pChildAtom->seekToContent() )
2342 {
2343 switch( pChildAtom->getType() )
2344 {
2346 {
2347 sal_Int32 nU1(0), nTrigger(0), nU3(0), nBegin(0);
2348 mrStCtrl.ReadInt32( nU1 );
2349 mrStCtrl.ReadInt32( nTrigger );
2350 mrStCtrl.ReadInt32( nU3 );
2351 mrStCtrl.ReadInt32( nBegin );
2352
2353 switch( nTrigger )
2354 {
2355 case 0: aEvent.Trigger = EventTrigger::NONE; break;
2356 case 1: aEvent.Trigger = EventTrigger::ON_BEGIN; break;
2357 case 2: aEvent.Trigger = EventTrigger::ON_END; break;
2358 case 3: aEvent.Trigger = EventTrigger::BEGIN_EVENT; break;
2359 case 4: aEvent.Trigger = EventTrigger::END_EVENT; break;
2360 case 5: aEvent.Trigger = EventTrigger::ON_CLICK; break;
2361 case 6: aEvent.Trigger = EventTrigger::ON_DBL_CLICK; break;
2362 case 7: aEvent.Trigger = EventTrigger::ON_MOUSE_ENTER; break;
2363 case 8: aEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE; break;
2364 case 9: aEvent.Trigger = EventTrigger::ON_NEXT; break;
2365 case 10: aEvent.Trigger = EventTrigger::ON_PREV; break;
2366 case 11: aEvent.Trigger = EventTrigger::ON_STOP_AUDIO; break;
2367 }
2368
2369 if( (nBegin != 0) || (aEvent.Trigger == EventTrigger::NONE) )
2370 aEvent.Offset = (nBegin == -1) ? Any( Timing_INDEFINITE ) : Any( nBegin / 1000.0 );
2371 }
2372 break;
2374 {
2375 sal_Int16 nSubType;
2376 importTargetElementContainer( pChildAtom, aEvent.Source, nSubType );
2377 }
2378 break;
2379 default:
2380 {
2381 OSL_FAIL("unknown atom inside ppt::AnimationImporter::importAnimationEvents()!");
2382 }
2383 }
2384
2385 pChildAtom = Atom::findNextChildAtom( pChildAtom );
2386 }
2387
2388 *pEvents = oox::addToSequence( *pEvents, (aEvent.Trigger == EventTrigger::NONE) ? aEvent.Offset : Any( aEvent ) );
2389 }
2390
2391 pEventAtom = pAtom->findNextChildAtom( DFF_msofbtAnimEvent, pEventAtom );
2392 }
2393
2394 xNode->setBegin( aBegin );
2395 xNode->setEnd( aEnd );
2396 // TODO: xNode->setNext( aNext );
2397 // TODO: xNode->setPrev( aNext );
2398
2399#ifdef DBG_ANIM_LOG
2400 if( aBegin.hasValue() )
2401 {
2402 dump( " begin=\"" );
2403 dump( aBegin );
2404 dump( "\"" );
2405 }
2406
2407 if( aEnd.hasValue() )
2408 {
2409 dump( " end=\"" );
2410 dump( aEnd );
2411 dump( "\"" );
2412 }
2413
2414 if( aNext.hasValue() )
2415 {
2416 dump( " next=\"" );
2417 dump( aNext );
2418 dump( "\"" );
2419 }
2420
2421 if( aPrev.hasValue() )
2422 {
2423 dump( " prev=\"" );
2424 dump( aPrev );
2425 dump( "\"" );
2426 }
2427#endif
2428}
2429
2430void AnimationImporter::importAnimationActions( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2431{
2432 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationActions()!");
2433
2434 if( !pAtom )
2435 return;
2436
2437 const Atom* pActionAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAction );
2438
2439 if( !(pActionAtom && pActionAtom->seekToContent()) )
2440 return;
2441
2442 sal_Int32 nConcurrent(0), nNextAction(0), nEndSync(0), nU4(0), nU5(0);
2443 mrStCtrl.ReadInt32( nConcurrent );
2444 mrStCtrl.ReadInt32( nNextAction );
2445 mrStCtrl.ReadInt32( nEndSync );
2446 mrStCtrl.ReadInt32( nU4 );
2447 mrStCtrl.ReadInt32( nU5 );
2448
2449 if( nEndSync == 1 )
2450 xNode->setEndSync( Any( AnimationEndSync::ALL ) );
2451
2452#ifdef DBG_ANIM_LOG
2453 dump( " concurrent=\"%s\"", nConcurrent == 0 ? "disabled" : (nConcurrent == 1 ? "enabled" : "unknown") );
2454
2455 dump( " nextAction=\"%s\"", nNextAction == 0 ? "none" : (nNextAction == 1 ? "seek" : "unknown") );
2456
2457 if( nEndSync != 0 )
2458 {
2459 dump( " endSync=\"%s\"", nEndSync == 1 ? "all" : "unknown" );
2460 }
2461
2462 dump( " action_4=\"%#lx\"", nU4 );
2463 dump( " action_5=\"%#lx\"", nU5 );
2464#endif
2465}
2466
2467void AnimationImporter::importTargetElementContainer( const Atom* pAtom, Any& rTarget, sal_Int16& rSubType )
2468{
2469 rSubType = ShapeAnimationSubType::AS_WHOLE;
2470 sal_Int32 nRefMode = -1;
2471
2472 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateTargetElement), "invalid call to ppt::AnimationImporter::importTargetElementContainer()!" );
2473 if( !pAtom )
2474 return;
2475
2476 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2477 while( pChildAtom && pChildAtom->seekToContent() )
2478 {
2479 switch( pChildAtom->getType() )
2480 {
2482 {
2483 sal_Int32 nRefType(0), nRefId(0);
2484 sal_Int32 begin(0), end(0);
2485 mrStCtrl.ReadInt32( nRefMode );
2486 mrStCtrl.ReadInt32( nRefType );
2487 mrStCtrl.ReadInt32( nRefId );
2490
2491 switch( nRefType )
2492 {
2493 case 1: // shape
2494 {
2495 SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId );
2496 if( pSdrObject == nullptr )
2497 break;
2498
2499 rTarget <<= pSdrObject->getUnoShape();
2500
2501 switch( nRefMode )
2502 {
2503 case 6: rSubType = ShapeAnimationSubType::ONLY_BACKGROUND; break;
2504 case 8: rSubType = ShapeAnimationSubType::ONLY_TEXT; break;
2505 case 2: // one paragraph
2506 {
2507 if((begin == -1) && (end == -1))
2508 break;
2509
2510 SdrTextObj* pTextObj = DynCastSdrTextObj( pSdrObject );
2511 if(!pTextObj)
2512 break;
2513
2514 const OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject();
2515 if( pOPO == nullptr )
2516 break;
2517
2518 const EditTextObject& rEditTextObject = pOPO->GetTextObject();
2519
2520 const sal_Int32 nParaCount = rEditTextObject.GetParagraphCount();
2521
2522 sal_Int32 nPara = 0;
2523
2524 while( (nPara < nParaCount) && (begin > 0) )
2525 {
2526 sal_Int32 nParaLength = rEditTextObject.GetText( nPara ).getLength() + 1;
2527 begin -= nParaLength;
2528 end -= nParaLength;
2529 nPara++;
2530 }
2531
2532 if( nPara < nParaCount )
2533 {
2534 ParagraphTarget aParaTarget;
2535 rTarget >>= aParaTarget.Shape;
2536 /* FIXME: Paragraph should be sal_Int32 as well */
2537 aParaTarget.Paragraph = static_cast<sal_Int16>(nPara);
2538 rTarget <<= aParaTarget;
2539
2540 rSubType = ShapeAnimationSubType::ONLY_TEXT;
2541 dump( " paragraph %d,", nPara);
2542 dump( " %d characters", end );
2543 }
2544 }
2545 }
2546 }
2547 break;
2548
2549 case 2: // sound
2550 {
2551 OUString aSoundURL( mpPPTImport->ReadSound( nRefId ) );
2552 rTarget <<= aSoundURL;
2553 dump( " srcRef=\"%s\"", aSoundURL );
2554 }
2555 break;
2556 case 3: // audio object
2557 case 4: // video object
2558 {
2559 SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId );
2560 if( pSdrObject == nullptr )
2561 break;
2562
2563 rTarget <<= pSdrObject->getUnoShape();
2564 }
2565 break;
2566 default:
2567 OSL_FAIL("unknown reference type");
2568 }
2569
2570 }
2571 break;
2572 case 0x2b01:
2573 {
2574 sal_Int32 nU1;
2575 mrStCtrl.ReadInt32( nU1 );
2576 }
2577 break;
2578 default:
2579 OSL_FAIL("unknown atom inside ppt::AnimationImporter::importTargetElementContainer()!");
2580 break;
2581 }
2582
2583 pChildAtom = Atom::findNextChildAtom( pChildAtom );
2584
2585 }
2586}
2587
2589{
2590 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimPropertySet), "invalid call to ppt::AnimationImporter::importPropertySetContainer()!" );
2591
2592 if( !pAtom )
2593 return;
2594
2595 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2596 while( pChildAtom )
2597 {
2598 if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue )
2599 {
2600 Any aAny;
2601 (void)importAttributeValue( pChildAtom, aAny );
2602 rSet.maProperties[ pChildAtom->getInstance() ] = aAny;
2603 }
2604 else
2605 {
2606 OSL_FAIL("unknown atom inside ppt::AnimationImporter::importPropertySetContainer()!");
2607 }
2608
2609 pChildAtom = Atom::findNextChildAtom( pChildAtom );
2610 }
2611}
2612
2613#ifdef DBG_ANIM_LOG
2614void AnimationImporter::dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend )
2615{
2616 if( pAtom )
2617 {
2618 const char* pTitle;
2619
2620 switch( pAtom->getType() )
2621 {
2622 case DFF_msofbtAnimEvent: pTitle = "AnimEvent"; break;
2623 case DFF_msofbtAnimTrigger: pTitle = "AnimTrigger"; break;
2624 case DFF_msofbtAnimateMotion: pTitle = "AnimateMotion"; break;
2625 case DFF_msofbtAnimPropertySet: pTitle = "AnimPropertySet"; break;
2626 case DFF_msofbtAnimateAttributeNames: pTitle = "AnimAttributeName"; break;
2627 case DFF_msofbtAnimAttributeValue: pTitle = "AnimAttributeValue"; break;
2628 case DFF_msofbtAnimGroup: pTitle = "AnimGroup"; break;
2629 case DFF_msofbtAnimNode: pTitle = "AnimNode"; break;
2630 case DFF_msofbtAnimValue: pTitle = "AnimValue"; break;
2631 case DFF_msofbtAnimateFilter: pTitle = "animateFilter"; break;
2632 case DFF_msofbtAnimate: pTitle = "animate"; break;
2633 case DFF_msofbtAnimateSet: pTitle = "set"; break;
2634 case DFF_msofbtAnimKeyTime: pTitle = "AnimKeyTime"; break;
2635 case DFF_msofbtAnimKeyPoints: pTitle = "AnimKeyPoints"; break;
2636 case DFF_msofbtAnimReference: pTitle = "AnimReference"; break;
2637 case DFF_msofbtAnimateTargetElement: pTitle = "AnimTargetElementContainer"; break;
2638 case DFF_msofbtAnimAction: pTitle = "AnimAction"; break;
2639 case DFF_msofbtAnimCommand: pTitle = "AnimCommand"; break;
2640 case DFF_msofbtAnimateTarget: pTitle = "TransformationTarget"; break;
2641 case DFF_msofbtAnimateTargetSettings: pTitle = "TransformationTargetSettings"; break;
2642 case DFF_msofbtAnimIteration: pTitle = "iterate"; break;
2643 case DFF_msofbtAnimateColorData: pTitle = "colorData"; break;
2644 case DFF_msofbtAnimateScaleData: pTitle = "scaleData"; break;
2645 case DFF_msofbtAnimateSetData: pTitle = "setData"; break;
2646
2647 default:
2648 {
2649 static char buffer[128];
2650 sprintf( buffer, "unknown_%#x", pAtom->getType() );
2651 pTitle = buffer;
2652 }
2653 }
2654
2655 if( bOpen )
2656 {
2657 fprintf(mpFile, "<%s", pTitle );
2658
2659 fprintf(mpFile, " instance=\"%hu\"%s",
2660 pAtom->getInstance(),
2661 bAppend ? "" : ">\n");
2662 }
2663 else
2664 {
2665 if( bAppend )
2666 fprintf(mpFile,"/>\n");
2667 else
2668 fprintf(mpFile, "</%s>\n", pTitle );
2669 }
2670 }
2671}
2672
2673void AnimationImporter::dump( sal_uInt32 nLen, bool bNewLine )
2674{
2675 char * faul = "0123456789abcdef";
2676
2677 sal_uInt32 i = 0;
2678 int b = 0;
2679 char nData;
2680
2681 for( i = 0; i < nLen; i++ )
2682 {
2683 mrStCtrl.ReadChar(nData);
2684
2685 fprintf( mpFile, "%c%c ", faul[ (nData >> 4) & 0x0f ], faul[ nData & 0x0f ] );
2686
2687 b++;
2688 if( bNewLine && (b == 32) )
2689 {
2690 fprintf(mpFile,"\n");
2691 b = 0;
2692 }
2693 }
2694 if( (b != 0) && bNewLine )
2695 fprintf(mpFile,"\n");
2696}
2697
2698void AnimationImporter::dump_atom( const Atom* pAtom, bool bNewLine )
2699{
2700 if( pAtom )
2701 {
2702 if( pAtom->isContainer() )
2703 {
2704 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2705 while( pChildAtom )
2706 {
2707 if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue )
2708 {
2709 fprintf(mpFile, "<attributeValue instance=\"%hu\"", pChildAtom->getInstance() );
2710
2711 Any aValue;
2712 if( importAttributeValue( pChildAtom, aValue ) )
2713 {
2714 sal_Int32 nInt;
2715 OUString aString;
2716 double fDouble;
2717
2718 if( aValue >>= nInt )
2719 {
2720 fprintf(mpFile, " value=\"%" SAL_PRIdINT32 "\"", nInt );
2721 }
2722 else if( aValue >>= aString )
2723 {
2724 fprintf(mpFile, " value=\"%s\"",
2725 OUStringToOString(aString,
2726 RTL_TEXTENCODING_UTF8).getStr());
2727 }
2728 else if( aValue >>= fDouble )
2729 {
2730 fprintf(mpFile, " value=\"%g\"", fDouble );
2731 }
2732 }
2733 else
2734 {
2735 if( pChildAtom->seekToContent() )
2736 {
2737 fprintf(mpFile, " value=\"" );
2738 dump_atom( pChildAtom, false );
2739 fprintf(mpFile, "\"");
2740 }
2741 }
2742
2743 fprintf(mpFile, "/>\n" );
2744 }
2745 else
2746 {
2747 dump_atom_header( pChildAtom, true, pChildAtom->getType() == DFF_msofbtAnimAttributeValue );
2748 dump_atom( pChildAtom );
2749 dump_atom_header( pChildAtom, false, pChildAtom->getType() == DFF_msofbtAnimAttributeValue );
2750 }
2751
2752 pChildAtom = Atom::findNextChildAtom(pChildAtom);
2753 }
2754 }
2755 else if( pAtom->seekToContent() )
2756 {
2757 dump( pAtom->getLength(), bNewLine );
2758 }
2759 }
2760}
2761
2762void AnimationImporter::dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen )
2763{
2764 fprintf( mpFile, bOpen ? "<" : "</" );
2765
2766 switch( rNode.mnGroupType )
2767 {
2769 fprintf( mpFile, "par" );
2770 break;
2772 fprintf( mpFile, "seq" );
2773 break;
2775 switch( rNode.mnNodeType )
2776 {
2778 fprintf( mpFile, "animateFilter" );
2779 break;
2781 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
2782 fprintf( mpFile, "set" );
2783 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
2784 fprintf( mpFile, "animateColor" );
2785 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
2786 fprintf( mpFile, "animateScale" );
2787 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
2788 fprintf( mpFile, "animateRotation" );
2789 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
2790 fprintf( mpFile, "animateMotion" );
2791 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
2792 fprintf( mpFile, "command" );
2793 else
2794 fprintf( mpFile, "animation" );
2795 break;
2796 default:
2797 {
2798 fprintf( mpFile, "unknown_node_%#lx", rNode.mnNodeType );
2799 }
2800 break;
2801 }
2802 break;
2804 fprintf( mpFile, "media" );
2805 break;
2806 default:
2807 fprintf( mpFile, "unknown_group_%#lx", rNode.mnGroupType );
2808 break;
2809 }
2810
2811 if( bOpen )
2812 {
2813 dump( rNode );
2814 dump( rSet );
2815 }
2816
2817 fprintf(mpFile,">\n");
2818}
2819
2820void AnimationImporter::dump( const AnimationNode& rNode )
2821{
2822 // dump animation node
2823 if( rNode.mnRestart != 0 )
2824 {
2825 fprintf(mpFile," restart=\"%s\"",
2826 rNode.mnRestart == 1 ? "always" : (rNode.mnRestart == 2 ? "whenOff" : (rNode.mnRestart == 3 ? "never" : "unknown")) );
2827 }
2828
2829 if( rNode.mnFill )
2830 {
2831 fprintf(mpFile," fill=\"%s\"",
2832 rNode.mnFill == 1 ? "remove" : (rNode.mnFill == 3 ? "hold" : (rNode.mnFill == 2 ? "freeze" : "unknown")) );
2833 }
2834
2835 if( rNode.mnDuration > 0 )
2836 {
2837 double fSeconds = rNode.mnDuration;
2838 fSeconds /= 1000.0;
2839 fprintf(mpFile, " dur=\"%g\"", fSeconds);
2840 }
2841 else if( rNode.mnDuration < 0 )
2842 {
2843 fprintf(mpFile, " dur=\"indefinite\"" );
2844 }
2845
2846 if( rNode.mnU1 ) fprintf(mpFile," u1=\"%#lx\"", rNode.mnU1);
2847 if( rNode.mnU3 ) fprintf(mpFile," u3=\"%#lx\"", rNode.mnU3);
2848 if( rNode.mnU4 ) fprintf(mpFile," u4=\"%#lx\"", rNode.mnU4);
2849}
2850
2851void AnimationImporter::dump( Any& rAny )
2852{
2853 Sequence< Any > aSeq;
2854 sal_Int32 nInt;
2855 double fDouble;
2856 OUString aString;
2857 sal_Bool bBool;
2858 Event aEvent;
2859 Timing aTiming;
2860
2861 if( rAny >>= aSeq )
2862 {
2863 const sal_Int32 nSize = aSeq.getLength();
2864 sal_Int32 nIndex = 0;
2865 while( nIndex < nSize )
2866 {
2867 dump( aSeq[nIndex++] );
2868 if(nIndex < nSize)
2869 fprintf( mpFile, "," );
2870 }
2871 }
2872 else if( rAny >>= aString )
2873 {
2874 fprintf( mpFile, "%s", OUStringToOString(aString,
2875 RTL_TEXTENCODING_UTF8).getStr() );
2876 }
2877 else if( rAny >>= nInt )
2878 {
2879 fprintf( mpFile, "%" SAL_PRIdINT32, nInt );
2880 }
2881 else if( rAny >>= bBool )
2882 {
2883 fprintf( mpFile, "%s", bBool ? "true" : "false" );
2884 }
2885 else if( rAny >>= fDouble )
2886 {
2887 fprintf( mpFile, "%g", fDouble );
2888 }
2889 else if( rAny >>= aTiming )
2890 {
2891 fprintf( mpFile, "%s", aTiming == (Timing_INDEFINITE) ? "indefinite" : "media" );
2892 }
2893 else if( rAny >>= aEvent )
2894 {
2895 if( aEvent.Trigger != EventTrigger::NONE )
2896 {
2897 static const char* triggers[] =
2898 {
2899 "none","onbegin","onend","begin",
2900 "end","onclick","ondoubleclick","onmouseenter",
2901 "onmouseleave","onpptnext","onpptprev","onstopaudio"
2902 };
2903
2904 if( aEvent.Source.hasValue() )
2905 {
2906 dump_target( aEvent.Source );
2907 dump( "." );
2908 }
2909
2910 dump( triggers[ aEvent.Trigger ] );
2911 }
2912
2913 if( aEvent.Offset.hasValue() )
2914 {
2915 double fOffset;
2916 if( aEvent.Offset >>= fOffset )
2917 fprintf( mpFile, "%g", fOffset );
2918 else
2919 dump( "indefinite" );
2920 }
2921 }
2922}
2923
2924void AnimationImporter::dump( const PropertySet& rSet )
2925{
2926 // dump property set
2927
2928 for( const auto& rProp : rSet.maProperties )
2929 {
2930 bool bKnown = false;
2931
2932 const sal_Int32 nInstance = rProp.first;
2933 Any aAny( rProp.second );
2934
2935 switch ( nInstance )
2936 {
2938 {
2939 sal_Int32 nColorSpace;
2940 if( aAny >>= nColorSpace )
2941 {
2942 fprintf( mpFile, " colorSpace=\"%s\"", (nColorSpace == 0) ? "rgb" : (nColorSpace == 1) ? "hsl" : "unknown" );
2943 bKnown = true;
2944 }
2945 }
2946 break;
2947
2948 case DFF_ANIM_DIRECTION:
2949 {
2950 sal_Bool bDirection;
2951 if( aAny >>= bDirection )
2952 {
2953 fprintf( mpFile, " direction=\"%s\"", bDirection ? "cclockwise" : "clockwise" );
2954 bKnown = true;
2955 }
2956 else
2957 {
2958 sal_Int32 nMasterRel;
2959 if( aAny >>= nMasterRel )
2960 {
2961 fprintf( mpFile, " direction=\"%s\"", nMasterRel == 0 ? "sameClick" : ( nMasterRel == 2 ? "nextClick" : "lastClick" ) );
2962 bKnown = true;
2963 }
2964 }
2965 }
2966 break;
2967
2968 case DFF_ANIM_OVERRIDE: // TODO
2969 {
2970 sal_Int32 nOverride;
2971 if( aAny >>= nOverride )
2972 {
2973 fprintf( mpFile, " override=\"%s\"", (nOverride == 1) ? "childStyle" : (nOverride == 0) ? "normal" : "unknown" );
2974 bKnown = true;
2975 }
2976 }
2977 break;
2978
2980 {
2981 sal_Bool bPathEditMode;
2982 if( aAny >>= bPathEditMode )
2983 {
2984 fprintf( mpFile, " pptPathEditMode=\"%s\"", bPathEditMode ? "relative" : "fixed" );
2985 bKnown = true;
2986 }
2987 }
2988 break;
2989
2990 case DFF_ANIM_PRESET_ID :
2991 {
2992 sal_Int32 nPresetId ;
2993 if( aAny >>= nPresetId )
2994 {
2995 fprintf(mpFile, " presetid=\"%" SAL_PRIdINT32 "\"", nPresetId );
2996 bKnown = true;
2997 }
2998 }
2999 break;
3000
3002 {
3003 sal_Int32 nPointsType ;
3004 if( aAny >>= nPointsType )
3005 {
3006 fprintf(mpFile, " presetSubType=\"%" SAL_PRIdINT32 "\"", nPointsType );
3007 bKnown = true;
3008 }
3009 }
3010 break;
3011
3013 {
3014 sal_Int32 nPresetClass;
3015 if ( aAny >>= nPresetClass )
3016 {
3017 const char* pMode;
3018 switch( nPresetClass )
3019 {
3020 case DFF_ANIM_PRESS_CLASS_USER_DEFINED: pMode = "userdefined"; break;
3021 case DFF_ANIM_PRESS_CLASS_ENTRANCE: pMode = "entrance"; break;
3022 case DFF_ANIM_PRESS_CLASS_EXIT: pMode = "exit"; break;
3023 case DFF_ANIM_PRESS_CLASS_EMPHASIS: pMode = "emphasis"; break;
3024 case DFF_ANIM_PRESS_CLASS_MOTIONPATH: pMode = "motionpath"; break;
3025 case DFF_ANIM_PRESS_CLASS_OLE_ACTION: pMode = "oleaction"; break;
3026 case DFF_ANIM_PRESS_CLASS_MEDIACALL: pMode = "mediacall"; break;
3027 default:
3028 pMode = nullptr;
3029 break;
3030 }
3031
3032 if (pMode)
3033 fprintf(mpFile, " class=\"%s\"", pMode);
3034 else
3035 fprintf(mpFile, " class =\"%" SAL_PRIdINT32 "\"", nPresetClass);
3036 bKnown = true;
3037 }
3038 }
3039 break;
3040
3041 case DFF_ANIM_NODE_TYPE :
3042 {
3043 sal_Int32 nNodeType;
3044 if ( aAny >>= nNodeType )
3045 {
3046 const char* pNode;
3047 switch( nNodeType )
3048 {
3049 case DFF_ANIM_NODE_TYPE_ON_CLICK: pNode = "onclick"; break;
3050 case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: pNode = "withprevious"; break;
3051 case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: pNode = "afterprevious"; break;
3052 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: pNode = "mainsequence"; break;
3053 case DFF_ANIM_NODE_TYPE_TIMING_ROOT: pNode = "timingroot"; break;
3054 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:pNode = "interactivesequence"; break;
3055 default :
3056 {
3057 static char buffer[128];
3058 sprintf( buffer, "%" SAL_PRIdINT32, nNodeType );
3059 pNode = buffer;
3060 }
3061 break;
3062 }
3063
3064 fprintf(mpFile, " nodeType=\"%s\"", pNode);
3065 bKnown = true;
3066 }
3067 }
3068 break;
3069
3070 case DFF_ANIM_GROUP_ID:
3071 {
3072 sal_Int32 nGroupId;
3073 if ( aAny >>= nGroupId )
3074 {
3075 fprintf( mpFile, " groupId=\"%" SAL_PRIdINT32 "\"", nGroupId );
3076 bKnown = true;
3077 }
3078 }
3079 break;
3080
3081 case DFF_ANIM_ID:
3082 {
3083 OUString aString;
3084 if( aAny >>= aString )
3085 {
3086 fprintf( mpFile, " id=\"%s\"",
3087 OUStringToOString(aString,
3088 RTL_TEXTENCODING_UTF8).getStr() );
3089 bKnown = true;
3090 }
3091 }
3092 break;
3093
3095 {
3096 OUString aString;
3097 if( aAny >>= aString )
3098 {
3099 fprintf( mpFile, " eventFilter=\"%s\"",
3100 OUStringToOString(aString,
3101 RTL_TEXTENCODING_UTF8).getStr() );
3102 bKnown = true;
3103 }
3104 }
3105 break;
3106
3108 {
3109 sal_Int32 nEndAfterSlide;
3110 if( aAny >>= nEndAfterSlide )
3111 {
3112 fprintf(mpFile, " endAfterSlide=\"%" SAL_PRIdINT32 "\"", nEndAfterSlide );
3113 bKnown = true;
3114 }
3115 }
3116
3118 {
3119 OUString aString;
3120 if( aAny >>= aString )
3121 {
3122 fprintf( mpFile, " timeFilter=\"%s\"",
3123 OUStringToOString(aString,
3124 RTL_TEXTENCODING_UTF8).getStr() );
3125 bKnown = true;
3126 }
3127 }
3128 break;
3129
3131 {
3132 OUString aString;
3133 if( aAny >>= aString )
3134 {
3135 fprintf( mpFile, " runtimeContext=\"%s\"",
3136 OUStringToOString(aString,
3137 RTL_TEXTENCODING_UTF8).getStr() );
3138 bKnown = true;
3139 }
3140 }
3141 break;
3142
3143 case DFF_ANIM_VOLUME:
3144 {
3145 double fVolume(0.0);
3146 if( aAny >>= fVolume )
3147 {
3148 fprintf( mpFile, " volume=\"%g%%\"", (double)(fVolume * 100.0) );
3149 bKnown = true;
3150 }
3151 }
3152 break;
3153
3155 {
3156 sal_Bool bAfterEffect;
3157 if( aAny >>= bAfterEffect )
3158 {
3159 fprintf( mpFile, "afterEffect=\"%s\"", bAfterEffect ? "true" : "false" );
3160 bKnown = true;
3161 }
3162 }
3163 break;
3164
3165 }
3166
3167 if( !bKnown )
3168 {
3169 fprintf( mpFile, " unknown_%" SAL_PRIdINT32 "=\"", nInstance );
3170 dump( aAny );
3171 fprintf( mpFile, "\"" );
3172 }
3173 }
3174}
3175
3176void AnimationImporter::dump_target( Any& rAny )
3177{
3178 Any aSource, aSourceData;
3179 Sequence< Any > aSeq;
3180 if( rAny >>= aSeq )
3181 {
3182 if( aSeq.getLength() >= 1 ) aSource = aSeq[0];
3183 if( aSeq.getLength() >= 2 ) aSourceData = aSeq[1];
3184 }
3185 else
3186 {
3187 aSource = rAny;
3188 }
3189
3190 Reference< XShape > xShape;
3191 aSource >>= xShape;
3192 if( xShape.is() )
3193 {
3194 OUString aStr( xShape->getShapeType() );
3195 dump( aStr );
3196
3197 if( aSourceData.hasValue() )
3198 {
3199 dump( "(" );
3200 dump( aSourceData );
3201 dump( ")" );
3202 }
3203 }
3204}
3205
3206void AnimationImporter::dump( const char * pText )
3207{
3208 fprintf( mpFile, "%s", pText );
3209}
3210
3211void AnimationImporter::dump( const OUString& rString )
3212{
3213 fprintf( mpFile, OUStringToOString(rString,
3214 RTL_TEXTENCODING_UTF8).getStr() );
3215}
3216
3217void AnimationImporter::dump( const char * pText, sal_Int64 nInt )
3218{
3219 fprintf( mpFile, pText, nInt );
3220}
3221
3222void AnimationImporter::dump( const char * pText, sal_Int32 nInt )
3223{
3224 fprintf( mpFile, pText, nInt );
3225}
3226
3227void AnimationImporter::dump( const char * pText, double fDouble )
3228{
3229 fprintf( mpFile, pText, fDouble );
3230}
3231
3232void AnimationImporter::dump( const char * pText, const char * pText2 )
3233{
3234 fprintf( mpFile, pText, pText2 );
3235}
3236
3237void AnimationImporter::dump( const char * pText, const OUString& rString )
3238{
3239 fprintf( mpFile, pText, OUStringToOString(rString,
3240 RTL_TEXTENCODING_UTF8).getStr() );
3241}
3242
3243#else
3244
3245void AnimationImporter::dump_atom_header( const Atom* , bool , bool )
3246{
3247}
3248
3250{
3251}
3252
3254{
3255}
3256
3257void AnimationImporter::dump( css::uno::Any& )
3258{
3259}
3260
3262{
3263}
3264
3266{
3267}
3268
3269void AnimationImporter::dump( const char * )
3270{
3271}
3272
3273void AnimationImporter::dump( const char * , sal_Int32 )
3274{
3275}
3276
3277void AnimationImporter::dump( const char * , double )
3278{
3279}
3280
3281void AnimationImporter::dump( const char * , const char * )
3282{
3283}
3284
3285void AnimationImporter::dump( const char * , std::u16string_view )
3286{
3287}
3288
3289#endif
3290
3291} // namespace ppt;
3292
3293/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
AnyEventRef aEvent
Color GetRGBColor() const
sal_uInt8 GetBlue() const
sal_uInt8 GetRed() const
sal_uInt8 GetGreen() const
virtual sal_Int32 GetParagraphCount() const=0
virtual OUString GetText(sal_Int32 nPara) const=0
OUString ReadSound(sal_uInt32 nSoundRef) const
Definition: pptin.cxx:1891
const EditTextObject & GetTextObject() const
virtual css::uno::Reference< css::drawing::XShape > getUnoShape()
virtual bool GetColorFromPalette(sal_uInt16 nNum, Color &rColor) const override
virtual OutlinerParaObject * GetOutlinerParaObject() const override
bool good() const
SvStream & ReadFloat(float &rFloat)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
SvStream & ReadChar(char &rChar)
SvStream & ReadInt32(sal_Int32 &rInt32)
SvStream & ReadSChar(signed char &rChar)
SvStream & ReadUChar(unsigned char &rChar)
SdrObject * getShapeForId(sal_Int32 nShapeId)
static OUString MSDFFReadZString(SvStream &rIn, sal_uInt32 nMaxLen, bool bUniCode)
std::vector< sd::AfterEffectNode > maAfterEffectNodes
int importAudioContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
static sal_Int16 implGetColorSpace(sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC)
int importAnimationContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xParent)
void importAttributeNamesContainer(const Atom *pAtom, OUString &rAttributeNames)
static void dump_atom(const Atom *pAtom, bool bNewLine=true)
void importCommandContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
void importAnimateFilterContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
ImplSdPPTImport * mpPPTImport
void importAnimateRotationContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
void importAnimateContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
css::uno::Reference< css::animations::XAnimationNode > mxRootNode
void importAnimateScaleContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
void importAnimateSetContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
static void dump(css::uno::Any &rAny)
void importAnimationValues(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
static css::uno::Reference< css::animations::XAnimationNode > createNode(const Atom *pAtom, const AnimationNode &rNode)
int import(const css::uno::Reference< css::drawing::XDrawPage > &xPage, const DffRecordHeader &rProgTagContentHd)
int importAnimationNodeContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
css::uno::Any implGetColorAny(sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC)
void importAnimateMotionContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
void importAnimateColorContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
bool convertAnimationNode(const css::uno::Reference< css::animations::XAnimationNode > &xNode, const css::uno::Reference< css::animations::XAnimationNode > &xParent)
static void dump_atom_header(const Atom *pAtom, bool bOpen, bool bAppend)
bool importAttributeValue(const Atom *pAtom, css::uno::Any &rAny)
void importAnimateKeyPoints(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
void importPropertySetContainer(const Atom *pAtom, PropertySet &rSet)
int importTimeContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
static void dump_target(css::uno::Any &rAny)
static void fillNode(css::uno::Reference< css::animations::XAnimationNode > const &xTiming, const AnimationNode &rNode, const PropertySet &rSet)
void importTargetElementContainer(const Atom *pAtom, css::uno::Any &rTarget, sal_Int16 &nSubType)
void importAnimateAttributeTargetContainer(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
void importAnimationEvents(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
AnimationImporter(ImplSdPPTImport *pPPTImport, SvStream &rStCtrl)
void importAnimationActions(const Atom *pAtom, const css::uno::Reference< css::animations::XAnimationNode > &xNode)
const Atom * findFirstChildAtom(sal_uInt16 nRecType) const
Definition: pptatom.hxx:78
bool seekToContent() const
seeks to the contents of this atom
Definition: pptatom.hxx:92
sal_uInt16 getType() const
Definition: pptatom.hxx:98
bool hasChildAtom(sal_uInt16 nRecType) const
Definition: pptatom.hxx:73
sal_uInt16 getInstance() const
Definition: pptatom.hxx:100
sal_uInt32 getLength() const
Definition: pptatom.hxx:102
static Atom * import(const DffRecordHeader &rRootRecordHeader, SvStream &rStCtrl)
imports this atom and its child atoms
Definition: pptatom.cxx:77
bool isContainer() const
Definition: pptatom.hxx:90
const Atom * findNextChildAtom(sal_uInt16 nRecType, const Atom *pLast) const
returns the next child atom after pLast with nRecType or NULL
Definition: pptatom.cxx:93
bool hasProperty(sal_Int32 nProperty) const
PropertySetMap_t maProperties
css::uno::Any getProperty(sal_Int32 nProperty) const
sal_Int32 nElements
#define DBG_ASSERT(sCon, aError)
float u
FilterGroup & rTarget
sal_Int32 nIndex
OUString aName
void * p
sal_Int64 n
uno_Any a
Environment aTo
sal_uInt16 nPos
Sequence< sal_Int8 > aSeq
#define SAL_WARN(area, stream)
aStr
int i
int sprintf(char(&s)[N], char const *format, T &&... arguments)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
double toDouble(std::u16string_view str)
enumrange< T >::Iterator begin(enumrange< T >)
bool convertMeasure(OUString &rString)
const ImplAttributeNameConversion * getAttributeConversionList()
void fixMainSequenceTiming(const css::uno::Reference< css::animations::XAnimationNode > &xNode)
bool convertAnimationValue(AnimationAttributeEnum eAttribute, css::uno::Any &rValue)
void fixInteractiveSequenceTiming(const css::uno::Reference< css::animations::XAnimationNode > &xNode)
OUString getConvertedSubType(sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType)
AnimationAttributeEnum
Any addToSequence(const Any &rOldValue, const Any &rNewValue)
end
const sal_Int32 mso_Anim_GroupType_MEDIA
const sal_Int32 mso_Anim_Behaviour_ANIMATION
static SvStream & operator>>(SvStream &rIn, AnimationNode &rNode)
const sal_Int32 mso_Anim_GroupType_PAR
const sal_Int32 mso_Anim_GroupType_SEQ
const sal_Int32 mso_Anim_Behaviour_FILTER
static bool is_random(const AnimationNode &rNode, const PropertySet &rSet, sal_Int32 &rPresetClass)
const sal_Int32 mso_Anim_GroupType_NODE
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
void stl_process_after_effect_node_func(AfterEffectNode const &rNode)
inserts the animation node in the given AfterEffectNode at the correct position in the timing hierarc...
Reference< XInterface > RandomAnimationNode_createInstance(sal_Int16 nPresetClass)
Definition: randomnode.cxx:155
#define DFF_ANIM_RUNTIMECONTEXT
#define DFF_ANIM_PRESS_CLASS_OLE_ACTION
#define DFF_msofbtAnimateRotationData
#define DFF_msofbtAnimAction
#define DFF_msofbtAnimateMotionData
#define DFF_ANIM_GROUP_ID
#define DFF_msofbtAnimateTargetSettings
#define DFF_msofbtAnimPropertySet
#define DFF_msofbtAnimCommand
#define DFF_ANIM_NODE_TYPE_WITH_GROUP
#define DFF_msofbtAnimateFilterData
#define DFF_msofbtAnimateSetData
#define DFF_msofbtAnimValue
#define DFF_ANIM_DIRECTION
#define DFF_msofbtAnimKeyPoints
#define DFF_msofbtAnimSubGoup
#define DFF_ANIM_PRESS_CLASS_USER_DEFINED
#define DFF_ANIM_NODE_TYPE_ON_CLICK
#define DFF_ANIM_EVENT_FILTER
#define DFF_msofbtAnimateTarget
#define DFF_ANIM_PRESET_SUB_TYPE
#define DFF_ANIM_NODE_TYPE
#define DFF_ANIM_NODE_TYPE_CLICK_PARALLEL
#define DFF_ANIM_NODE_TYPE_AFTER_GROUP
#define DFF_ANIM_PATH_EDIT_MODE
#define DFF_ANIM_AFTEREFFECT
#define DFF_msofbtAnimReference
#define DFF_msofbtAnimGroup
#define DFF_msofbtAnimateAttributeNames
#define DFF_msofbtAnimateTargetElement
#define DFF_msofbtAnimIteration
#define DFF_ANIM_TIMEFILTER
#define DFF_ANIM_NODE_TYPE_WITH_PREVIOUS
#define DFF_ANIM_OVERRIDE
#define DFF_msofbtAnimKeyTime
#define DFF_ANIM_PRESET_CLASS
#define DFF_ANIM_MASTERREL
#define DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ
#define DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS
#define DFF_msofbtAnimTrigger
#define DFF_msofbtAnimAttributeValue
#define DFF_ANIM_PRESS_CLASS_EXIT
#define DFF_msofbtAnimNode
#define DFF_ANIM_PRESS_CLASS_EMPHASIS
#define DFF_ANIM_PROP_TYPE_UNISTRING
#define DFF_msofbtAnimateData
#define DFF_ANIM_NODE_TYPE_TIMING_ROOT
#define DFF_msofbtAnimateScale
#define DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE
#define DFF_msofbtAnimEvent
#define DFF_msofbtAnimateScaleData
#define DFF_ANIM_VOLUME
#define DFF_msofbtAnimateSet
#define DFF_ANIM_PRESET_ID
#define DFF_msofbtAnimateRotation
#define DFF_ANIM_PROP_TYPE_BYTE
#define DFF_ANIM_PRESS_CLASS_MOTIONPATH
#define DFF_ANIM_PROP_TYPE_INT32
#define DFF_ANIM_ID
#define DFF_ANIM_PRESS_CLASS_ENTRANCE
#define DFF_ANIM_ENDAFTERSLIDE
#define DFF_msofbtAnimateMotion
#define DFF_ANIM_COLORSPACE
#define DFF_ANIM_PROP_TYPE_FLOAT
#define DFF_msofbtAnimateFilter
#define DFF_msofbtCommandData
#define DFF_ANIM_PRESS_CLASS_MEDIACALL
#define DFF_msofbtAnimate
#define DFF_msofbtAnimateColorData
#define DFF_msofbtAnimateColor
QPRO_FUNC_TYPE nType
static SfxItemSet & rSet
static const preset_mapping * getList()
static const transition * find(std::u16string_view rName)
this atom is the first entry in each animation group
sal_Int32 mnNodeType
see mso_Anim_Behaviour_?
sal_Int32 mnFill
see mso_Anim_Fill_?
sal_Int32 mnGroupType
see mso_Anim_GroupType_?
sal_Int32 mnRestart
see mso_Anim_Restart_?
sal_Int32 mnDuration
duration of this group in 1000th seconds
stores the link between an after effect node and its master for later insertion into the timing hiera...
Definition: animations.hxx:36
SVXCORE_DLLPUBLIC SdrTextObj * DynCastSdrTextObj(SdrObject *)
unsigned char sal_uInt8
unsigned char sal_Bool
signed char sal_Int8