1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_slideshow.hxx" 30 31 // must be first 32 #include <canvas/debug.hxx> 33 #include <canvas/verbosetrace.hxx> 34 35 #include "basecontainernode.hxx" 36 #include "tools.hxx" 37 #include "nodetools.hxx" 38 #include "delayevent.hxx" 39 40 #include <boost/mem_fn.hpp> 41 #include <algorithm> 42 43 using namespace com::sun::star; 44 45 namespace slideshow { 46 namespace internal { 47 48 BaseContainerNode::BaseContainerNode( 49 const uno::Reference< animations::XAnimationNode >& xNode, 50 const BaseContainerNodeSharedPtr& rParent, 51 const NodeContext& rContext ) 52 : BaseNode( xNode, rParent, rContext ), 53 maChildren(), 54 mnFinishedChildren(0), 55 mbDurationIndefinite( isIndefiniteTiming( xNode->getEnd() ) && 56 isIndefiniteTiming( xNode->getDuration() ) ) 57 { 58 } 59 60 void BaseContainerNode::dispose() 61 { 62 forEachChildNode( boost::mem_fn(&Disposable::dispose) ); 63 maChildren.clear(); 64 BaseNode::dispose(); 65 } 66 67 bool BaseContainerNode::init_st() 68 { 69 mnFinishedChildren = 0; 70 // initialize all children 71 return (std::count_if( 72 maChildren.begin(), maChildren.end(), 73 boost::mem_fn(&AnimationNode::init) ) == 74 static_cast<VectorOfNodes::difference_type>(maChildren.size())); 75 } 76 77 void BaseContainerNode::deactivate_st( NodeState eDestState ) 78 { 79 if (eDestState == FROZEN) { 80 // deactivate all children that are not FROZEN or ENDED: 81 forEachChildNode( boost::mem_fn(&AnimationNode::deactivate), 82 ~(FROZEN | ENDED) ); 83 } 84 else { 85 // end all children that are not ENDED: 86 forEachChildNode( boost::mem_fn(&AnimationNode::end), ~ENDED ); 87 } 88 } 89 90 bool BaseContainerNode::hasPendingAnimation() const 91 { 92 // does any of our children returns "true" on 93 // AnimationNode::hasPendingAnimation()? 94 // If yes, we, too, return true 95 VectorOfNodes::const_iterator const iEnd( maChildren.end() ); 96 return (std::find_if( 97 maChildren.begin(), iEnd, 98 boost::mem_fn(&AnimationNode::hasPendingAnimation) ) != iEnd); 99 } 100 101 void BaseContainerNode::appendChildNode( AnimationNodeSharedPtr const& pNode ) 102 { 103 if (! checkValidNode()) 104 return; 105 106 // register derived classes as end listeners at all children. 107 // this is necessary to control the children animation 108 // sequence, and to determine our own end event 109 if (pNode->registerDeactivatingListener( getSelf() )) { 110 maChildren.push_back( pNode ); 111 } 112 } 113 114 bool BaseContainerNode::isChildNode( AnimationNodeSharedPtr const& pNode ) const 115 { 116 // find given notifier in child vector 117 VectorOfNodes::const_iterator const iBegin( maChildren.begin() ); 118 VectorOfNodes::const_iterator const iEnd( maChildren.end() ); 119 VectorOfNodes::const_iterator const iFind( 120 std::find( iBegin, iEnd, pNode ) ); 121 return (iFind != iEnd); 122 } 123 124 bool BaseContainerNode::notifyDeactivatedChild( 125 AnimationNodeSharedPtr const& pChildNode ) 126 { 127 OSL_ASSERT( pChildNode->getState() == FROZEN || 128 pChildNode->getState() == ENDED ); 129 // early exit on invalid nodes 130 OSL_ASSERT( getState() != INVALID ); 131 if( getState() == INVALID ) 132 return false; 133 134 if (! isChildNode(pChildNode)) { 135 OSL_ENSURE( false, "unknown notifier!" ); 136 return false; 137 } 138 139 std::size_t const nSize = maChildren.size(); 140 OSL_ASSERT( mnFinishedChildren < nSize ); 141 ++mnFinishedChildren; 142 bool const bFinished = (mnFinishedChildren >= nSize); 143 144 // all children finished, and we've got indefinite duration? 145 // think of ParallelTimeContainer::notifyDeactivating() 146 // if duration given, we will be deactivated by some end event 147 // @see fillCommonParameters() 148 if (bFinished && isDurationIndefinite()) { 149 deactivate(); 150 } 151 152 return bFinished; 153 } 154 155 #if defined(VERBOSE) && defined(DBG_UTIL) 156 void BaseContainerNode::showState() const 157 { 158 for( std::size_t i=0; i<maChildren.size(); ++i ) 159 { 160 BaseNodeSharedPtr pNode = 161 boost::shared_dynamic_cast<BaseNode>(maChildren[i]); 162 VERBOSE_TRACE( 163 "Node connection: n0x%X -> n0x%X", 164 (const char*)this+debugGetCurrentOffset(), 165 (const char*)pNode.get()+debugGetCurrentOffset() ); 166 pNode->showState(); 167 } 168 169 BaseNode::showState(); 170 } 171 #endif 172 173 } // namespace internal 174 } // namespace slideshow 175 176