LCOV - code coverage report
Current view: top level - slideshow/source/engine/animationnodes - animationnodefactory.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 0 128 0.0 %
Date: 2014-11-03 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10