Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : // must be first
22 : : #include <canvas/debug.hxx>
23 : : #include <canvas/verbosetrace.hxx>
24 : :
25 : : #include <com/sun/star/drawing/XShape.hpp>
26 : : #include <com/sun/star/animations/XAnimate.hpp>
27 : : #include <com/sun/star/animations/AnimationNodeType.hpp>
28 : : #include <com/sun/star/presentation/EffectNodeType.hpp>
29 : : #include <com/sun/star/presentation/TextAnimationType.hpp>
30 : : #include <com/sun/star/animations/XAnimateSet.hpp>
31 : : #include <com/sun/star/animations/XIterateContainer.hpp>
32 : : #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
33 : : #include <com/sun/star/animations/XAnimateMotion.hpp>
34 : : #include <com/sun/star/animations/XAnimateColor.hpp>
35 : : #include <com/sun/star/animations/XAnimateTransform.hpp>
36 : : #include <com/sun/star/animations/AnimationTransformType.hpp>
37 : : #include <com/sun/star/animations/XTransitionFilter.hpp>
38 : : #include <com/sun/star/animations/XAudio.hpp>
39 : : #include <com/sun/star/presentation/ParagraphTarget.hpp>
40 : : #include <com/sun/star/beans/XPropertySet.hpp>
41 : : #include <animations/animationnodehelper.hxx>
42 : : #include <basegfx/numeric/ftools.hxx>
43 : :
44 : : #include "animationnodefactory.hxx"
45 : : #include "paralleltimecontainer.hxx"
46 : : #include "sequentialtimecontainer.hxx"
47 : : #include "propertyanimationnode.hxx"
48 : : #include "animationsetnode.hxx"
49 : : #include "animationpathmotionnode.hxx"
50 : : #include "animationcolornode.hxx"
51 : : #include "animationtransformnode.hxx"
52 : : #include "animationtransitionfilternode.hxx"
53 : : #include "animationaudionode.hxx"
54 : : #include "animationcommandnode.hxx"
55 : : #include "nodetools.hxx"
56 : : #include "tools.hxx"
57 : :
58 : : #include <boost/shared_ptr.hpp>
59 : :
60 : : using namespace ::com::sun::star;
61 : :
62 : : namespace slideshow {
63 : : namespace internal {
64 : :
65 : : namespace {
66 : :
67 : : // forward declaration needed by NodeCreator
68 : : BaseNodeSharedPtr implCreateAnimationNode(
69 : : const uno::Reference< animations::XAnimationNode >& xNode,
70 : : const BaseContainerNodeSharedPtr& rParent,
71 : : const NodeContext& rContext );
72 : :
73 : : class NodeCreator
74 : : {
75 : : public:
76 : 0 : NodeCreator( BaseContainerNodeSharedPtr& rParent,
77 : : const NodeContext& rContext )
78 : 0 : : mrParent( rParent ), mrContext( rContext ) {}
79 : :
80 : 0 : void operator()(
81 : : const uno::Reference< animations::XAnimationNode >& xChildNode ) const
82 : : {
83 : 0 : createChild( xChildNode, mrContext );
84 : 0 : }
85 : :
86 : : protected:
87 : 0 : void createChild(
88 : : const uno::Reference< animations::XAnimationNode >& xChildNode,
89 : : const NodeContext& rContext ) const
90 : : {
91 : : BaseNodeSharedPtr pChild( implCreateAnimationNode( xChildNode,
92 : : mrParent,
93 : 0 : rContext ) );
94 : :
95 : : OSL_ENSURE( pChild,
96 : : "NodeCreator::operator(): child creation failed" );
97 : :
98 : : // TODO(Q1): This yields circular references, which, it seems, is
99 : : // unavoidable here
100 : 0 : if( pChild )
101 : 0 : mrParent->appendChildNode( pChild );
102 : 0 : }
103 : :
104 : : BaseContainerNodeSharedPtr& mrParent;
105 : : const NodeContext& mrContext;
106 : : };
107 : :
108 : : /** Same as NodeCreator, only that NodeContext's
109 : : SubsetShape is cloned for every child node.
110 : :
111 : : This is used for iterated animation node generation
112 : : */
113 : : class CloningNodeCreator : private NodeCreator
114 : : {
115 : : public:
116 : 0 : CloningNodeCreator( BaseContainerNodeSharedPtr& rParent,
117 : : const NodeContext& rContext )
118 : 0 : : NodeCreator( rParent, rContext ) {}
119 : :
120 : 0 : void operator()(
121 : : const uno::Reference< animations::XAnimationNode >& xChildNode ) const
122 : : {
123 : 0 : NodeContext aContext( mrContext );
124 : :
125 : : // TODO(Q1): There's a catch here. If you clone a
126 : : // subset whose actual subsetting has already been
127 : : // realized (i.e. if enableSubsetShape() has been
128 : : // called already), and the original of your clone
129 : : // goes out of scope, then your subset will be
130 : : // gone (SubsettableShapeManager::revokeSubset() be
131 : : // called). As of now, this behaviour is not
132 : : // triggered here (we either clone, XOR we enable
133 : : // subset initially), but one might consider
134 : : // reworking DrawShape/ShapeSubset to avoid this.
135 : :
136 : : // clone ShapeSubset, since each node needs their
137 : : // own version of the ShapeSubset (otherwise,
138 : : // e.g. activity counting does not work - subset
139 : : // would be removed after first animation node
140 : : // disables it).
141 : : //
142 : : // NOTE: this is only a problem for animation
143 : : // nodes that explicitly call
144 : : // disableSubsetShape(). Independent shape subsets
145 : : // (like those created for ParagraphTargets)
146 : : // solely rely on the ShapeSubset destructor to
147 : : // normalize things, which does the right thing
148 : : // here: the subset is only removed after _the
149 : : // last_ animation node releases the shared ptr.
150 : : aContext.mpMasterShapeSubset.reset(
151 : 0 : new ShapeSubset( *aContext.mpMasterShapeSubset ) );
152 : :
153 : 0 : createChild( xChildNode, aContext );
154 : 0 : }
155 : : };
156 : :
157 : : /** Create animation nodes for text iterations
158 : :
159 : : This method clones the animation nodes below xIterNode
160 : : for every iterated shape entity.
161 : : */
162 : 0 : bool implCreateIteratedNodes(
163 : : const uno::Reference< animations::XIterateContainer >& xIterNode,
164 : : BaseContainerNodeSharedPtr& rParent,
165 : : const NodeContext& rContext )
166 : : {
167 : 0 : ENSURE_OR_THROW( xIterNode.is(),
168 : : "implCreateIteratedNodes(): Invalid node" );
169 : :
170 : 0 : const double nIntervalTimeout( xIterNode->getIterateInterval() );
171 : :
172 : : // valid iterate interval? We're ruling out monstrous
173 : : // values here, to avoid pseudo 'hangs' in the
174 : : // presentation
175 : 0 : if( nIntervalTimeout < 0.0 ||
176 : : nIntervalTimeout > 1000.0 )
177 : : {
178 : 0 : return false; // not an active iteration
179 : : }
180 : :
181 : 0 : if( ::basegfx::fTools::equalZero( nIntervalTimeout ) )
182 : : OSL_TRACE( "implCreateIteratedNodes(): "
183 : : "iterate interval close to zero, there's "
184 : : "no point in defining such an effect "
185 : : "(visually equivalent to whole-shape effect)" );
186 : :
187 : : // Determine target shape (or subset)
188 : : // ==================================
189 : :
190 : : // TODO(E1): I'm not too sure what to expect here...
191 : 0 : ENSURE_OR_RETURN_FALSE(
192 : : xIterNode->getTarget().hasValue(),
193 : : "implCreateIteratedNodes(): no target on ITERATE node" );
194 : :
195 : 0 : uno::Reference< drawing::XShape > xTargetShape( xIterNode->getTarget(),
196 : 0 : uno::UNO_QUERY );
197 : :
198 : 0 : presentation::ParagraphTarget aTarget;
199 : 0 : sal_Int16 nSubItem( xIterNode->getSubItem() );
200 : 0 : bool bParagraphTarget( false );
201 : :
202 : 0 : if( !xTargetShape.is() )
203 : : {
204 : : // no shape provided. Maybe a ParagraphTarget?
205 : 0 : if( !(xIterNode->getTarget() >>= aTarget) )
206 : 0 : ENSURE_OR_RETURN_FALSE(
207 : : false,
208 : : "implCreateIteratedNodes(): could not extract any "
209 : : "target information" );
210 : :
211 : 0 : xTargetShape = aTarget.Shape;
212 : :
213 : 0 : ENSURE_OR_RETURN_FALSE(
214 : : xTargetShape.is(),
215 : : "implCreateIteratedNodes(): invalid shape in ParagraphTarget" );
216 : :
217 : : // we've a paragraph target to iterate over, thus,
218 : : // the whole animation container refers only to
219 : : // the text
220 : 0 : nSubItem = presentation::ShapeAnimationSubType::ONLY_TEXT;
221 : :
222 : 0 : bParagraphTarget = true;
223 : : }
224 : :
225 : : // Lookup shape, and fill NodeContext
226 : : // ==================================
227 : :
228 : : AttributableShapeSharedPtr pTargetShape(
229 : : lookupAttributableShape( rContext.maContext.mpSubsettableShapeManager,
230 : 0 : xTargetShape ) );
231 : :
232 : : const DocTreeNodeSupplier& rTreeNodeSupplier(
233 : 0 : pTargetShape->getTreeNodeSupplier() );
234 : :
235 : 0 : ShapeSubsetSharedPtr pTargetSubset;
236 : :
237 : 0 : NodeContext aContext( rContext );
238 : :
239 : : // paragraph targets already need a subset as the
240 : : // master shape (they're representing only a single
241 : : // paragraph)
242 : 0 : if( bParagraphTarget )
243 : : {
244 : 0 : ENSURE_OR_RETURN_FALSE(
245 : : aTarget.Paragraph >= 0 &&
246 : : rTreeNodeSupplier.getNumberOfTreeNodes(
247 : : DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ) > aTarget.Paragraph,
248 : : "implCreateIteratedNodes(): paragraph index out of range" );
249 : :
250 : : pTargetSubset.reset(
251 : : new ShapeSubset(
252 : : pTargetShape,
253 : : // retrieve index aTarget.Paragraph of
254 : : // type PARAGRAPH from this shape
255 : : rTreeNodeSupplier.getTreeNode(
256 : : aTarget.Paragraph,
257 : 0 : DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ),
258 : 0 : rContext.maContext.mpSubsettableShapeManager ) );
259 : :
260 : : // iterate target is not the whole shape, but only
261 : : // the selected paragraph - subset _must_ be
262 : : // independent, to be able to affect visibility
263 : : // independent of master shape
264 : 0 : aContext.mbIsIndependentSubset = true;
265 : :
266 : : // already enable parent subset right here, to
267 : : // make potentially generated subsets subtract
268 : : // their content from the parent subset (and not
269 : : // the original shape). Otherwise, already
270 : : // subsetted parents (e.g. paragraphs) would not
271 : : // have their characters removed, when the child
272 : : // iterations start.
273 : : // Furthermore, the setup of initial shape
274 : : // attributes of course needs the subset shape
275 : : // generated, to apply e.g. visibility changes.
276 : 0 : pTargetSubset->enableSubsetShape();
277 : : }
278 : : else
279 : : {
280 : : pTargetSubset.reset(
281 : : new ShapeSubset( pTargetShape,
282 : 0 : rContext.maContext.mpSubsettableShapeManager ));
283 : : }
284 : :
285 : 0 : aContext.mpMasterShapeSubset = pTargetSubset;
286 : : uno::Reference< animations::XAnimationNode > xNode( xIterNode,
287 : 0 : uno::UNO_QUERY_THROW );
288 : :
289 : : // Generate subsets
290 : : // ================
291 : :
292 : 0 : if( bParagraphTarget ||
293 : : nSubItem != presentation::ShapeAnimationSubType::ONLY_TEXT )
294 : : {
295 : : // prepend with animations for
296 : : // full Shape (will be subtracted
297 : : // from the subset parts within
298 : : // the Shape::createSubset()
299 : : // method). For ONLY_TEXT effects,
300 : : // we skip this part, to animate
301 : : // only the text.
302 : : //
303 : : // OR
304 : : //
305 : : // prepend with subset animation for full
306 : : // _paragraph_, from which the individual
307 : : // paragraph subsets are subtracted. Note that the
308 : : // subitem is superfluous here, we always assume
309 : : // ONLY_TEXT, if a paragraph is referenced as the
310 : : // master of an iteration effect.
311 : 0 : NodeCreator aCreator( rParent, aContext );
312 : 0 : if( !::anim::for_each_childNode( xNode,
313 : 0 : aCreator ) )
314 : : {
315 : 0 : ENSURE_OR_RETURN_FALSE(
316 : : false,
317 : : "implCreateIteratedNodes(): iterated child node creation failed" );
318 : : }
319 : : }
320 : :
321 : : // TODO(F2): This does not do the correct
322 : : // thing. Having nSubItem be set to ONLY_BACKGROUND
323 : : // should result in the text staying unanimated in the
324 : : // foreground, while the shape moves in the background
325 : : // (this behaviour is perfectly possible with the
326 : : // slideshow engine, only that the text won't be
327 : : // currently visible, because animations are always in
328 : : // the foreground)
329 : 0 : if( nSubItem != presentation::ShapeAnimationSubType::ONLY_BACKGROUND )
330 : : {
331 : : // determine type of subitem iteration (logical
332 : : // text unit to animate)
333 : : DocTreeNode::NodeType eIterateNodeType(
334 : 0 : DocTreeNode::NODETYPE_LOGICAL_CHARACTER_CELL );
335 : :
336 : 0 : switch( xIterNode->getIterateType() )
337 : : {
338 : : case presentation::TextAnimationType::BY_PARAGRAPH:
339 : 0 : eIterateNodeType = DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH;
340 : 0 : break;
341 : :
342 : : case presentation::TextAnimationType::BY_WORD:
343 : 0 : eIterateNodeType = DocTreeNode::NODETYPE_LOGICAL_WORD;
344 : 0 : break;
345 : :
346 : : case presentation::TextAnimationType::BY_LETTER:
347 : 0 : eIterateNodeType = DocTreeNode::NODETYPE_LOGICAL_CHARACTER_CELL;
348 : 0 : break;
349 : :
350 : : default:
351 : 0 : ENSURE_OR_THROW(
352 : : false, "implCreateIteratedNodes(): "
353 : : "Unexpected IterateType on XIterateContainer");
354 : : break;
355 : : }
356 : :
357 : 0 : if( bParagraphTarget &&
358 : : eIterateNodeType != DocTreeNode::NODETYPE_LOGICAL_WORD &&
359 : : eIterateNodeType != DocTreeNode::NODETYPE_LOGICAL_CHARACTER_CELL )
360 : : {
361 : : // will not animate the whole paragraph, when
362 : : // only the paragraph is animated at all.
363 : : OSL_FAIL( "implCreateIteratedNodes(): Ignoring paragraph iteration for paragraph master" );
364 : : }
365 : : else
366 : : {
367 : : // setup iteration parameters
368 : : // --------------------------
369 : :
370 : : // iterate target is the whole shape (or the
371 : : // whole parent subshape), thus, can save
372 : : // loads of subset shapes by generating them
373 : : // only when the effects become active -
374 : : // before and after the effect active
375 : : // duration, all attributes are shared by
376 : : // master shape and subset (since the iterated
377 : : // effects are all the same).
378 : 0 : aContext.mbIsIndependentSubset = false;
379 : :
380 : : // determine number of nodes for given subitem
381 : : // type
382 : 0 : sal_Int32 nTreeNodes( 0 );
383 : 0 : if( bParagraphTarget )
384 : : {
385 : : // create the iterated subset _relative_ to
386 : : // the given paragraph index (i.e. animate the
387 : : // given subset type, but only when it's part
388 : : // of the given paragraph)
389 : : nTreeNodes = rTreeNodeSupplier.getNumberOfSubsetTreeNodes(
390 : 0 : pTargetSubset->getSubset(),
391 : 0 : eIterateNodeType );
392 : : }
393 : : else
394 : : {
395 : : // generate normal subset
396 : : nTreeNodes = rTreeNodeSupplier.getNumberOfTreeNodes(
397 : 0 : eIterateNodeType );
398 : : }
399 : :
400 : :
401 : : // iterate node, generate copies of the children for each subset
402 : : // -------------------------------------------------------------
403 : :
404 : : // NodeContext::mnStartDelay contains additional node delay.
405 : : // This will make the duplicated nodes for each iteration start
406 : : // increasingly later.
407 : 0 : aContext.mnStartDelay = nIntervalTimeout;
408 : :
409 : 0 : for( sal_Int32 i=0; i<nTreeNodes; ++i )
410 : : {
411 : : // create subset with the corresponding tree nodes
412 : 0 : if( bParagraphTarget )
413 : : {
414 : : // create subsets relative to paragraph subset
415 : : aContext.mpMasterShapeSubset.reset(
416 : : new ShapeSubset(
417 : : pTargetSubset,
418 : : rTreeNodeSupplier.getSubsetTreeNode(
419 : 0 : pTargetSubset->getSubset(),
420 : : i,
421 : 0 : eIterateNodeType ) ) );
422 : : }
423 : : else
424 : : {
425 : : // create subsets from main shape
426 : : aContext.mpMasterShapeSubset.reset(
427 : : new ShapeSubset( pTargetSubset,
428 : : rTreeNodeSupplier.getTreeNode(
429 : : i,
430 : 0 : eIterateNodeType ) ) );
431 : : }
432 : :
433 : 0 : CloningNodeCreator aCreator( rParent, aContext );
434 : 0 : if( !::anim::for_each_childNode( xNode,
435 : 0 : aCreator ) )
436 : : {
437 : 0 : ENSURE_OR_RETURN_FALSE(
438 : : false, "implCreateIteratedNodes(): "
439 : : "iterated child node creation failed" );
440 : : }
441 : :
442 : 0 : aContext.mnStartDelay += nIntervalTimeout;
443 : : }
444 : : }
445 : : }
446 : :
447 : : // done with iterate child generation
448 : 0 : return true;
449 : : }
450 : :
451 : 0 : BaseNodeSharedPtr implCreateAnimationNode(
452 : : const uno::Reference< animations::XAnimationNode >& xNode,
453 : : const BaseContainerNodeSharedPtr& rParent,
454 : : const NodeContext& rContext )
455 : : {
456 : 0 : ENSURE_OR_THROW( xNode.is(),
457 : : "implCreateAnimationNode(): invalid XAnimationNode" );
458 : :
459 : 0 : BaseNodeSharedPtr pCreatedNode;
460 : 0 : BaseContainerNodeSharedPtr pCreatedContainer;
461 : :
462 : : // create the internal node, corresponding to xNode
463 : 0 : switch( xNode->getType() )
464 : : {
465 : : case animations::AnimationNodeType::CUSTOM:
466 : : OSL_FAIL( "implCreateAnimationNode(): "
467 : : "CUSTOM not yet implemented" );
468 : 0 : return pCreatedNode;
469 : :
470 : : case animations::AnimationNodeType::PAR:
471 : : pCreatedNode = pCreatedContainer = BaseContainerNodeSharedPtr(
472 : 0 : new ParallelTimeContainer( xNode, rParent, rContext ) );
473 : 0 : break;
474 : :
475 : : case animations::AnimationNodeType::ITERATE:
476 : : // map iterate container to ParallelTimeContainer.
477 : : // the iterating functionality is to be found
478 : : // below, (see method implCreateIteratedNodes)
479 : : pCreatedNode = pCreatedContainer = BaseContainerNodeSharedPtr(
480 : 0 : new ParallelTimeContainer( xNode, rParent, rContext ) );
481 : 0 : break;
482 : :
483 : : case animations::AnimationNodeType::SEQ:
484 : : pCreatedNode = pCreatedContainer = BaseContainerNodeSharedPtr(
485 : 0 : new SequentialTimeContainer( xNode, rParent, rContext ) );
486 : 0 : break;
487 : :
488 : : case animations::AnimationNodeType::ANIMATE:
489 : : pCreatedNode.reset( new PropertyAnimationNode(
490 : 0 : xNode, rParent, rContext ) );
491 : 0 : break;
492 : :
493 : : case animations::AnimationNodeType::SET:
494 : : pCreatedNode.reset( new AnimationSetNode(
495 : 0 : xNode, rParent, rContext ) );
496 : 0 : break;
497 : :
498 : : case animations::AnimationNodeType::ANIMATEMOTION:
499 : : pCreatedNode.reset( new AnimationPathMotionNode(
500 : 0 : xNode, rParent, rContext ) );
501 : 0 : break;
502 : :
503 : : case animations::AnimationNodeType::ANIMATECOLOR:
504 : : pCreatedNode.reset( new AnimationColorNode(
505 : 0 : xNode, rParent, rContext ) );
506 : 0 : break;
507 : :
508 : : case animations::AnimationNodeType::ANIMATETRANSFORM:
509 : : pCreatedNode.reset( new AnimationTransformNode(
510 : 0 : xNode, rParent, rContext ) );
511 : 0 : break;
512 : :
513 : : case animations::AnimationNodeType::TRANSITIONFILTER:
514 : : pCreatedNode.reset( new AnimationTransitionFilterNode(
515 : 0 : xNode, rParent, rContext ) );
516 : 0 : break;
517 : :
518 : : case animations::AnimationNodeType::AUDIO:
519 : : pCreatedNode.reset( new AnimationAudioNode(
520 : 0 : xNode, rParent, rContext ) );
521 : 0 : break;
522 : :
523 : : case animations::AnimationNodeType::COMMAND:
524 : : pCreatedNode.reset( new AnimationCommandNode(
525 : 0 : xNode, rParent, rContext ) );
526 : 0 : break;
527 : :
528 : : default:
529 : : OSL_FAIL( "implCreateAnimationNode(): "
530 : : "invalid AnimationNodeType" );
531 : 0 : return pCreatedNode;
532 : : }
533 : :
534 : : // TODO(Q1): This yields circular references, which, it seems, is
535 : : // unavoidable here
536 : :
537 : : // HACK: node objects need shared_ptr to themselves,
538 : : // which we pass them here.
539 : 0 : pCreatedNode->setSelf( pCreatedNode );
540 : :
541 : : // if we've got a container node object, recursively add
542 : : // its children
543 : 0 : if( pCreatedContainer )
544 : : {
545 : : uno::Reference< animations::XIterateContainer > xIterNode(
546 : 0 : xNode, uno::UNO_QUERY );
547 : :
548 : : // when this node is an XIterateContainer with
549 : : // active iterations, this method will generate
550 : : // the appropriate children
551 : 0 : if( xIterNode.is() )
552 : : {
553 : : // note that implCreateIteratedNodes() might
554 : : // choose not to generate any child nodes
555 : : // (e.g. when the iterate timeout is outside
556 : : // sensible limits). Then, no child nodes are
557 : : // generated at all, since typically, child
558 : : // node attribute are incomplete for iteration
559 : : // children.
560 : : implCreateIteratedNodes( xIterNode,
561 : : pCreatedContainer,
562 : 0 : rContext );
563 : : }
564 : : else
565 : : {
566 : : // no iterate subset node, just plain child generation now
567 : 0 : NodeCreator aCreator( pCreatedContainer, rContext );
568 : 0 : if( !::anim::for_each_childNode( xNode, aCreator ) )
569 : : {
570 : : OSL_FAIL( "implCreateAnimationNode(): "
571 : : "child node creation failed" );
572 : 0 : return BaseNodeSharedPtr();
573 : : }
574 : 0 : }
575 : : }
576 : :
577 : 0 : return pCreatedNode;
578 : : }
579 : :
580 : : } // anon namespace
581 : :
582 : 0 : AnimationNodeSharedPtr AnimationNodeFactory::createAnimationNode(
583 : : const uno::Reference< animations::XAnimationNode >& xNode,
584 : : const ::basegfx::B2DVector& rSlideSize,
585 : : const SlideShowContext& rContext )
586 : : {
587 : 0 : ENSURE_OR_THROW(
588 : : xNode.is(),
589 : : "AnimationNodeFactory::createAnimationNode(): invalid XAnimationNode" );
590 : :
591 : : return BaseNodeSharedPtr( implCreateAnimationNode(
592 : : xNode,
593 : : BaseContainerNodeSharedPtr(), // no parent
594 : : NodeContext( rContext,
595 : 0 : rSlideSize )));
596 : : }
597 : :
598 : : #if OSL_DEBUG_LEVEL >= 2 && defined(DBG_UTIL)
599 : : void AnimationNodeFactory::showTree( AnimationNodeSharedPtr& pRootNode )
600 : : {
601 : : if( pRootNode )
602 : : DEBUG_NODES_SHOWTREE( boost::dynamic_pointer_cast<BaseContainerNode>(
603 : : pRootNode).get() );
604 : : }
605 : : #endif
606 : :
607 : : } // namespace internal
608 : : } // namespace slideshow
609 : :
610 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|