19f4ab948SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39f4ab948SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f4ab948SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f4ab948SAndrew Rist  * distributed with this work for additional information
69f4ab948SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f4ab948SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f4ab948SAndrew Rist  * "License"); you may not use this file except in compliance
99f4ab948SAndrew Rist  * with the License.  You may obtain a copy of the License at
109f4ab948SAndrew Rist  *
119f4ab948SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
129f4ab948SAndrew Rist  *
139f4ab948SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f4ab948SAndrew Rist  * software distributed under the License is distributed on an
159f4ab948SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f4ab948SAndrew Rist  * KIND, either express or implied.  See the License for the
179f4ab948SAndrew Rist  * specific language governing permissions and limitations
189f4ab948SAndrew Rist  * under the License.
199f4ab948SAndrew Rist  *
209f4ab948SAndrew Rist  *************************************************************/
219f4ab948SAndrew Rist 
229f4ab948SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp>
25cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
26cdf0e10cSrcweir #include <com/sun/star/lang/XTypeProvider.hpp>
27cdf0e10cSrcweir #include <com/sun/star/animations/XTargetPropertiesCreator.hpp>
28cdf0e10cSrcweir #include <com/sun/star/animations/XIterateContainer.hpp>
29cdf0e10cSrcweir #include <com/sun/star/animations/TargetProperties.hpp>
30cdf0e10cSrcweir #include <com/sun/star/presentation/ParagraphTarget.hpp>
31cdf0e10cSrcweir #include <com/sun/star/registry/XRegistryKey.hpp>
32cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
33cdf0e10cSrcweir #include <com/sun/star/lang/XServiceName.hpp>
34cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35cdf0e10cSrcweir #include <com/sun/star/drawing/XShape.hpp>
36cdf0e10cSrcweir #include <com/sun/star/animations/AnimationNodeType.hpp>
37cdf0e10cSrcweir #include <com/sun/star/animations/XAnimate.hpp>
38cdf0e10cSrcweir #include <cppuhelper/compbase3.hxx>
39cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
40cdf0e10cSrcweir #include <cppuhelper/implementationentry.hxx>
41cdf0e10cSrcweir #include <comphelper/broadcasthelper.hxx>
42cdf0e10cSrcweir #include <comphelper/sequence.hxx>
43cdf0e10cSrcweir 
44cdf0e10cSrcweir #include <animations/animationnodehelper.hxx>
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #include <vector>
47cdf0e10cSrcweir #include <hash_map>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 
50cdf0e10cSrcweir using namespace ::com::sun::star;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #define IMPLEMENTATION_NAME "animcore::TargetPropertiesCreator"
53cdf0e10cSrcweir #define SERVICE_NAME "com.sun.star.animations.TargetPropertiesCreator"
54cdf0e10cSrcweir 
55cdf0e10cSrcweir namespace animcore
56cdf0e10cSrcweir {
57cdf0e10cSrcweir     typedef ::cppu::WeakComponentImplHelper3< ::com::sun::star::animations::XTargetPropertiesCreator,
58cdf0e10cSrcweir                                               lang::XServiceInfo,
59cdf0e10cSrcweir                                               lang::XServiceName >  TargetPropertiesCreator_Base;
60cdf0e10cSrcweir 
61cdf0e10cSrcweir     class TargetPropertiesCreator : public ::comphelper::OBaseMutex,
62cdf0e10cSrcweir                                     public TargetPropertiesCreator_Base
63cdf0e10cSrcweir     {
64cdf0e10cSrcweir     public:
createInstance(const uno::Reference<uno::XComponentContext> & xContext)65cdf0e10cSrcweir         static uno::Reference< uno::XInterface > SAL_CALL createInstance( const uno::Reference< uno::XComponentContext >& xContext ) throw ( uno::Exception )
66cdf0e10cSrcweir         {
67cdf0e10cSrcweir             return uno::Reference< uno::XInterface >( static_cast<cppu::OWeakObject*>(new TargetPropertiesCreator( xContext )) );
68cdf0e10cSrcweir         }
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 	    /// Dispose all internal references
71cdf0e10cSrcweir         virtual void SAL_CALL disposing();
72cdf0e10cSrcweir 
73cdf0e10cSrcweir         // XTargetPropertiesCreator
74cdf0e10cSrcweir         virtual uno::Sequence< animations::TargetProperties > SAL_CALL createInitialTargetProperties( const uno::Reference< animations::XAnimationNode >& rootNode ) throw (uno::RuntimeException);
75cdf0e10cSrcweir 
76cdf0e10cSrcweir         // XServiceInfo
77cdf0e10cSrcweir         virtual ::rtl::OUString SAL_CALL getImplementationName() throw( uno::RuntimeException );
78cdf0e10cSrcweir         virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException );
79cdf0e10cSrcweir         virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()  throw( uno::RuntimeException );
80cdf0e10cSrcweir 
81cdf0e10cSrcweir         // XServiceName
82cdf0e10cSrcweir         virtual ::rtl::OUString SAL_CALL getServiceName(  ) throw (uno::RuntimeException);
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     protected:
85cdf0e10cSrcweir         ~TargetPropertiesCreator(); // we're a ref-counted UNO class. _We_ destroy ourselves.
86cdf0e10cSrcweir 
87cdf0e10cSrcweir     private:
88cdf0e10cSrcweir         // default: disabled copy/assignment
89cdf0e10cSrcweir         TargetPropertiesCreator(const TargetPropertiesCreator&);
90cdf0e10cSrcweir         TargetPropertiesCreator& operator=( const TargetPropertiesCreator& );
91cdf0e10cSrcweir 
92cdf0e10cSrcweir         TargetPropertiesCreator( const uno::Reference< uno::XComponentContext >& rxContext );
93cdf0e10cSrcweir     };
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 	// --------------------------------------------------------------------
96cdf0e10cSrcweir 
createInstance_TargetPropertiesCreator(const uno::Reference<uno::XComponentContext> & rSMgr)97cdf0e10cSrcweir     uno::Reference< uno::XInterface > SAL_CALL createInstance_TargetPropertiesCreator( const uno::Reference< uno::XComponentContext > & rSMgr ) throw (uno::Exception)
98cdf0e10cSrcweir     {
99cdf0e10cSrcweir         return TargetPropertiesCreator::createInstance( rSMgr );
100cdf0e10cSrcweir     }
101cdf0e10cSrcweir 
getImplementationName_TargetPropertiesCreator()102cdf0e10cSrcweir     ::rtl::OUString getImplementationName_TargetPropertiesCreator()
103cdf0e10cSrcweir     {
104cdf0e10cSrcweir         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir 
getSupportedServiceNames_TargetPropertiesCreator(void)107cdf0e10cSrcweir     uno::Sequence< ::rtl::OUString > getSupportedServiceNames_TargetPropertiesCreator(void)
108cdf0e10cSrcweir     {
109cdf0e10cSrcweir         uno::Sequence< ::rtl::OUString > aRet(1);
110cdf0e10cSrcweir         aRet.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) );
111cdf0e10cSrcweir         return aRet;
112cdf0e10cSrcweir     }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 	// --------------------------------------------------------------------
115cdf0e10cSrcweir 
116cdf0e10cSrcweir     namespace
117cdf0e10cSrcweir     {
118cdf0e10cSrcweir         // Vector containing all properties for a given shape
119cdf0e10cSrcweir         typedef ::std::vector< beans::NamedValue > VectorOfNamedValues;
120cdf0e10cSrcweir 
121cdf0e10cSrcweir         /** The hash map key
122cdf0e10cSrcweir 
123cdf0e10cSrcweir         	This key contains both XShape reference and a paragraph
124cdf0e10cSrcweir         	index, as we somehow have to handle shape and paragraph
125cdf0e10cSrcweir         	targets with the same data structure.
126cdf0e10cSrcweir          */
127cdf0e10cSrcweir         struct ShapeHashKey
128cdf0e10cSrcweir         {
129cdf0e10cSrcweir             /// Shape target
130cdf0e10cSrcweir             uno::Reference< drawing::XShape >	mxRef;
131cdf0e10cSrcweir 
132cdf0e10cSrcweir             /** Paragraph index.
133cdf0e10cSrcweir 
134cdf0e10cSrcweir             	If this is a pure shape target, mnParagraphIndex is
135cdf0e10cSrcweir             	set to -1.
136cdf0e10cSrcweir              */
137cdf0e10cSrcweir             sal_Int16							mnParagraphIndex;
138cdf0e10cSrcweir 
139cdf0e10cSrcweir             /// Comparison needed for hash_map
operator ==animcore::__anon47324aba0111::ShapeHashKey140cdf0e10cSrcweir             bool operator==( const ShapeHashKey& rRHS ) const
141cdf0e10cSrcweir             {
142cdf0e10cSrcweir                 return mxRef == rRHS.mxRef && mnParagraphIndex == rRHS.mnParagraphIndex;
143cdf0e10cSrcweir             }
144cdf0e10cSrcweir         };
145cdf0e10cSrcweir 
146*8dd563e3SHerbert Dürr         // A hash functor for ShapeHashKey objects
147*8dd563e3SHerbert Dürr         struct ShapeKeyHasher {
operator ()animcore::__anon47324aba0111::ShapeKeyHasher148*8dd563e3SHerbert Dürr 		::std::size_t operator()( const ShapeHashKey& rKey ) const
149*8dd563e3SHerbert Dürr 		{
150*8dd563e3SHerbert Dürr 		// TODO(P2): Maybe a better hash function would be to
151*8dd563e3SHerbert Dürr 		// spread mnParagraphIndex to 32 bit: a0b0c0d0e0... Hakmem
152*8dd563e3SHerbert Dürr 		// should have a formula.
153*8dd563e3SHerbert Dürr 		//
154*8dd563e3SHerbert Dürr 		// Yes it has:
155*8dd563e3SHerbert Dürr 		// x = (x & 0x0000FF00) << 8) | (x >> 8) & 0x0000FF00 | x & 0xFF0000FF;
156*8dd563e3SHerbert Dürr 		// x = (x & 0x00F000F0) << 4) | (x >> 4) & 0x00F000F0 | x & 0xF00FF00F;
157*8dd563e3SHerbert Dürr 		// x = (x & 0x0C0C0C0C) << 2) | (x >> 2) & 0x0C0C0C0C | x & 0xC3C3C3C3;
158*8dd563e3SHerbert Dürr 		// x = (x & 0x22222222) << 1) | (x >> 1) & 0x22222222 | x & 0x99999999;
159*8dd563e3SHerbert Dürr 		//
160*8dd563e3SHerbert Dürr 		// Costs about 17 cycles on a RISC machine with infinite
161*8dd563e3SHerbert Dürr 		// instruction level parallelism (~42 basic
162*8dd563e3SHerbert Dürr 		// instructions). Thus I truly doubt this pays off...
163*8dd563e3SHerbert Dürr 		return reinterpret_cast< ::std::size_t >(rKey.mxRef.get()) ^ (rKey.mnParagraphIndex << 16L);
164*8dd563e3SHerbert Dürr 	    }
165*8dd563e3SHerbert Dürr 	};
166cdf0e10cSrcweir 
167*8dd563e3SHerbert Dürr         // A hash map which maps a XShape to the corresponding vector of initial properties
168*8dd563e3SHerbert Dürr         typedef ::std::hash_map< ShapeHashKey, VectorOfNamedValues, ShapeKeyHasher > XShapeHash;
169cdf0e10cSrcweir 
170cdf0e10cSrcweir         class NodeFunctor
171cdf0e10cSrcweir         {
172cdf0e10cSrcweir         public:
NodeFunctor(XShapeHash & rShapeHash)173cdf0e10cSrcweir             explicit NodeFunctor( XShapeHash& rShapeHash ) :
174cdf0e10cSrcweir                 mrShapeHash( rShapeHash ),
175cdf0e10cSrcweir                 mxTargetShape(),
176cdf0e10cSrcweir                 mnParagraphIndex( -1 )
177cdf0e10cSrcweir             {
178cdf0e10cSrcweir             }
179cdf0e10cSrcweir 
NodeFunctor(XShapeHash & rShapeHash,const uno::Reference<drawing::XShape> & rTargetShape,sal_Int16 nParagraphIndex)180cdf0e10cSrcweir             NodeFunctor( XShapeHash& 								rShapeHash,
181cdf0e10cSrcweir                          const uno::Reference< drawing::XShape >& 	rTargetShape,
182cdf0e10cSrcweir                          sal_Int16									nParagraphIndex ) :
183cdf0e10cSrcweir                 mrShapeHash( rShapeHash ),
184cdf0e10cSrcweir                 mxTargetShape( rTargetShape ),
185cdf0e10cSrcweir                 mnParagraphIndex( nParagraphIndex )
186cdf0e10cSrcweir             {
187cdf0e10cSrcweir             }
188cdf0e10cSrcweir 
operator ()(const uno::Reference<animations::XAnimationNode> & xNode) const189cdf0e10cSrcweir             void operator()( const uno::Reference< animations::XAnimationNode >& xNode ) const
190cdf0e10cSrcweir             {
191cdf0e10cSrcweir                 if( !xNode.is() )
192cdf0e10cSrcweir                 {
193cdf0e10cSrcweir                     OSL_ENSURE( false,
194cdf0e10cSrcweir                                 "AnimCore: NodeFunctor::operator(): invalid XAnimationNode" );
195cdf0e10cSrcweir                     return;
196cdf0e10cSrcweir                 }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir                 uno::Reference< drawing::XShape > xTargetShape( mxTargetShape );
199cdf0e10cSrcweir                 sal_Int16						  nParagraphIndex( mnParagraphIndex );
200cdf0e10cSrcweir 
201cdf0e10cSrcweir                 switch( xNode->getType() )
202cdf0e10cSrcweir                 {
203cdf0e10cSrcweir                     case animations::AnimationNodeType::ITERATE:
204cdf0e10cSrcweir                     {
205cdf0e10cSrcweir                         // extract target shape from iterate node
206cdf0e10cSrcweir                         // (will override the target for all children)
207cdf0e10cSrcweir                         // --------------------------------------------------
208cdf0e10cSrcweir 
209cdf0e10cSrcweir                         uno::Reference< animations::XIterateContainer > xIterNode( xNode,
210cdf0e10cSrcweir                                                                                    uno::UNO_QUERY );
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 	                    // TODO(E1): I'm not too sure what to expect here...
213cdf0e10cSrcweir                         if( !xIterNode->getTarget().hasValue() )
214cdf0e10cSrcweir                         {
215cdf0e10cSrcweir                             OSL_ENSURE( false,
216cdf0e10cSrcweir                                         "animcore: NodeFunctor::operator(): no target on ITERATE node" );
217cdf0e10cSrcweir                             return;
218cdf0e10cSrcweir                         }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir                         xTargetShape.set( xIterNode->getTarget(),
221cdf0e10cSrcweir                                           uno::UNO_QUERY );
222cdf0e10cSrcweir 
223cdf0e10cSrcweir                         if( !xTargetShape.is() )
224cdf0e10cSrcweir                         {
225cdf0e10cSrcweir                             ::com::sun::star::presentation::ParagraphTarget aTarget;
226cdf0e10cSrcweir 
227cdf0e10cSrcweir                             // no shape provided. Maybe a ParagraphTarget?
228cdf0e10cSrcweir                             if( !(xIterNode->getTarget() >>= aTarget) )
229cdf0e10cSrcweir                             {
230cdf0e10cSrcweir                                 OSL_ENSURE( false,
231cdf0e10cSrcweir                                             "animcore: NodeFunctor::operator(): could not extract any "
232cdf0e10cSrcweir                                             "target information" );
233cdf0e10cSrcweir                                 return;
234cdf0e10cSrcweir                             }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir                             xTargetShape = aTarget.Shape;
237cdf0e10cSrcweir                             nParagraphIndex = aTarget.Paragraph;
238cdf0e10cSrcweir 
239cdf0e10cSrcweir                             if( !xTargetShape.is() )
240cdf0e10cSrcweir                             {
241cdf0e10cSrcweir                                 OSL_ENSURE( false,
242cdf0e10cSrcweir                                             "animcore: NodeFunctor::operator(): invalid shape in ParagraphTarget" );
243cdf0e10cSrcweir                                 return;
244cdf0e10cSrcweir                             }
245cdf0e10cSrcweir                         }
246cdf0e10cSrcweir                     }
247cdf0e10cSrcweir 	                    // FALLTHROUGH intended
248cdf0e10cSrcweir                     case animations::AnimationNodeType::PAR:
249cdf0e10cSrcweir                         // FALLTHROUGH intended
250cdf0e10cSrcweir                     case animations::AnimationNodeType::SEQ:
251cdf0e10cSrcweir                     {
252cdf0e10cSrcweir                         NodeFunctor aFunctor( mrShapeHash,
253cdf0e10cSrcweir                                               xTargetShape,
254cdf0e10cSrcweir                                               nParagraphIndex );
255cdf0e10cSrcweir                         if( !::anim::for_each_childNode( xNode,
256cdf0e10cSrcweir                                                          aFunctor ) )
257cdf0e10cSrcweir                         {
258cdf0e10cSrcweir                             OSL_ENSURE( false,
259cdf0e10cSrcweir                                         "AnimCore: NodeFunctor::operator(): child node iteration failed, "
260cdf0e10cSrcweir                                         "or extraneous container nodes encountered" );
261cdf0e10cSrcweir                         }
262cdf0e10cSrcweir                     }
263cdf0e10cSrcweir                     break;
264cdf0e10cSrcweir 
265cdf0e10cSrcweir                     case animations::AnimationNodeType::CUSTOM:
266cdf0e10cSrcweir                         // FALLTHROUGH intended
267cdf0e10cSrcweir                     case animations::AnimationNodeType::ANIMATE:
268cdf0e10cSrcweir                         // FALLTHROUGH intended
269cdf0e10cSrcweir                     case animations::AnimationNodeType::ANIMATEMOTION:
270cdf0e10cSrcweir                         // FALLTHROUGH intended
271cdf0e10cSrcweir                     case animations::AnimationNodeType::ANIMATECOLOR:
272cdf0e10cSrcweir                         // FALLTHROUGH intended
273cdf0e10cSrcweir                     case animations::AnimationNodeType::ANIMATETRANSFORM:
274cdf0e10cSrcweir                         // FALLTHROUGH intended
275cdf0e10cSrcweir                     case animations::AnimationNodeType::TRANSITIONFILTER:
276cdf0e10cSrcweir                         // FALLTHROUGH intended
277cdf0e10cSrcweir                     case animations::AnimationNodeType::AUDIO:
278cdf0e10cSrcweir                         // FALLTHROUGH intended
2799584452cSAndre Fischer                     /*default:
280cdf0e10cSrcweir                         // ignore this node, no valuable content for now.
2819584452cSAndre Fischer                         break;*/
282cdf0e10cSrcweir 
283cdf0e10cSrcweir                     case animations::AnimationNodeType::SET:
284cdf0e10cSrcweir                     {
285cdf0e10cSrcweir                         // evaluate set node content
286cdf0e10cSrcweir                         uno::Reference< animations::XAnimate > xAnimateNode( xNode,
287cdf0e10cSrcweir                                                                              uno::UNO_QUERY );
288cdf0e10cSrcweir 
289cdf0e10cSrcweir                         if( !xAnimateNode.is() )
290cdf0e10cSrcweir                             break; // invalid node
291cdf0e10cSrcweir 
292cdf0e10cSrcweir                         // determine target shape (if any)
293cdf0e10cSrcweir                         ShapeHashKey aTarget;
294cdf0e10cSrcweir                         if( xTargetShape.is() )
295cdf0e10cSrcweir                         {
296cdf0e10cSrcweir                             // override target shape with parent-supplied
297cdf0e10cSrcweir                             aTarget.mxRef = xTargetShape;
298cdf0e10cSrcweir                             aTarget.mnParagraphIndex = nParagraphIndex;
299cdf0e10cSrcweir                         }
300cdf0e10cSrcweir                         else
301cdf0e10cSrcweir                         {
302cdf0e10cSrcweir                             // no parent-supplied target, retrieve
303cdf0e10cSrcweir                             // node target
304cdf0e10cSrcweir                             if( (xAnimateNode->getTarget() >>= aTarget.mxRef) )
305cdf0e10cSrcweir                             {
306cdf0e10cSrcweir                                 // pure shape target - set paragraph
307cdf0e10cSrcweir                                 // index to magic
308cdf0e10cSrcweir                                 aTarget.mnParagraphIndex = -1;
309cdf0e10cSrcweir                             }
310cdf0e10cSrcweir                             else
311cdf0e10cSrcweir                             {
312cdf0e10cSrcweir                                 // not a pure shape target - maybe a
313cdf0e10cSrcweir                                 // ParagraphTarget?
314cdf0e10cSrcweir                                 presentation::ParagraphTarget aUnoTarget;
315cdf0e10cSrcweir 
316cdf0e10cSrcweir                                 if( !(xAnimateNode->getTarget() >>= aUnoTarget) )
317cdf0e10cSrcweir                                 {
318cdf0e10cSrcweir                                     OSL_ENSURE( false,
319cdf0e10cSrcweir                                                 "AnimCore: NodeFunctor::operator(): unknown target type encountered" );
320cdf0e10cSrcweir                                     break;
321cdf0e10cSrcweir                                 }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir                                 aTarget.mxRef = aUnoTarget.Shape;
324cdf0e10cSrcweir                                 aTarget.mnParagraphIndex = aUnoTarget.Paragraph;
325cdf0e10cSrcweir                             }
326cdf0e10cSrcweir                         }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir                         if( !aTarget.mxRef.is() )
329cdf0e10cSrcweir                         {
330cdf0e10cSrcweir                             OSL_ENSURE( false,
331cdf0e10cSrcweir                                         "AnimCore: NodeFunctor::operator(): Found target, but XShape is NULL" );
332cdf0e10cSrcweir                             break; // invalid target XShape
333cdf0e10cSrcweir                         }
334cdf0e10cSrcweir 
335cdf0e10cSrcweir                         // check whether we already have an entry for
336cdf0e10cSrcweir                         // this target (we only take the first set
337cdf0e10cSrcweir                         // effect for every shape)
338cdf0e10cSrcweir                         XShapeHash::const_iterator aIter;
339cdf0e10cSrcweir                         if( (aIter=mrShapeHash.find( aTarget )) != mrShapeHash.end() )
340cdf0e10cSrcweir                             break; // already an entry in existence for given XShape
341cdf0e10cSrcweir 
342cdf0e10cSrcweir                         // if this is an appear effect, hide shape
343cdf0e10cSrcweir                         // initially. This is currently the only place
344cdf0e10cSrcweir                         // where a shape effect influences shape
345cdf0e10cSrcweir                         // attributes outside it's effective duration.
3469584452cSAndre Fischer 			sal_Bool bVisible( sal_False );
347cdf0e10cSrcweir                         if( xAnimateNode->getAttributeName().equalsIgnoreAsciiCaseAscii("visibility") )
348cdf0e10cSrcweir                         {
349cdf0e10cSrcweir 
350cdf0e10cSrcweir                             uno::Any aAny( xAnimateNode->getTo() );
351cdf0e10cSrcweir 
352cdf0e10cSrcweir                             // try to extract bool value
353cdf0e10cSrcweir                             if( !(aAny >>= bVisible) )
354cdf0e10cSrcweir                             {
355cdf0e10cSrcweir                                 // try to extract string
356cdf0e10cSrcweir                                 ::rtl::OUString aString;
357cdf0e10cSrcweir                                 if( (aAny >>= aString) )
358cdf0e10cSrcweir                                 {
359cdf0e10cSrcweir                                     // we also take the strings "true" and "false",
360cdf0e10cSrcweir                                     // as well as "on" and "off" here
361cdf0e10cSrcweir                                     if( aString.equalsIgnoreAsciiCaseAscii("true") ||
362cdf0e10cSrcweir                                         aString.equalsIgnoreAsciiCaseAscii("on") )
363cdf0e10cSrcweir                                     {
364cdf0e10cSrcweir                                         bVisible = sal_True;
365cdf0e10cSrcweir                                     }
366cdf0e10cSrcweir                                     if( aString.equalsIgnoreAsciiCaseAscii("false") ||
367cdf0e10cSrcweir                                         aString.equalsIgnoreAsciiCaseAscii("off") )
368cdf0e10cSrcweir                                     {
369cdf0e10cSrcweir                                         bVisible = sal_False;
370cdf0e10cSrcweir                                     }
371cdf0e10cSrcweir                                 }
372cdf0e10cSrcweir                             }
373cdf0e10cSrcweir 
3749584452cSAndre Fischer                             /*if( bVisible )
375cdf0e10cSrcweir                             {
376cdf0e10cSrcweir                                 // target is set to 'visible' at the
377cdf0e10cSrcweir                                 // first relevant effect. Thus, target
378cdf0e10cSrcweir                                 // must be initially _hidden_, for the
379cdf0e10cSrcweir                                 // effect to have visible impact.
3809584452cSAndre Fischer                                 */
3819584452cSAndre Fischer 				}
3829584452cSAndre Fischer 						    // target is set the 'visible' value,
3839584452cSAndre Fischer 							// so we should record the opposite value
3849584452cSAndre Fischer 				mrShapeHash.insert(
385cdf0e10cSrcweir                                     XShapeHash::value_type(
386cdf0e10cSrcweir                                         aTarget,
387cdf0e10cSrcweir                                         VectorOfNamedValues(
388cdf0e10cSrcweir                                             1,
389cdf0e10cSrcweir                                             beans::NamedValue(
3909584452cSAndre Fischer                                                 //xAnimateNode->getAttributeName(),
3919584452cSAndre Fischer 						::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("visibility")),
3929584452cSAndre Fischer                                                 uno::makeAny( !bVisible ) ) ) ) );
3939584452cSAndre Fischer                             //}
3949584452cSAndre Fischer                         //}
395cdf0e10cSrcweir                     }
396cdf0e10cSrcweir                     break;
397cdf0e10cSrcweir                 }
398cdf0e10cSrcweir             }
399cdf0e10cSrcweir 
400cdf0e10cSrcweir         private:
401cdf0e10cSrcweir             XShapeHash& 						mrShapeHash;
402cdf0e10cSrcweir             uno::Reference< drawing::XShape > 	mxTargetShape;
403cdf0e10cSrcweir             sal_Int16							mnParagraphIndex;
404cdf0e10cSrcweir         };
405cdf0e10cSrcweir     }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 	// --------------------------------------------------------------------
408cdf0e10cSrcweir 
TargetPropertiesCreator(const uno::Reference<uno::XComponentContext> &)409cdf0e10cSrcweir     TargetPropertiesCreator::TargetPropertiesCreator( const uno::Reference< uno::XComponentContext >&  ) :
410cdf0e10cSrcweir         TargetPropertiesCreator_Base( m_aMutex )
411cdf0e10cSrcweir     {
412cdf0e10cSrcweir     }
413cdf0e10cSrcweir 
~TargetPropertiesCreator()414cdf0e10cSrcweir     TargetPropertiesCreator::~TargetPropertiesCreator()
415cdf0e10cSrcweir     {
416cdf0e10cSrcweir     }
417cdf0e10cSrcweir 
disposing()418cdf0e10cSrcweir 	void SAL_CALL TargetPropertiesCreator::disposing()
419cdf0e10cSrcweir 	{
420cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
421cdf0e10cSrcweir 	}
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     // XTargetPropertiesCreator
createInitialTargetProperties(const uno::Reference<animations::XAnimationNode> & xRootNode)424cdf0e10cSrcweir     uno::Sequence< animations::TargetProperties > SAL_CALL TargetPropertiesCreator::createInitialTargetProperties
425cdf0e10cSrcweir     	(
426cdf0e10cSrcweir             const uno::Reference< animations::XAnimationNode >& xRootNode
427cdf0e10cSrcweir         ) throw (uno::RuntimeException)
428cdf0e10cSrcweir     {
429cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
430cdf0e10cSrcweir 
431cdf0e10cSrcweir         // scan all nodes for visibility changes, and record first
432cdf0e10cSrcweir         // 'visibility=true' for each shape
433*8dd563e3SHerbert Dürr         XShapeHash aShapeHash( 101 );
434cdf0e10cSrcweir 
435cdf0e10cSrcweir         NodeFunctor aFunctor( aShapeHash );
436cdf0e10cSrcweir 
437cdf0e10cSrcweir         // TODO(F1): Maybe limit functor application to main sequence
438cdf0e10cSrcweir         // alone (CL said something that shape visibility is only
439cdf0e10cSrcweir         // affected by effects in the main sequence for PPT).
440cdf0e10cSrcweir         //
441cdf0e10cSrcweir         // OTOH, client code can pass us only the main sequence (which
442cdf0e10cSrcweir         // it actually does right now, for the slideshow implementation).
443cdf0e10cSrcweir         aFunctor( xRootNode );
444cdf0e10cSrcweir 
445cdf0e10cSrcweir 
446cdf0e10cSrcweir         // output to result sequence
447cdf0e10cSrcweir         // ----------------------------------------------------------------------
448cdf0e10cSrcweir 
449cdf0e10cSrcweir         uno::Sequence< animations::TargetProperties > aRes( aShapeHash.size() );
450cdf0e10cSrcweir 
451cdf0e10cSrcweir         ::std::size_t						nCurrIndex(0);
452cdf0e10cSrcweir         XShapeHash::const_iterator 			aCurr( aShapeHash.begin() );
453cdf0e10cSrcweir         const XShapeHash::const_iterator	aEnd ( aShapeHash.end()   );
454cdf0e10cSrcweir         while( aCurr != aEnd )
455cdf0e10cSrcweir         {
456cdf0e10cSrcweir             animations::TargetProperties& rCurrProps( aRes[ nCurrIndex++ ] );
457cdf0e10cSrcweir 
458cdf0e10cSrcweir             if( aCurr->first.mnParagraphIndex == -1 )
459cdf0e10cSrcweir             {
460cdf0e10cSrcweir                 rCurrProps.Target = uno::makeAny( aCurr->first.mxRef );
461cdf0e10cSrcweir             }
462cdf0e10cSrcweir             else
463cdf0e10cSrcweir             {
464cdf0e10cSrcweir                 rCurrProps.Target = uno::makeAny(
465cdf0e10cSrcweir                     presentation::ParagraphTarget(
466cdf0e10cSrcweir                         aCurr->first.mxRef,
467cdf0e10cSrcweir                         aCurr->first.mnParagraphIndex ) );
468cdf0e10cSrcweir             }
469cdf0e10cSrcweir 
470cdf0e10cSrcweir             rCurrProps.Properties = ::comphelper::containerToSequence( aCurr->second );
471cdf0e10cSrcweir 
472cdf0e10cSrcweir             ++aCurr;
473cdf0e10cSrcweir         }
474cdf0e10cSrcweir 
475cdf0e10cSrcweir         return aRes;
476cdf0e10cSrcweir     }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir     // XServiceInfo
getImplementationName()479cdf0e10cSrcweir     ::rtl::OUString SAL_CALL TargetPropertiesCreator::getImplementationName() throw( uno::RuntimeException )
480cdf0e10cSrcweir     {
481cdf0e10cSrcweir         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
482cdf0e10cSrcweir     }
483cdf0e10cSrcweir 
supportsService(const::rtl::OUString & ServiceName)484cdf0e10cSrcweir     sal_Bool SAL_CALL TargetPropertiesCreator::supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException )
485cdf0e10cSrcweir     {
486cdf0e10cSrcweir         return ServiceName.equalsIgnoreAsciiCaseAscii( SERVICE_NAME );
487cdf0e10cSrcweir     }
488cdf0e10cSrcweir 
getSupportedServiceNames()489cdf0e10cSrcweir     uno::Sequence< ::rtl::OUString > SAL_CALL TargetPropertiesCreator::getSupportedServiceNames()  throw( uno::RuntimeException )
490cdf0e10cSrcweir     {
491cdf0e10cSrcweir         uno::Sequence< ::rtl::OUString > aRet(1);
492cdf0e10cSrcweir         aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
493cdf0e10cSrcweir 
494cdf0e10cSrcweir         return aRet;
495cdf0e10cSrcweir     }
496cdf0e10cSrcweir 
497cdf0e10cSrcweir     // XServiceName
getServiceName()498cdf0e10cSrcweir     ::rtl::OUString SAL_CALL TargetPropertiesCreator::getServiceName(  ) throw (uno::RuntimeException)
499cdf0e10cSrcweir     {
500cdf0e10cSrcweir         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) );
501cdf0e10cSrcweir     }
502cdf0e10cSrcweir 
503cdf0e10cSrcweir } // namespace animcore
504