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