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