/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sd.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pptin.hxx" #include using ::std::map; using ::rtl::OUString; using ::rtl::OUStringBuffer; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::makeAny; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::XInterface; using ::com::sun::star::beans::NamedValue; using ::com::sun::star::container::XEnumerationAccess; using ::com::sun::star::container::XEnumeration; using ::com::sun::star::lang::XMultiServiceFactory; using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::animations; using namespace ::com::sun::star::presentation; namespace sd { extern Reference< XInterface > RandomAnimationNode_createInstance( sal_Int16 nPresetClass ); } namespace ppt { const transition* transition::find( const OUString& rName ) { const transition* p = gTransitions; while( p->mpName ) { if( rName.compareToAscii( p->mpName ) == 0 ) return p; p++; } return NULL; } // ==================================================================== // ==================================================================== SvStream& operator>>(SvStream& rIn, AnimationNode& rNode ) { rIn >> rNode.mnU1; rIn >> rNode.mnRestart; rIn >> rNode.mnGroupType; rIn >> rNode.mnFill; rIn >> rNode.mnU3; rIn >> rNode.mnU4; rIn >> rNode.mnDuration; rIn >> rNode.mnNodeType; return rIn; } // ==================================================================== static bool convertMeasure( OUString& rString ) { bool bRet = false; const sal_Char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", NULL }; const sal_Char* pDest[] = { "x", "y", "width", "height", NULL }; sal_Int32 nIndex = 0; const sal_Char** ps = pSource; const sal_Char** pd = pDest; while( *ps ) { const OUString aSearch( OUString::createFromAscii( *ps ) ); while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1 ) { sal_Int32 nLength = aSearch.getLength(); if( nIndex && (rString.getStr()[nIndex-1] == '#' ) ) { nIndex--; nLength++; } const OUString aNew( OUString::createFromAscii( *pd ) ); rString = rString.replaceAt( nIndex, nLength, aNew ); nIndex += aNew.getLength(); bRet = true; } ps++; pd++; } return bRet; } // ==================================================================== bool PropertySet::hasProperty( sal_Int32 nProperty ) const { return maProperties.find( nProperty ) != maProperties.end(); } // -------------------------------------------------------------------- Any PropertySet::getProperty( sal_Int32 nProperty ) const { PropertySetMap_t::const_iterator aIter( maProperties.find( nProperty ) ); if( aIter != maProperties.end() ) return (*aIter).second; else return Any(); } // ==================================================================== /** this adds an any to another any. if rNewValue is empty, rOldValue is returned. if rOldValue is empty, rNewValue is returned. if rOldValue contains a value, a sequence with rOldValue and rNewValue is returned. if rOldValue contains a sequence, a new sequence with the old sequence and rNewValue is returned. */ static Any addToSequence( const Any& rOldValue, const Any& rNewValue ) { if( !rNewValue.hasValue() ) { return rOldValue; } else if( !rOldValue.hasValue() ) { return rNewValue; } else { Sequence< Any > aNewSeq; if( rOldValue >>= aNewSeq ) { sal_Int32 nSize = aNewSeq.getLength(); aNewSeq.realloc(nSize+1); aNewSeq[nSize] = rNewValue; } else { aNewSeq.realloc(2); aNewSeq[0] = rOldValue; aNewSeq[1] = rNewValue; } return makeAny( aNewSeq ); } } // ==================================================================== AnimationImporter::AnimationImporter( ImplSdPPTImport* pPPTImport, SvStream& rStCtrl ) : mpPPTImport( pPPTImport ), mrStCtrl( rStCtrl ) { } // -------------------------------------------------------------------- void AnimationImporter::import( const Reference< XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd ) { #ifdef DBG_ANIM_LOG mpFile = fopen( "c:\\output.xml", "w+" ); #endif dump("\n"); Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY ); if( xNodeSupplier.is() ) { mxRootNode = xNodeSupplier->getAnimationNode(); if( mxRootNode.is() ) { Reference< XAnimationNode > xParent; const Atom* pAtom = Atom::import( rProgTagContentHd, mrStCtrl ); if( pAtom ) { importAnimationContainer( pAtom, xParent ); } processAfterEffectNodes(); } } #ifdef DBG_ANIM_LOG fclose( mpFile ); #endif } // -------------------------------------------------------------------- void AnimationImporter::processAfterEffectNodes() { std::for_each( maAfterEffectNodes.begin(), maAfterEffectNodes.end(), sd::stl_process_after_effect_node_func ); } // -------------------------------------------------------------------- Reference< XAnimationNode > AnimationImporter::createNode( const Atom* pAtom, const AnimationNode& rNode ) { const char* pServiceName = NULL; switch( rNode.mnGroupType ) { case mso_Anim_GroupType_PAR: if( pAtom->hasChildAtom( DFF_msofbtAnimIteration ) ) pServiceName = "com.sun.star.animations.IterateContainer"; else pServiceName = "com.sun.star.animations.ParallelTimeContainer"; break; case mso_Anim_GroupType_SEQ: pServiceName = "com.sun.star.animations.SequenceTimeContainer"; break; case mso_Anim_GroupType_NODE: { switch( rNode.mnNodeType ) { case mso_Anim_Behaviour_FILTER: case mso_Anim_Behaviour_ANIMATION: if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) ) pServiceName = "com.sun.star.animations.AnimateSet"; else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) ) pServiceName = "com.sun.star.animations.AnimateColor"; else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) ) pServiceName = "com.sun.star.animations.AnimateTransform"; else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) ) pServiceName = "com.sun.star.animations.AnimateTransform"; else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) ) pServiceName = "com.sun.star.animations.AnimateMotion"; else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) ) pServiceName = "com.sun.star.animations.TransitionFilter"; else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) pServiceName = "com.sun.star.animations.Command"; else pServiceName = "com.sun.star.animations.Animate"; break; } break; } case mso_Anim_GroupType_MEDIA: pServiceName = "com.sun.star.animations.Audio"; break; default: pServiceName = "com.sun.star.animations.Animate"; break; } Reference< XAnimationNode > xNode; if( pServiceName ) { const OUString aServiceName( OUString::createFromAscii(pServiceName) ); Reference< XInterface > xFac( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName) ); xNode.set(xFac , UNO_QUERY ); } DBG_ASSERT( xNode.is(), "sd::AnimationImporter::createNode(), node creation failed!" ); return xNode; } // -------------------------------------------------------------------- static bool is_random( const AnimationNode& rNode, const PropertySet& rSet, sal_Int32& rPresetClass ) { if( rNode.mnGroupType != mso_Anim_GroupType_PAR ) return false; if( !rSet.hasProperty( DFF_ANIM_PRESET_ID ) || !rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) ) return false; sal_Int32 nPresetId = 0; if( !(rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId) || (nPresetId != 24) ) return false; sal_Int32 nPresetClass = 0; if( !(rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass) ) return false; switch( nPresetClass ) { case DFF_ANIM_PRESS_CLASS_ENTRANCE: rPresetClass = EffectPresetClass::ENTRANCE; return true; case DFF_ANIM_PRESS_CLASS_EXIT: rPresetClass = EffectPresetClass::EXIT; return true; } return false; } void AnimationImporter::importAnimationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xParent ) { if( pAtom->seekToContent() ) { AnimationNode aNode; const Atom* pAnimationNodeAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimNode ); if( pAnimationNodeAtom && pAnimationNodeAtom->seekToContent() ) mrStCtrl >> aNode; PropertySet aSet; const Atom* pAnimationPropertySetAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimPropertySet ); if( pAnimationPropertySetAtom ) importPropertySetContainer( pAnimationPropertySetAtom, aSet ); Reference< XAnimationNode > xNode; if( xParent.is() ) { sal_Int32 nPresetClass; if( is_random( aNode, aSet, nPresetClass ) ) { // create a random animation node with the given preset class xNode.set( sd::RandomAnimationNode_createInstance( (sal_Int16)nPresetClass ), UNO_QUERY ); } if( !xNode.is() ) { // create a node for the given atom xNode = createNode( pAtom, aNode ); } } else { // if we have no parent we fill the root node xNode = mxRootNode; } // import if we have a node and its not random if( xNode.is() ) { fillNode( xNode, aNode, aSet ); switch( aNode.mnGroupType ) { case mso_Anim_GroupType_PAR: { dump( "\n" ); // for iteration containers, map target from childs to iteration Reference< XIterateContainer > xIter( xNode, UNO_QUERY ); if( xIter.is() ) { double fDuration = 0.0; Any aTarget, aEmpty; Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY ); if( xEnumerationAccess.is() ) { Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY ); if( xEnumeration.is() ) { while( xEnumeration->hasMoreElements() ) { Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY ); if( xChildNode.is() ) { double fChildBegin = 0.0; double fChildDuration = 0.0; xChildNode->getBegin() >>= fChildBegin; xChildNode->getDuration() >>= fChildDuration; fChildDuration += fChildBegin; if( fChildDuration > fDuration ) fDuration = fChildDuration; if( !aTarget.hasValue() ) aTarget = xChildNode->getTarget(); xChildNode->setTarget( aEmpty ); } } } } xIter->setTarget( aTarget ); double fIterateInterval = xIter->getIterateInterval() * fDuration / 100; xIter->setIterateInterval( fIterateInterval ); } } break; case mso_Anim_GroupType_SEQ: { dump( "\n" ); if( aSet.hasProperty( DFF_ANIM_NODE_TYPE ) ) { sal_Int32 nPPTNodeType = 0; if( aSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType ) { switch(nPPTNodeType) { case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: fixMainSequenceTiming( xNode ); break; case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ: fixInteractiveSequenceTiming( xNode ); break; } } } } break; case mso_Anim_GroupType_NODE: { #ifdef DBG_ANIM_LOG if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) ) { dump( "hasChildAtom( DFF_msofbtAnimateColor ) ) { dump( "hasChildAtom( DFF_msofbtAnimateScale ) ) { dump( "hasChildAtom( DFF_msofbtAnimateRotation ) ) { dump( "hasChildAtom( DFF_msofbtAnimateMotion ) ) { dump( "hasChildAtom( DFF_msofbtAnimate ) ) { dump( "hasChildAtom( DFF_msofbtAnimateFilter ) ) { dump( "hasChildAtom( DFF_msofbtAnimCommand ) ) { dump( "\n"); } break; case mso_Anim_GroupType_MEDIA: { dump( "\n" ); } break; default: OSL_FAIL( "unknown group atom!" ); dump_atom_header( pAtom, true, false ); dump_atom( pAtom ); dump_atom_header( pAtom, false, false ); break; } } if( xParent.is() && xNode.is() ) { Reference< XTimeContainer > xParentContainer( xParent, UNO_QUERY ); DBG_ASSERT( xParentContainer.is(), "parent is no container, then why do I have a child here?" ); if( xParentContainer.is() ) { xParentContainer->appendChild( xNode ); } } } } // -------------------------------------------------------------------- void AnimationImporter::fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) { try { bool bFirst = true; Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW ); Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW ); while( xE->hasMoreElements() ) { // click node Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY ); Event aEvent; aEvent.Trigger = EventTrigger::ON_NEXT; aEvent.Repeat = 0; xClickNode->setBegin( makeAny( aEvent ) ); if( bFirst ) { bFirst = false; Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW ); Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW ); if( xE2->hasMoreElements() ) { // with node xE2->nextElement() >>= xEA2; if( xEA2.is() ) xE2.query( xEA2->createEnumeration() ); else xE2.clear(); if( xE2.is() && xE2->hasMoreElements() ) { Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW ); const Sequence< NamedValue > aUserData( xEffectNode->getUserData() ); const NamedValue* p = aUserData.getConstArray(); sal_Int32 nLength = aUserData.getLength(); while( nLength-- ) { if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) ) { sal_Int16 nNodeType = 0; p->Value >>= nNodeType; if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK ) { // first effect does not start on click, so correct // first click nodes begin to 0s xClickNode->setBegin( makeAny( (double)0.0 ) ); break; } } p++; } } } } } } catch( Exception& e ) { (void)e; OSL_FAIL("sd::AnimationImporter::fixMainSequenceTiming(), exception caught!" ); } } // -------------------------------------------------------------------- void AnimationImporter::fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) { try { Any aBegin( xNode->getBegin() ); Any aEmpty; xNode->setBegin( aEmpty ); Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW ); Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW ); while( xE->hasMoreElements() ) { // click node Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY ); xClickNode->setBegin( aBegin ); } } catch( Exception& e ) { (void)e; OSL_FAIL("sd::AnimationImporter::fixInteractiveSequenceTiming(), exception caught!" ); } } // -------------------------------------------------------------------- bool AnimationImporter::convertAnimationNode( const Reference< XAnimationNode >& xNode, const Reference< XAnimationNode >& xParent ) { Reference< XAnimate > xAnimate( xNode, UNO_QUERY ); if( !xAnimate.is() ) return true; if( !xAnimate->getTarget().hasValue() ) return false; const sal_Int16 nNodeType = xNode->getType(); if( nNodeType == AnimationNodeType::TRANSITIONFILTER ) return true; OUString aAttributeName( xAnimate->getAttributeName() ); if( (nNodeType == AnimationNodeType::SET) && aAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "fill.on" ) ) ) return false; const ImplAttributeNameConversion* p = gImplConversionList; MS_AttributeNames eAttribute = MS_UNKNOWN; if( (nNodeType == AnimationNodeType::ANIMATEMOTION) || (nNodeType == AnimationNodeType::ANIMATETRANSFORM) ) { OUString aEmpty; aAttributeName = aEmpty; } else { while( p->mpMSName ) { if( aAttributeName.compareToAscii( p->mpMSName ) == 0 ) break; p++; } DBG_ASSERT( p->mpMSName || (aAttributeName.getLength() == 0), "sd::AnimationImporter::convertAnimationNode(), unknown attribute!" ); #ifdef DBG_ANIM_LOG if( p->mpMSName == 0 ) dump( "\n" ); #endif eAttribute = p->meAttribute; if( p->mpAPIName ) aAttributeName = OUString::createFromAscii( p->mpAPIName ); } xAnimate->setAttributeName( aAttributeName ); if( eAttribute != MS_UNKNOWN ) { Any aAny( xAnimate->getFrom() ); if( aAny.hasValue() ) { if( convertAnimationValue( eAttribute, aAny ) ) xAnimate->setFrom( aAny ); } aAny = xAnimate->getBy(); if( aAny.hasValue() ) { if( convertAnimationValue( eAttribute, aAny ) ) xAnimate->setBy( aAny ); } aAny = xAnimate->getTo(); if( aAny.hasValue() ) { if( convertAnimationValue( eAttribute, aAny ) ) xAnimate->setTo( aAny ); } Sequence< Any > aValues( xAnimate->getValues() ); sal_Int32 nValues = aValues.getLength(); if( nValues ) { Any* p2 = aValues.getArray(); while( nValues-- ) convertAnimationValue( eAttribute, *p2++ ); xAnimate->setValues( aValues ); } OUString aFormula( xAnimate->getFormula() ); if( aFormula.getLength() ) { if( convertMeasure( aFormula ) ) xAnimate->setFormula( aFormula ); } } // check for after-affect Sequence< NamedValue > aUserData( xNode->getUserData() ); NamedValue* pValue = aUserData.getArray(); NamedValue* pLastValue = pValue; sal_Int32 nLength = aUserData.getLength(), nRemoved = 0; sal_Bool bAfterEffect = false; sal_Int32 nMasterRel = 0; for( ; nLength--; pValue++ ) { if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("after-effect") ) ) { pValue->Value >>= bAfterEffect; nRemoved++; } else if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("master-rel") ) ) { pValue->Value >>= nMasterRel; nRemoved++; } else { if( nRemoved ) *pLastValue = *pValue; pLastValue++; } } if( nRemoved ) { aUserData.realloc( aUserData.getLength() - nRemoved ); xNode->setUserData( aUserData ); } // if its an after effect node, add it to the list for // later processing // after effect nodes are not inserted at their import // position, so return false in this case if( bAfterEffect ) { if( nMasterRel != 2 ) { Event aEvent; aEvent.Source <<= xParent; aEvent.Trigger = EventTrigger::END_EVENT; aEvent.Repeat = 0; xNode->setBegin( makeAny( aEvent ) ); } // add to after effect nodes for later processing sd::AfterEffectNode aNode( xNode, xParent, nMasterRel == 2 ); maAfterEffectNodes.push_back( aNode ); return false; } return true; } static int lcl_gethex( int nChar ) { if( nChar >= '0' && nChar <= '9' ) return nChar - '0'; else if( nChar >= 'a' && nChar <= 'f' ) return nChar - 'a' + 10; else if( nChar >= 'A' && nChar <= 'F' ) return nChar - 'A' + 10; else return 0; } bool AnimationImporter::convertAnimationValue( MS_AttributeNames eAttribute, Any& rValue ) { bool bRet = false; switch( eAttribute ) { case MS_PPT_X: case MS_PPT_Y: case MS_PPT_W: case MS_PPT_H: { OUString aString; if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) ) { ValuePair aValuePair; if( rValue >>= aValuePair ) { if( aValuePair.First >>= aString ) { if( convertMeasure( aString ) ) { aValuePair.First <<= aString; bRet = true; } } if( aValuePair.Second >>= aString ) { if( convertMeasure( aString ) ) { aValuePair.Second <<= aString; bRet = true; } } } } else if( rValue.getValueType() == ::getCppuType((const OUString*)0) ) { if( rValue >>= aString ) { bRet = convertMeasure( aString ); if( bRet ) rValue <<= aString; } } } break; case MS_XSHEAR: case MS_R: { OUString aString; if( rValue >>= aString ) { rValue <<= aString.toDouble(); bRet = true; } } break; case MS_STYLEROTATION: { if( rValue.getValueType() == ::getCppuType((const OUString*)0) ) { OUString aString; rValue >>= aString; rValue <<= (sal_Int16)aString.toDouble(); bRet = true; } else if( rValue.getValueType() == ::getCppuType((const double*)0) ) { double fValue = 0.0; rValue >>= fValue; rValue <<= (sal_Int16)fValue; bRet = true; } } break; case MS_FILLCOLOR: case MS_STROKECOLOR: case MS_STYLECOLOR: case MS_PPT_C: { OUString aString; if( rValue >>= aString ) { if( aString.getLength() >= 7 && aString[0] == '#' ) { Color aColor; aColor.SetRed( (sal_uInt8)(lcl_gethex( aString[1] ) * 16 + lcl_gethex( aString[2] )) ); aColor.SetGreen( (sal_uInt8)(lcl_gethex( aString[3] ) * 16 + lcl_gethex( aString[4] )) ); aColor.SetBlue( (sal_uInt8)(lcl_gethex( aString[5] ) * 16 + lcl_gethex( aString[6] )) ); rValue <<= (sal_Int32)aColor.GetColor(); bRet = true; } else if( aString.matchAsciiL( "rgb(", 4, 0 ) ) { aString = aString.copy( 4, aString.getLength() - 5 ); Color aColor; sal_Int32 index = 0; aColor.SetRed( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); aColor.SetGreen( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); aColor.SetRed( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); rValue <<= (sal_Int32)aColor.GetColor(); bRet = true; } else if( aString.matchAsciiL( "hsl(", 4, 0 ) ) { sal_Int32 index = 0; sal_Int32 nA = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); sal_Int32 nB = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); sal_Int32 nC = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); dump( "hsl(%ld", nA ); dump( ",%ld", nB ); dump( ",%ld)", nC ); Sequence< double > aHSL( 3 ); aHSL[0] = nA * 360.0/255.0; aHSL[1] = nB / 255.0; aHSL[2] = nC / 255.0; rValue <<= aHSL; bRet = true; } } } break; case MS_FILLTYPE: { OUString aString; if( rValue >>= aString ) { rValue <<= aString.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "solid" ) ) ? FillStyle_SOLID : FillStyle_NONE; bRet = true; } } break; case MS_STROKEON: { OUString aString; if( rValue >>= aString ) { rValue <<= aString.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "true" ) ) ? ::com::sun::star::drawing::LineStyle_SOLID : ::com::sun::star::drawing::LineStyle_NONE; bRet = true; } } break; case MS_FONTWEIGHT: { OUString aString; if( rValue >>= aString ) { rValue <<= aString.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "bold" ) ) ? com::sun::star::awt::FontWeight::BOLD : com::sun::star::awt::FontWeight::NORMAL; bRet = true; } } break; case MS_STYLEFONTSTYLE: { OUString aString; if( rValue >>= aString ) { rValue <<= aString.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "italic" ) ) ? com::sun::star::awt::FontSlant_ITALIC : com::sun::star::awt::FontSlant_NONE; bRet = true; } } break; case MS_STYLEUNDERLINE: { OUString aString; if( rValue >>= aString ) { rValue <<= aString.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "true" ) ) ? com::sun::star::awt::FontUnderline::SINGLE : com::sun::star::awt::FontUnderline::NONE; bRet = true; } } break; case MS_STYLEOPACITY: case MS_STYLEFONTSIZE: { OUString aString; if( rValue >>= aString ) { rValue <<= (float)aString.toDouble(); bRet = true; } } break; case MS_STYLEVISIBILITY: { OUString aString; if( rValue >>= aString ) { rValue <<= aString.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "visible" ) ) ? sal_True : sal_False; bRet = true; } } break; default: break; } return bRet; } // -------------------------------------------------------------------- static OUString getConvertedSubType( sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType ) { const sal_Char* pStr = 0; if( (nPresetClass == EffectPresetClass::ENTRANCE) || (nPresetClass == EffectPresetClass::EXIT) ) { // skip wheel effect if( nPresetId != 21 ) { if( nPresetId == 5 ) { // checkerboard switch( nPresetSubType ) { case 5: pStr = "downward"; break; case 10: pStr = "across"; break; } } else if( nPresetId == 17 ) { // stretch if( nPresetSubType == 10 ) pStr = "across"; } else if( nPresetId == 18 ) { // strips switch( nPresetSubType ) { case 3: pStr = "right-to-top"; break; case 6: pStr = "right-to-bottom"; break; case 9: pStr = "left-to-top"; break; case 12: pStr = "left-to-bottom"; break; } } if( pStr == 0 ) { const convert_subtype* p = gConvertArray; while( p->mpStrSubType ) { if( p->mnID == nPresetSubType ) { pStr = p->mpStrSubType; break; } p++; } } } } if( pStr ) return OUString::createFromAscii( pStr ); else return OUString::valueOf( nPresetSubType ); } // -------------------------------------------------------------------- void AnimationImporter::fillNode( Reference< XAnimationNode >& xNode, const AnimationNode& rNode, const PropertySet& rSet ) { sal_Bool bAfterEffect = false; // attribute Restart if( rNode.mnRestart ) { sal_Int16 nRestart = AnimationRestart::DEFAULT; switch( rNode.mnRestart ) { case 1: nRestart = AnimationRestart::ALWAYS; break; case 2: nRestart = AnimationRestart::WHEN_NOT_ACTIVE; break; case 3: nRestart = AnimationRestart::NEVER; break; } xNode->setRestart( nRestart ); } // attribute Fill if( rNode.mnFill ) { sal_Int16 nFill = AnimationFill::DEFAULT; switch( rNode.mnFill ) { case 1: nFill = AnimationFill::REMOVE; break; case 2: nFill = AnimationFill::FREEZE; break; case 3: nFill = AnimationFill::HOLD; break; case 4: nFill = AnimationFill::TRANSITION; break; } xNode->setFill( nFill ); } // attribute Duration if( rNode.mnDuration ) { Any aDuration; if( rNode.mnDuration > 0 ) { aDuration <<= (double)(rNode.mnDuration / 1000.0); } else if( rNode.mnDuration < 0 ) { aDuration <<= Timing_INDEFINITE; } xNode->setDuration( aDuration ); } // TODO: DFF_ANIM_PATH_EDIT_MODE if( rSet.hasProperty( DFF_ANIM_PATH_EDIT_MODE ) ) { sal_Int32 nPathEditMode ; if( rSet.getProperty( DFF_ANIM_PATH_EDIT_MODE ) >>= nPathEditMode ) { } } // set user data Sequence< NamedValue > aUserData; // attribute Type if( rSet.hasProperty( DFF_ANIM_NODE_TYPE ) ) { sal_Int32 nPPTNodeType = 0; if( rSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType ) { sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT; switch( nPPTNodeType ) { case DFF_ANIM_NODE_TYPE_ON_CLICK: nNodeType = ::com::sun::star::presentation::EffectNodeType::ON_CLICK; break; case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS; break; case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS; break; case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: nNodeType = ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE; break; case DFF_ANIM_NODE_TYPE_TIMING_ROOT: nNodeType = ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT; break; case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:nNodeType = ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE; break; } sal_Int32 nSize = aUserData.getLength(); aUserData.realloc(nSize+1); aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) ); aUserData[nSize].Value <<= nNodeType; } } if( rSet.hasProperty( DFF_ANIM_GROUP_ID ) ) { sal_Int32 nGroupId; if( rSet.getProperty( DFF_ANIM_GROUP_ID ) >>= nGroupId ) { sal_Int32 nSize = aUserData.getLength(); aUserData.realloc(nSize+1); aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "group-id" ) ); aUserData[nSize].Value <<= nGroupId; } } sal_Int16 nEffectPresetClass = EffectPresetClass::CUSTOM; sal_Int32 nPresetId = 0; if( rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) ) { sal_Int32 nPresetClass = 0; if ( rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass ) { switch( nPresetClass ) { case DFF_ANIM_PRESS_CLASS_ENTRANCE: nEffectPresetClass = EffectPresetClass::ENTRANCE; break; case DFF_ANIM_PRESS_CLASS_EXIT: nEffectPresetClass = EffectPresetClass::EXIT; break; case DFF_ANIM_PRESS_CLASS_EMPHASIS: nEffectPresetClass = EffectPresetClass::EMPHASIS; break; case DFF_ANIM_PRESS_CLASS_MOTIONPATH: nEffectPresetClass = EffectPresetClass::MOTIONPATH; break; case DFF_ANIM_PRESS_CLASS_OLE_ACTION: nEffectPresetClass = EffectPresetClass::OLEACTION; break; case DFF_ANIM_PRESS_CLASS_MEDIACALL: nEffectPresetClass = EffectPresetClass::MEDIACALL; break; } sal_Int32 nSize = aUserData.getLength(); aUserData.realloc(nSize+1); aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-class" ) ); aUserData[nSize].Value <<= nEffectPresetClass; } } if( rSet.hasProperty( DFF_ANIM_PRESET_ID ) ) { if( rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId ) { sal_Int32 nSize = aUserData.getLength(); aUserData.realloc(nSize+1); aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-id" ) ); const preset_maping* p = gPresetMaping; while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) ) p++; if( p->mpStrPresetId ) { aUserData[nSize].Value <<= OUString::createFromAscii( p->mpStrPresetId ); } else { OUStringBuffer sBuffer; sBuffer.appendAscii( "ppt_" ); switch( nEffectPresetClass ) { case EffectPresetClass::ENTRANCE: sBuffer.appendAscii( "entrance_" ); break; case EffectPresetClass::EXIT: sBuffer.appendAscii( "exit_" ); break; case EffectPresetClass::EMPHASIS: sBuffer.appendAscii( "emphasis_" ); break; case EffectPresetClass::MOTIONPATH: sBuffer.appendAscii( "motionpath_" ); break; case EffectPresetClass::OLEACTION: sBuffer.appendAscii( "oleaction_" ); break; case EffectPresetClass::MEDIACALL: sBuffer.appendAscii( "mediacall_" ); break; } sBuffer.append( nPresetId ); aUserData[nSize].Value <<= sBuffer.makeStringAndClear(); } } } if( rSet.hasProperty( DFF_ANIM_PRESET_SUB_TYPE ) ) { sal_Int32 nPresetSubType = 0; if( (rSet.getProperty( DFF_ANIM_PRESET_SUB_TYPE ) >>= nPresetSubType) ) { if( nPresetSubType ) { sal_Int32 nSize = aUserData.getLength(); aUserData.realloc(nSize+1); aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-sub-type" ) ); aUserData[nSize].Value <<= getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType ); } } } if( rSet.hasProperty( DFF_ANIM_AFTEREFFECT ) ) { if( rSet.getProperty( DFF_ANIM_AFTEREFFECT ) >>= bAfterEffect ) { sal_Int32 nSize = aUserData.getLength(); aUserData.realloc(nSize+1); aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "after-effect" ) ); aUserData[nSize].Value <<= bAfterEffect; } } if( bAfterEffect && rSet.hasProperty( DFF_ANIM_MASTERREL ) ) { sal_Int32 nMasterRel = 2; if( rSet.getProperty( DFF_ANIM_MASTERREL ) >>= nMasterRel ) { sal_Int32 nSize = aUserData.getLength(); aUserData.realloc(nSize+1); aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "master-rel" ) ); aUserData[nSize].Value <<= nMasterRel; } } xNode->setUserData( aUserData ); // TODO: DFF_ANIM_ID if( rSet.hasProperty( DFF_ANIM_ID ) ) { rtl::OUString aString; rSet.getProperty( DFF_ANIM_ID ) >>= aString; if( aString.getLength() ) { } } // TODO: DFF_ANIM_EVENT_FILTER if( rSet.hasProperty( DFF_ANIM_EVENT_FILTER ) ) { rtl::OUString aString; rSet.getProperty( DFF_ANIM_EVENT_FILTER ) >>= aString; if( aString.getLength() ) { } } // DFF_ANIM_TIMEFILTER if( rSet.hasProperty( DFF_ANIM_TIMEFILTER ) ) { Reference< XAnimate > xAnim( xNode, UNO_QUERY ); if( xAnim.is() ) { rtl::OUString aString; rSet.getProperty( DFF_ANIM_TIMEFILTER ) >>= aString; if( aString.getLength() ) { sal_Int32 nElements = 1; // a non empty string has at least one value sal_Int32 fromIndex = 0; while(true) { fromIndex = aString.indexOf( (sal_Unicode)';', fromIndex ); if( fromIndex == -1 ) break; fromIndex++; nElements++; } Sequence< TimeFilterPair > aTimeFilter( nElements ); TimeFilterPair* pValues = aTimeFilter.getArray(); sal_Int32 nIndex = 0; while( (nElements--) && (nIndex >= 0) ) { const OUString aToken( aString.getToken( 0, ';', nIndex ) ); sal_Int32 nPos = aToken.indexOf( ',' ); if( nPos >= 0 ) { pValues->Time = aToken.copy( 0, nPos ).toDouble(); pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble(); } pValues++; } xAnim->setTimeFilter( aTimeFilter ); } } } // TODO: DFF_ANIM_ENDAFTERSLIDE / DFF_ANIM_VOLUME handling. git history has sample code Reference< XAnimateColor > xColor( xNode, UNO_QUERY ); if( xColor.is() ) { if( rSet.hasProperty( DFF_ANIM_DIRECTION ) ) { sal_Bool bDirection = sal_False; if( rSet.getProperty( DFF_ANIM_DIRECTION ) >>= bDirection ) xColor->setDirection( (sal_Bool)!bDirection ); } if( rSet.hasProperty( DFF_ANIM_COLORSPACE ) ) { sal_Int32 nColorSpace = 0; rSet.getProperty( DFF_ANIM_COLORSPACE ) >>= nColorSpace; xColor->setColorInterpolation( (nColorSpace == 0) ? AnimationColorSpace::RGB : AnimationColorSpace::HSL ); } } } // -------------------------------------------------------------------- void AnimationImporter::importTimeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!"); if( pAtom && xNode.is() ) { importAnimationEvents( pAtom, xNode ); importAnimationValues( pAtom, xNode ); importAnimationActions( pAtom, xNode ); dump(">\n"); // import sub containers const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { switch( pChildAtom->getType() ) { case DFF_msofbtAnimNode: case DFF_msofbtAnimEvent: case DFF_msofbtAnimValue: case DFF_msofbtAnimAction: case DFF_msofbtAnimPropertySet: break; case DFF_msofbtAnimSubGoup : { if( pChildAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) { const OUString aServiceName( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.Command")) ); Reference< XAnimationNode > xChildNode( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY ); importAnimationNodeContainer( pChildAtom, xChildNode ); Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY ); if( xParentContainer.is() && xChildNode.is() ) xParentContainer->appendChild( xChildNode ); } else { importAnimationContainer( pChildAtom, xNode ); } } break; case DFF_msofbtAnimGroup : { importAnimationContainer( pChildAtom, xNode ); } break; case DFF_msofbtAnimIteration: { if( pChildAtom->seekToContent() ) { float fInterval; sal_Int32 nTextUnitEffect, nU1, nU2, nU3; mrStCtrl >> fInterval >> nTextUnitEffect >> nU1 >> nU2 >> nU3; Reference< XIterateContainer > xIter( xNode, UNO_QUERY ); if( xIter.is() ) { sal_Int16 nIterateType = TextAnimationType::BY_PARAGRAPH; switch( nTextUnitEffect ) { case 1: nIterateType = TextAnimationType::BY_WORD; break; case 2: nIterateType = TextAnimationType::BY_LETTER; break; } xIter->setIterateType( nIterateType ); xIter->setIterateInterval( (double)fInterval ); } dump( "\n", nU3 ); } } break; case 0xf136: { #ifdef DBG_ANIM_LOG sal_uInt32 nU1, nU2; mrStCtrl >> nU1 >> nU2; fprintf( mpFile, "\n", nU1, nU2 ); #endif } break; default: { dump_atom_header( pChildAtom, true, false ); dump_atom( pChildAtom ); dump_atom_header( pChildAtom, false, false ); } break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importAnimationNodeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationNodeContainer()!"); if( pAtom && xNode.is() ) { importAnimationEvents( pAtom, xNode ); importAnimationValues( pAtom, xNode ); importAnimationActions( pAtom, xNode ); const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { switch( pChildAtom->getType() ) { case DFF_msofbtAnimNode: case DFF_msofbtAnimEvent: case DFF_msofbtAnimValue: case DFF_msofbtAnimAction: case DFF_msofbtAnimPropertySet: break; case DFF_msofbtAnimateFilter: importAnimateFilterContainer( pChildAtom, xNode ); break; case DFF_msofbtAnimateSet: importAnimateSetContainer( pChildAtom, xNode ); break; case DFF_msofbtAnimate: importAnimateContainer( pChildAtom, xNode ); break; case DFF_msofbtAnimateScale: importAnimateScaleContainer( pChildAtom, xNode ); break; case DFF_msofbtAnimateColor: importAnimateColorContainer( pChildAtom, xNode ); break; case DFF_msofbtAnimateRotation: importAnimateRotationContainer( pChildAtom, xNode ); break; case DFF_msofbtAnimateMotion: importAnimateMotionContainer( pChildAtom, xNode ); break; case DFF_msofbtAnimCommand: importCommandContainer( pChildAtom, xNode ); break; default: { dump_atom_header( pChildAtom, true, false ); dump_atom( pChildAtom ); dump_atom_header( pChildAtom, false, false ); } break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importAnimateFilterContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateFilter && xFilter.is(), "invalid call to ppt::AnimationImporter::importAnimateFilterContainer()!"); if( pAtom && xFilter.is() ) { sal_uInt32 nBits = 0; const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimateFilterData: { sal_uInt32 transition; mrStCtrl >> nBits; mrStCtrl >> transition; if( nBits & 1 ) xFilter->setMode( transition == 0 ); dump( " transition=\"%s\"", (transition == 0) ? "in" : "out" ); } break; case DFF_msofbtAnimAttributeValue: { if( (nBits & 2 ) && ( pChildAtom->getInstance() == 1 ) ) { Any aAny; if ( importAttributeValue( pChildAtom, aAny ) ) { rtl::OUString filter; aAny >>= filter; dump( " filter=\"%s\"", filter ); const transition* pTransition = transition::find( filter ); if( pTransition ) { xFilter->setTransition( pTransition->mnType ); xFilter->setSubtype( pTransition->mnSubType ); xFilter->setDirection( pTransition->mbDirection ); } else { OSL_FAIL( "unknown transition!" ); } } } } break; case DFF_msofbtAnimateTarget: importAnimateAttributeTargetContainer( pChildAtom, xNode ); break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importAnimateAttributeTargetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateTarget, "invalid call to ppt::AnimationImporter::importAnimateAttributeTargetContainer()!"); Any aTarget; Reference< XAnimate > xAnimate( xNode, UNO_QUERY ); bool bWrongContext = false; if( pAtom ) { const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimPropertySet: { PropertySet aSet; importPropertySetContainer( pChildAtom, aSet ); if( aSet.hasProperty( DFF_ANIM_RUNTIMECONTEXT ) ) { OUString aContext; if( aSet.getProperty( DFF_ANIM_RUNTIMECONTEXT ) >>= aContext ) { if( !aContext.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("PPT") ) ) bWrongContext = true; } } dump( aSet ); } break; case DFF_msofbtAnimateTargetSettings: { if( xAnimate.is() ) { sal_uInt32 nBits; sal_uInt32 nAdditive; sal_uInt32 nAccumulate; sal_uInt32 nTransformType; mrStCtrl >> nBits >> nAdditive >> nAccumulate >> nTransformType; // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none // nAccumulate 0 = none, 1 = always // nTransformType 0: "property" else "image" if( nBits & 3 ) { if( xAnimate.is() ) { if( nBits & 1 ) { sal_Int16 nTemp = AnimationAdditiveMode::BASE; switch( nAdditive ) { case 1: nTemp = AnimationAdditiveMode::SUM; break; case 2: nTemp = AnimationAdditiveMode::REPLACE; break; case 3: nTemp = AnimationAdditiveMode::MULTIPLY; break; case 4: nTemp = AnimationAdditiveMode::NONE; break; } xAnimate->setAdditive( nTemp ); } if( nBits & 2 ) { xAnimate->setAccumulate( (nAccumulate == 0) ? sal_True : sal_False ); } } } #ifdef DBG_ANIM_LOG if( nBits & 1 ) fprintf( mpFile, " additive=\"%s\"", (nAdditive == 0) ? "base" : (nAdditive == 2) ? "replace" : (nAdditive == 1) ? "sum" : (nAdditive == 3 ) ? "multiply" : (nAdditive == 4) ? "none" : "unknown" ); if( nBits & 2 ) fprintf( mpFile, " accumulate=\"%s\"", (nAccumulate == 0) ? "none" : "always" ); if( nBits & 8 ) fprintf( mpFile, " transformType=\"%s\"", (nTransformType == 0) ? "property" : "image" ); #endif } } break; case DFF_msofbtAnimateAttributeNames: { if( xAnimate.is() ) { OUString aAttributeName; importAttributeNamesContainer( pChildAtom, aAttributeName ); if( xAnimate.is() ) xAnimate->setAttributeName( aAttributeName ); dump( " attributeName=\"%s\"", aAttributeName ); } } break; case DFF_msofbtAnimateTargetElement: { sal_Int16 nSubType; importTargetElementContainer( pChildAtom, aTarget, nSubType ); if( xAnimate.is() ) xAnimate->setSubItem( nSubType ); dump( " target=\"" ); dump_target( aTarget ); dump( "\"" ); } break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } if( bWrongContext ) aTarget.clear(); if( xAnimate.is() ) xAnimate->setTarget( aTarget ); else { Reference< XCommand > xCommand( xNode, UNO_QUERY ); if( xCommand.is() ) xCommand->setTarget( aTarget ); } } // -------------------------------------------------------------------- sal_Int16 AnimationImporter::implGetColorSpace( sal_Int32 nMode, sal_Int32 /*nA*/, sal_Int32 /*nB*/, sal_Int32 /*nC*/ ) { switch( nMode ) { case 2: // index // FALLTHROUGH intended default: // FALLTHROUGH intended case 0: // rgb return AnimationColorSpace::RGB; case 1: // hsl return AnimationColorSpace::HSL; } } // -------------------------------------------------------------------- Any AnimationImporter::implGetColorAny( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC ) { switch( nMode ) { case 0: // rgb { dump( "rgb(%ld", nA ); dump( ",%ld", nB ); dump( ",%ld)", nC ); Color aColor( (sal_uInt8)nA, (sal_uInt8)nB, (sal_uInt8)nC ); return makeAny( (sal_Int32)aColor.GetRGBColor() ); } case 1: // hsl { dump( "hsl(%ld", nA ); dump( ",%ld", nB ); dump( ",%ld)", nC ); Sequence< double > aHSL( 3 ); aHSL[0] = nA * 360.0/255.0; aHSL[1] = nB / 255.0; aHSL[2] = nC / 255.0; return makeAny( aHSL ); } case 2: // index { Color aColor; mpPPTImport->GetColorFromPalette((sal_uInt16)nA, aColor ); dump( "index(%ld", nA ); dump( " [%ld", (sal_Int32)aColor.GetRed() ); dump( ",%ld", (sal_Int32)aColor.GetGreen() ); dump( ",%ld])", (sal_Int32)aColor.GetBlue() ); return makeAny( (sal_Int32)aColor.GetRGBColor() ); } default: { dump( "unknown_%ld(", nMode ); dump( "%ld", nA ); dump( ",%ld", nB ); dump( ",%ld)", nC ); OSL_FAIL( "ppt::implGetColorAny(), unhandled color type" ); Any aAny; return aAny; } } } void AnimationImporter::importAnimateColorContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XAnimateColor > xColor( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateColor && xColor.is(), "invalid call to ppt::AnimationImporter::importAnimateColorContainer()!"); if( pAtom && xColor.is() ) { const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimateColorData: { sal_uInt32 nBits; sal_Int32 nByMode, nByA, nByB, nByC; sal_Int32 nFromMode, nFromA, nFromB, nFromC; sal_Int32 nToMode, nToA, nToB, nToC; mrStCtrl >> nBits; mrStCtrl >> nByMode >> nByA >> nByB >> nByC; mrStCtrl >> nFromMode >> nFromA >> nFromB >> nFromC; mrStCtrl >> nToMode >> nToA >> nToB >> nToC; if( nBits & 1 ) { dump( " by=\"" ); xColor->setBy( implGetColorAny( nByMode, nByA, nByB, nByC ) ); xColor->setColorInterpolation( implGetColorSpace( nByMode, nByA, nByB, nByC ) ); dump( "\""); } if( nBits & 2 ) { dump( " from=\"" ); xColor->setFrom( implGetColorAny( nFromMode, nFromA, nFromB, nFromC ) ); xColor->setColorInterpolation( implGetColorSpace( nFromMode, nFromA, nFromB, nFromC ) ); dump( "\""); } if( nBits & 4 ) { dump( " to=\"" ); xColor->setTo( implGetColorAny( nToMode, nToA, nToB, nToC ) ); xColor->setColorInterpolation( implGetColorSpace( nToMode, nToA, nToB, nToC ) ); dump( "\""); } } break; case DFF_msofbtAnimateTarget: importAnimateAttributeTargetContainer( pChildAtom, xNode ); break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importAnimateSetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XAnimateSet > xSet( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateSet && xSet.is(), "invalid call to ppt::AnimationImporter::importAnimateSetContainer()!"); if( pAtom && xSet.is() ) { const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimateSetData: { sal_Int32 nU1, nU2; mrStCtrl >> nU1 >> nU2; dump( " set_1=\"%ld\"", nU1 ), dump( " set_2=\"%ld\"", nU2 ); } break; case DFF_msofbtAnimAttributeValue: { Any aTo; if ( importAttributeValue( pChildAtom, aTo ) ) { xSet->setTo( aTo ); dump( " value=\"" ); dump( aTo ); dump( "\"" ); } } break; case DFF_msofbtAnimateTarget: importAnimateAttributeTargetContainer( pChildAtom, xNode ); break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importAnimateContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XAnimate > xAnim( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimate && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateContainer()!"); if( pAtom && xAnim.is() ) { const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimateData: { sal_uInt32 nCalcmode, nBits, nValueType; mrStCtrl >> nCalcmode >> nBits >> nValueType; if( nBits & 0x08 ) { sal_Int16 n = (nCalcmode == 1) ? AnimationCalcMode::LINEAR : /* (nCalcmode == 2) ? AnimationCalcMode::FORMULA : */ AnimationCalcMode::DISCRETE; xAnim->setCalcMode( n ); dump( " calcmode=\"%s\"", (nCalcmode == 0) ? "discrete" : (nCalcmode == 1) ? "linear" : (nCalcmode == 2) ? "formula" : "unknown" ); } if( nBits & 0x30 ) { sal_Int16 n = (nValueType == 1) ? AnimationValueType::NUMBER : (nValueType == 2 ) ? AnimationValueType::COLOR : AnimationValueType::STRING; xAnim->setValueType( n ); dump( " valueType=\"%s\"", (nValueType == 0) ? "string" : (nValueType == 1) ? "number" : (nValueType == 2) ? "color" : "unknown" ); } } break; case DFF_msofbtAnimateTarget: importAnimateAttributeTargetContainer( pChildAtom, xNode ); break; case DFF_msofbtAnimKeyPoints: importAnimateKeyPoints( pChildAtom, xNode ); break; case DFF_msofbtAnimAttributeValue: { Any a; if ( importAttributeValue( pChildAtom, a ) ) { switch( pChildAtom->getInstance() ) { case 1: xAnim->setBy( a ); dump( " by=\"" ); break; case 2: xAnim->setFrom( a ); dump( " from=\"" ); break; case 3: xAnim->setTo( a ); dump( " to=\"" ); break; default: dump( " unknown_value=\"" ); } dump( a ); dump( "\"" ); } } break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importAnimateMotionContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateMotion && xMotion.is(), "invalid call to ppt::AnimationImporter::importAnimateMotionContainer()!"); if( pAtom && xMotion.is() ) { const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimateMotionData: { sal_uInt32 nBits, nOrigin; float fByX, fByY, fFromX, fFromY, fToX, fToY; mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nOrigin; #ifdef DBG_ANIM_LOG if( nBits & 1 ) fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY ); if( nBits & 2 ) fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY ); if( nBits & 4 ) fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY ); if( nBits & 8 ) fprintf( mpFile, " origin=\"%s\"", (nOrigin == 1) ? "parent" : (nOrigin == 2) ? "layout" : "unknown" ); #endif } break; case DFF_msofbtAnimAttributeValue: { Any aPath; if ( importAttributeValue( pChildAtom, aPath ) ) { rtl::OUString aStr; if ( aPath >>= aStr ) { aStr = aStr.replace( 'E', ' ' ); aStr = aStr.trim(); aPath <<= aStr; xMotion->setPath( aPath ); dump( " path=\"" ); dump( aPath ); dump( "\"" ); } } } break; case DFF_msofbtAnimateTarget: importAnimateAttributeTargetContainer( pChildAtom, xNode ); break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importCommandContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XCommand > xCommand( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimCommand && xCommand.is(), "invalid call to ppt::AnimationImporter::importCommandContainer()!"); if( pAtom && xCommand.is() ) { sal_Int32 nBits = 0, nType = 0; Any aValue; const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtCommandData: { sal_Int32 nCommandType; // looks like U1 is a bitset, bit 1 enables the type and bit 2 enables // a propertyvalue that follows mrStCtrl >> nBits; mrStCtrl >> nCommandType; if( nBits && 1 ) { dump( " type=\"%s\"", (nCommandType == 0) ? "event" : ( nCommandType == 1) ? "call" : "verb" ); } } break; case DFF_msofbtAnimAttributeValue: { if ( importAttributeValue( pChildAtom, aValue ) ) { if( nBits && 2 ) { dump( " cmd=\"" ); dump( aValue ); dump( "\"" ); } } } break; case DFF_msofbtAnimateTarget: importAnimateAttributeTargetContainer( pChildAtom, xNode ); break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } if( nBits & 3 ) { OUString aParam; aValue >>= aParam; sal_Int16 nCommand = EffectCommands::CUSTOM; NamedValue aParamValue; switch( nType ) { case 0: // event case 1: // call if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "onstopaudio" ) ) ) { nCommand = EffectCommands::STOPAUDIO; } else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("play") ) ) { nCommand = EffectCommands::PLAY; } else if( aParam.compareToAscii( RTL_CONSTASCII_STRINGPARAM("playFrom") ) == 0 ) { const OUString aMediaTime( aParam.copy( 9, aParam.getLength() - 10 ) ); rtl_math_ConversionStatus eStatus; double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL ); if( eStatus == rtl_math_ConversionStatus_Ok ) { aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("MediaTime")); aParamValue.Value <<= fMediaTime; } nCommand = EffectCommands::PLAY; } else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("togglePause") ) ) { nCommand = EffectCommands::TOGGLEPAUSE; } else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("stop") ) ) { nCommand = EffectCommands::STOP; } break; case 2: // verb { aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Verb")); aParamValue.Value <<= aParam.toInt32(); nCommand = EffectCommands::VERB; } break; } xCommand->setCommand( nCommand ); if( nCommand == EffectCommands::CUSTOM ) { OSL_FAIL("sd::AnimationImporter::importCommandContainer(), unknown command!"); aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefined")); aParamValue.Value <<= aParam; } if( aParamValue.Value.hasValue() ) { Sequence< NamedValue > aParamSeq( &aParamValue, 1 ); xCommand->setParameter( makeAny( aParamSeq ) ); } } } } // -------------------------------------------------------------------- void AnimationImporter::importAudioContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XAudio > xAudio( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && xAudio.is() && ( (pAtom->getType() == DFF_msofbtAnimGroup) || (pAtom->getType() == DFF_msofbtAnimSubGoup) ), "invalid call to ppt::AnimationImporter::importAudioContainer()!"); if( pAtom && xAudio.is() ) { importAnimationEvents( pAtom, xNode ); importAnimationValues( pAtom, xNode ); importAnimationActions( pAtom, xNode ); dump(">\n"); const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimNode: case DFF_msofbtAnimEvent: case DFF_msofbtAnimValue: case DFF_msofbtAnimAction: case DFF_msofbtAnimPropertySet: break; case DFF_msofbtAnimAttributeValue: { Any aValue; if ( importAttributeValue( pChildAtom, aValue ) ) { dump( " value=\"" ); dump( aValue ); dump( "\"" ); } } break; case DFF_msofbtAnimateTargetElement: { sal_Int16 nSubType; Any aSource; importTargetElementContainer( pChildAtom, aSource, nSubType ); if( xAudio.is() ) xAudio->setSource( aSource ); } break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } // TODO: What to do with them? Any aEmpty; xAudio->setBegin( aEmpty ); xAudio->setEnd( aEmpty ); } } // -------------------------------------------------------------------- void AnimationImporter::importAnimateScaleContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateScale && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateScaleContainer()!"); if( pAtom && xTransform.is() ) { xTransform->setTransformType( AnimationTransformType::SCALE ); const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimateScaleData: { sal_uInt32 nBits, nZoomContents; float fByX, fByY, fFromX, fFromY, fToX, fToY; // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool) mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nZoomContents; ValuePair aPair; // 'from' value if( nBits & 2 ) { aPair.First <<= (double)fFromX / 100.0; aPair.Second <<= (double)fFromY / 100.0; xTransform->setFrom( makeAny( aPair ) ); } // 'to' value if( nBits & 4 ) { aPair.First <<= (double)fToX / 100.0; aPair.Second <<= (double)fToY / 100.0; xTransform->setTo( makeAny( aPair ) ); } // 'by' value if( nBits & 1 ) { aPair.First <<= (double)fByX / 100.0; aPair.Second <<= (double)fByY / 100.0; if( nBits & 2 ) { // 'from' value given, import normally xTransform->setBy( makeAny( aPair ) ); } else { // mapping 'by' to 'to', if no 'from' is // given. This is due to a non-conformity in // PPT, which exports animateScale effects // with a sole 'by' value, but with the // semantics of a sole 'to' animation xTransform->setTo( makeAny( aPair ) ); } } #ifdef DBG_ANIM_LOG if( nBits & 1 ) fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY ); if( nBits & 2 ) fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY ); if( nBits & 4 ) fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY ); if( nBits & 8 ) fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" ); #endif } break; case DFF_msofbtAnimateTarget: importAnimateAttributeTargetContainer( pChildAtom, xNode ); break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importAnimateRotationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateRotation && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateRotationContainer()!"); if( pAtom && xTransform.is() ) { xTransform->setTransformType( AnimationTransformType::ROTATE ); const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( !pChildAtom->isContainer() ) { if( !pChildAtom->seekToContent() ) break; } switch( pChildAtom->getType() ) { case DFF_msofbtAnimateRotationData: { sal_uInt32 nBits, nU1; float fBy, fFrom, fTo; // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool) mrStCtrl >> nBits >> fBy >> fFrom >> fTo >> nU1; if( nBits & 1 ) xTransform->setBy( makeAny( (double) fBy ) ); if( nBits & 2 ) xTransform->setFrom( makeAny( (double) fFrom ) ); if( nBits & 4 ) xTransform->setTo( makeAny( (double) fTo ) ); #ifdef DBG_ANIM_LOG if( nBits & 1 ) fprintf( mpFile, " by=\"%g\"", (double)fBy ); if( nBits & 2 ) fprintf( mpFile, " from=\"%g\"", (double)fFrom ); if( nBits & 4 ) fprintf( mpFile, " to=\"%g\"", (double)fTo ); if( nU1 ) fprintf( mpFile, " rotation_1=\"%ld\"", nU1 ); #endif } break; case DFF_msofbtAnimateTarget: importAnimateAttributeTargetContainer( pChildAtom, xNode ); break; default: dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // -------------------------------------------------------------------- bool AnimationImporter::importAttributeNamesContainer( const Atom* pAtom, OUString& rAttributeNames ) { OUStringBuffer aNames; DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateAttributeNames), "invalid call to ppt::AnimationImporter::importAttributeName()!" ); if( pAtom ) { const Atom* pAttributeValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAttributeValue ); while( pAttributeValueAtom ) { Any aAny; if ( importAttributeValue( pAttributeValueAtom, aAny ) ) { OUString aName; if( aAny >>= aName ) { if( aNames.getLength() ) aNames.append( (sal_Unicode)';' ); aNames.append( aName ); } } else { OSL_FAIL( "error during ppt::AnimationImporter::importAttributeName()!" ); } pAttributeValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimAttributeValue, pAttributeValueAtom ); } } rAttributeNames = aNames.makeStringAndClear(); return true; } // -------------------------------------------------------------------- void AnimationImporter::importAnimationValues( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { DBG_ASSERT( pAtom, "invalid call to ppt::AnimationImporter::importAnimationValues()!" ); if( pAtom ) { const Atom* pValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimValue ); while( pValueAtom && pValueAtom->seekToContent() ) { sal_uInt32 nType; mrStCtrl >> nType; switch( nType ) { case 0: { float fRepeat; mrStCtrl >> fRepeat; xNode->setRepeatCount( (fRepeat < ((float)3.40282346638528860e+38)) ? makeAny( (double)fRepeat ) : makeAny( Timing_INDEFINITE ) ); #ifdef DBG_ANIM_LOG if( (fRepeat < ((float)3.40282346638528860e+38)) ) { dump( " repeat=\"%g\"", (double)fRepeat ); } else { dump( " repeat=\"indefinite\"" ); } #endif } break; case 3: { float faccelerate; mrStCtrl >> faccelerate; xNode->setAcceleration( faccelerate ); dump( " accelerate=\"%g\"", (double)faccelerate ); } break; case 4: { float fdecelerate; mrStCtrl >> fdecelerate; xNode->setDecelerate( fdecelerate ); dump( " decelerate=\"%g\"", (double)fdecelerate ); } break; case 5: { sal_Int32 nAutoreverse; mrStCtrl >> nAutoreverse; xNode->setAutoReverse( nAutoreverse != 0 ); dump( " autoreverse=\"%#lx\"", nAutoreverse ); } break; default: { sal_uInt32 nUnknown; mrStCtrl >> nUnknown; #ifdef DBG_ANIM_LOG fprintf(mpFile, " attribute_%d=\"%#lx\"", nType, nUnknown ); #endif } break; } pValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimValue, pValueAtom ); } } } // -------------------------------------------------------------------- void AnimationImporter::importAnimateKeyPoints( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { Reference< XAnimate > xAnim( xNode, UNO_QUERY ); DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimKeyPoints && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateKeyPoints()!" ); if( pAtom && xAnim.is() ) { // first count keytimes const Atom* pIter = NULL; int nKeyTimes = 0; while( (pIter = pAtom->findNextChildAtom( DFF_msofbtAnimKeyTime, pIter )) != 0 ) nKeyTimes++; Sequence< double > aKeyTimes( nKeyTimes ); Sequence< Any > aValues( nKeyTimes ); OUString aFormula; pIter = pAtom->findFirstChildAtom(DFF_msofbtAnimKeyTime); int nKeyTime; sal_Int32 nTemp; for( nKeyTime = 0; (nKeyTime < nKeyTimes) && pIter; nKeyTime++ ) { if( pIter->seekToContent() ) { mrStCtrl >> nTemp; double fTemp = (double)nTemp / 1000.0; aKeyTimes[nKeyTime] = fTemp; const Atom* pValue = pAtom->findNextChildAtom(pIter); if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue ) { Any aValue1, aValue2; if( importAttributeValue( pValue, aValue1 ) ) { pValue = pAtom->findNextChildAtom(pValue); if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue ) importAttributeValue( pValue, aValue2 ); bool bCouldBeFormula = false; bool bHasValue = aValue2.hasValue(); if( bHasValue ) { if( aValue2.getValueType() == ::getCppuType((const OUString*)0) ) { OUString aTest; aValue2 >>= aTest; bHasValue = aTest.getLength() != 0; bCouldBeFormula = true; } } if( bHasValue && bCouldBeFormula && (aValue1.getValueType() == ::getCppuType((const double*)0)) ) { aValue2 >>= aFormula; bHasValue = false; } if( bHasValue ) { aValues[nKeyTime] = makeAny( ValuePair( aValue1, aValue2 ) ); } else { aValues[nKeyTime] = aValue1; } } } } pIter = pAtom->findNextChildAtom(DFF_msofbtAnimKeyTime, pIter); } #ifdef DBG_ANIM_LOG dump( " keyTimes=\"" ); for( int i=0; i>= aStr ) dump( "%s", ::rtl::OUStringToOString( aStr, RTL_TEXTENCODING_ASCII_US ).getStr() ); else if( aValues[i] >>= nVal ) dump( "%f", nVal ); else { ValuePair aValuePair; if( aValues[i] >>= aValuePair ) { if( aValuePair.First >>= aStr ) dump( "%s", ::rtl::OUStringToOString( aStr, RTL_TEXTENCODING_ASCII_US ).getStr() ); else if( aValuePair.First >>= nVal ) dump( "%f", nVal ); else dump( "%X", (sal_Int32)&aValuePair.First ); if( aValuePair.Second >>= aStr ) dump( ",%s", ::rtl::OUStringToOString( aStr, RTL_TEXTENCODING_ASCII_US ).getStr() ); else if( aValuePair.Second >>= nVal ) dump( ",%f", nVal ); else dump( ",%X", (sal_Int32)&aValuePair.Second ); } } } dump( "\"" ); #endif xAnim->setKeyTimes( aKeyTimes ); xAnim->setValues( aValues ); xAnim->setFormula( aFormula ); } } // -------------------------------------------------------------------- bool AnimationImporter::importAttributeValue( const Atom* pAtom, Any& rAny ) { DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimAttributeValue, "invalid call to ppt::AnimationImporter::importAttributeValue()!" ); bool bOk = false; if( pAtom && pAtom->seekToContent() ) { sal_uInt32 nRecLen = pAtom->getLength(); if ( nRecLen >= 1 ) { sal_Int8 nType; mrStCtrl >> nType; switch( nType ) { case DFF_ANIM_PROP_TYPE_BYTE : { if ( nRecLen == 2 ) { sal_uInt8 nByte; mrStCtrl >> nByte; rAny <<= nByte; bOk = true; } } break; case DFF_ANIM_PROP_TYPE_INT32 : { if ( nRecLen == 5 ) { sal_uInt32 nInt32; mrStCtrl >> nInt32; rAny <<= nInt32; bOk = true; } } break; case DFF_ANIM_PROP_TYPE_FLOAT: { if( nRecLen == 5 ) { float fFloat; mrStCtrl >> fFloat; rAny <<= (double)fFloat; bOk = true; } } break; case DFF_ANIM_PROP_TYPE_UNISTRING : { if ( ( nRecLen & 1 ) && ( nRecLen > 1 ) ) { String aString; mpPPTImport->MSDFFReadZString( mrStCtrl, aString, nRecLen - 1, sal_True ); rtl::OUString aOUString( aString ); rAny <<= aOUString; bOk = true; } } break; } } } DBG_ASSERT( bOk, "invalid value inside ppt::AnimationImporter::importAttributeValue()!" ); return bOk; } // -------------------------------------------------------------------- void AnimationImporter::importAnimationEvents( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { DBG_ASSERT( xNode.is() && pAtom, "invalid call to ppt::AnimationImporter::importAnimationEvents()!" ); Any aBegin, aEnd, aNext, aPrev; const Atom* pEventAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimEvent ); while( pEventAtom ) { Any* pEvents = NULL; switch( pEventAtom->getInstance() ) { case 1: pEvents = &aBegin; break; case 2: pEvents = &aEnd; break; case 3: pEvents = &aNext; break; case 4: pEvents = &aPrev; break; } if( pEvents ) { Event aEvent; aEvent.Trigger = EventTrigger::NONE; aEvent.Repeat = 0; const Atom* pChildAtom = pEventAtom->findFirstChildAtom(); while( pChildAtom && pChildAtom->seekToContent() ) { switch( pChildAtom->getType() ) { case DFF_msofbtAnimTrigger: { sal_Int32 nU1, nTrigger, nU3, nBegin; mrStCtrl >> nU1; mrStCtrl >> nTrigger; mrStCtrl >> nU3; mrStCtrl >> nBegin; switch( nTrigger ) { case 0: aEvent.Trigger = EventTrigger::NONE; break; case 1: aEvent.Trigger = EventTrigger::ON_BEGIN; break; case 2: aEvent.Trigger = EventTrigger::ON_END; break; case 3: aEvent.Trigger = EventTrigger::BEGIN_EVENT; break; case 4: aEvent.Trigger = EventTrigger::END_EVENT; break; case 5: aEvent.Trigger = EventTrigger::ON_CLICK; break; case 6: aEvent.Trigger = EventTrigger::ON_DBL_CLICK; break; case 7: aEvent.Trigger = EventTrigger::ON_MOUSE_ENTER; break; case 8: aEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE; break; case 9: aEvent.Trigger = EventTrigger::ON_NEXT; break; case 10: aEvent.Trigger = EventTrigger::ON_PREV; break; case 11: aEvent.Trigger = EventTrigger::ON_STOP_AUDIO; break; } if( (nBegin != 0) || (aEvent.Trigger == EventTrigger::NONE) ) aEvent.Offset = (nBegin == -1) ? makeAny( Timing_INDEFINITE ) : makeAny( (double)(nBegin / 1000.0) ); } break; case DFF_msofbtAnimateTargetElement: { sal_Int16 nSubType; importTargetElementContainer( pChildAtom, aEvent.Source, nSubType ); } break; default: { OSL_FAIL("unknown atom inside ppt::AnimationImporter::importAnimationEvents()!"); } } pChildAtom = pEventAtom->findNextChildAtom( pChildAtom ); } *pEvents = addToSequence( *pEvents, (aEvent.Trigger == EventTrigger::NONE) ? aEvent.Offset : makeAny( aEvent ) ); } pEventAtom = pAtom->findNextChildAtom( DFF_msofbtAnimEvent, pEventAtom ); } xNode->setBegin( aBegin ); xNode->setEnd( aEnd ); // TODO: xNode->setNext( aNext ); // TODO: xNode->setPrev( aNext ); #ifdef DBG_ANIM_LOG if( aBegin.hasValue() ) { dump( " begin=\"" ); dump( aBegin ); dump( "\"" ); } if( aEnd.hasValue() ) { dump( " end=\"" ); dump( aEnd ); dump( "\"" ); } if( aNext.hasValue() ) { dump( " next=\"" ); dump( aNext ); dump( "\"" ); } if( aPrev.hasValue() ) { dump( " prev=\"" ); dump( aPrev ); dump( "\"" ); } #endif } // -------------------------------------------------------------------- void AnimationImporter::importAnimationActions( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) { DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationActions()!"); if( pAtom ) { const Atom* pActionAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAction ); if( pActionAtom && pActionAtom->seekToContent() ) { sal_Int32 nConcurrent, nNextAction, nEndSync, nU4, nU5; mrStCtrl >> nConcurrent; mrStCtrl >> nNextAction; mrStCtrl >> nEndSync; mrStCtrl >> nU4; mrStCtrl >> nU5; if( nEndSync == 1 ) xNode->setEndSync( makeAny( AnimationEndSync::ALL ) ); #ifdef DBG_ANIM_LOG dump( " concurrent=\"%s\"", nConcurrent == 0 ? "disabled" : (nConcurrent == 1 ? "enabled" : "unknown") ); dump( " nextAction=\"%s\"", nNextAction == 0 ? "none" : (nNextAction == 1 ? "seek" : "unknown") ); if( nEndSync != 0 ) { dump( " endSync=\"%s\"", nEndSync == 1 ? "all" : "unknown" ); } dump( " action_4=\"%#lx\"", nU4 ); dump( " action_5=\"%#lx\"", nU5 ); #endif } } } // -------------------------------------------------------------------- sal_Int32 AnimationImporter::importTargetElementContainer( const Atom* pAtom, Any& rTarget, sal_Int16& rSubType ) { rSubType = ShapeAnimationSubType::AS_WHOLE; sal_Int32 nRefMode = -1; DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateTargetElement), "invalid call to ppt::AnimationImporter::importTargetElementContainer()!" ); if( pAtom ) { const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom && pChildAtom->seekToContent() ) { switch( pChildAtom->getType() ) { case DFF_msofbtAnimReference: { sal_Int32 nRefType,nRefId; sal_Int32 begin,end; mrStCtrl >> nRefMode; mrStCtrl >> nRefType; mrStCtrl >> nRefId; mrStCtrl >> begin; mrStCtrl >> end; switch( nRefType ) { case 1: // shape { SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId ); if( pSdrObject == NULL ) break; rTarget <<= pSdrObject->getUnoShape(); switch( nRefMode ) { case 6: rSubType = ShapeAnimationSubType::ONLY_BACKGROUND; break; case 8: rSubType = ShapeAnimationSubType::ONLY_TEXT; break; case 2: // one paragraph { if( ((begin == -1) && (end == -1)) || !pSdrObject->ISA( SdrTextObj ) ) break; SdrTextObj* pTextObj = static_cast< SdrTextObj* >( pSdrObject ); const OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject(); if( pOPO == NULL ) break; const EditTextObject& rEditTextObject = pOPO->GetTextObject(); const sal_uInt16 nParaCount = rEditTextObject.GetParagraphCount(); sal_uInt16 nPara = 0; while( (nPara < nParaCount) && (begin > 0) ) { sal_Int32 nParaLength = rEditTextObject.GetText( nPara ).Len() + 1; begin -= nParaLength; end -= nParaLength; nPara++; } if( nPara < nParaCount ) { ParagraphTarget aParaTarget; rTarget >>= aParaTarget.Shape; aParaTarget.Paragraph = nPara; rTarget = makeAny( aParaTarget ); rSubType = ShapeAnimationSubType::ONLY_TEXT; dump( " paragraph %d,", (sal_Int32)nPara); dump( " %d characters", (sal_Int32)end ); } } } } break; case 2: // sound { OUString aSoundURL( ((ImplSdPPTImport*)mpPPTImport)->ReadSound( nRefId ) ); rTarget <<= aSoundURL; dump( " srcRef=\"%s\"", aSoundURL ); } break; case 3: // audio object case 4: // video object { SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId ); if( pSdrObject == NULL ) break; rTarget <<= pSdrObject->getUnoShape(); } break; default: OSL_FAIL("unknown reference type"); } } break; case 0x2b01: { sal_Int32 nU1; mrStCtrl >> nU1; } break; default: OSL_FAIL("unknwon atom inside ppt::AnimationImporter::importTargetElementContainer()!"); break; } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } return nRefMode; } // -------------------------------------------------------------------- void AnimationImporter::importPropertySetContainer( const Atom* pAtom, PropertySet& rSet ) { DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimPropertySet), "invalid call to ppt::AnimationImporter::importPropertySetContainer()!" ); if( pAtom ) { const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue ) { Any aAny; importAttributeValue( pChildAtom, aAny ); rSet.maProperties[ pChildAtom->getInstance() ] = aAny; } else { OSL_FAIL("unknwon atom inside ppt::AnimationImporter::importPropertySetContainer()!"); } pChildAtom = pAtom->findNextChildAtom( pChildAtom ); } } } // ==================================================================== #ifdef DBG_ANIM_LOG void AnimationImporter::dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend ) { if( pAtom ) { const char* pTitle; switch( pAtom->getType() ) { case DFF_msofbtAnimEvent: pTitle = "AnimEvent"; break; case DFF_msofbtAnimTrigger: pTitle = "AnimTrigger"; break; case DFF_msofbtAnimateMotion: pTitle = "AnimateMotion"; break; case DFF_msofbtAnimPropertySet: pTitle = "AnimPropertySet"; break; case DFF_msofbtAnimateAttributeNames: pTitle = "AnimAttributeName"; break; case DFF_msofbtAnimAttributeValue: pTitle = "AnimAttributeValue"; break; case DFF_msofbtAnimGroup: pTitle = "AnimGroup"; break; case DFF_msofbtAnimNode: pTitle = "AnimNode"; break; case DFF_msofbtAnimValue: pTitle = "AnimValue"; break; case DFF_msofbtAnimateFilter: pTitle = "animateFilter"; break; case DFF_msofbtAnimate: pTitle = "animate"; break; case DFF_msofbtAnimateSet: pTitle = "set"; break; case DFF_msofbtAnimKeyTime: pTitle = "AnimKeyTime"; break; case DFF_msofbtAnimKeyPoints: pTitle = "AnimKeyPoints"; break; case DFF_msofbtAnimReference: pTitle = "AnimReference"; break; case DFF_msofbtAnimateTargetElement: pTitle = "AnimTargetElementContainer"; break; case DFF_msofbtAnimAction: pTitle = "AnimAction"; break; case DFF_msofbtAnimCommand: pTitle = "AnimCommand"; break; case DFF_msofbtAnimateTarget: pTitle = "TransformationTarget"; break; case DFF_msofbtAnimateTargetSettings: pTitle = "TransformationTargetSettings"; break; case DFF_msofbtAnimIteration: pTitle = "iterate"; break; case DFF_msofbtAnimateColorData: pTitle = "colorData"; break; case DFF_msofbtAnimateScaleData: pTitle = "scaleData"; break; case DFF_msofbtAnimateSetData: pTitle = "setData"; break; default: { static char buffer[128]; sprintf( buffer, "unknown_%#x", pAtom->getType() ); pTitle = buffer; } } if( bOpen ) { fprintf(mpFile, "<%s", pTitle ); fprintf(mpFile, " instance=\"%hu\"%s", pAtom->getInstance(), bAppend ? "" : ">\n"); } else { if( bAppend ) fprintf(mpFile,"/>\n"); else fprintf(mpFile, "\n", pTitle ); } } } // -------------------------------------------------------------------- void AnimationImporter::dump( sal_uInt32 nLen, bool bNewLine ) { char * faul = "0123456789abcdef"; sal_uInt32 i = 0; int b = 0; sal_Int8 nData; for( i = 0; i < nLen; i++ ) { mrStCtrl >> nData; fprintf( mpFile, "%c%c ", faul[ (nData >> 4) & 0x0f ], faul[ nData & 0x0f ] ); b++; if( bNewLine && (b == 32) ) { fprintf(mpFile,"\n"); b = 0; } } if( (b != 0) && bNewLine ) fprintf(mpFile,"\n"); } // -------------------------------------------------------------------- void AnimationImporter::dump_atom( const Atom* pAtom, bool bNewLine ) { if( pAtom ) { if( pAtom->isContainer() ) { const Atom* pChildAtom = pAtom->findFirstChildAtom(); while( pChildAtom ) { if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue ) { fprintf(mpFile, "getInstance() ); Any aValue; if( importAttributeValue( pChildAtom, aValue ) ) { sal_Int32 nInt; rtl::OUString aString; double fDouble; if( aValue >>= nInt ) { fprintf(mpFile, " value=\"%ld\"", nInt ); } else if( aValue >>= aString ) { UniString aTmp( aString ); ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); fprintf(mpFile, " value=\"%s\"", aStr.GetBuffer() ); } else if( aValue >>= fDouble ) { fprintf(mpFile, " value=\"%g\"", fDouble ); } } else { if( pChildAtom->seekToContent() ) { fprintf(mpFile, " value=\"" ); dump_atom( pChildAtom, false ); fprintf(mpFile, "\""); } } fprintf(mpFile, "/>\n" ); } else { dump_atom_header( pChildAtom, true, pChildAtom->getType() == DFF_msofbtAnimAttributeValue ); dump_atom( pChildAtom ); dump_atom_header( pChildAtom, false, pChildAtom->getType() == DFF_msofbtAnimAttributeValue ); } pChildAtom = pAtom->findNextChildAtom(pChildAtom); } } else if( pAtom->seekToContent() ) { dump( pAtom->getLength(), bNewLine ); } } } // -------------------------------------------------------------------- void AnimationImporter::dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen ) { fprintf( mpFile, bOpen ? "<" : "hasChildAtom( DFF_msofbtAnimateSet ) ) fprintf( mpFile, "set" ); else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) ) fprintf( mpFile, "animateColor" ); else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) ) fprintf( mpFile, "animateScale" ); else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) ) fprintf( mpFile, "animateRotation" ); else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) ) fprintf( mpFile, "animateMotion" ); else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) fprintf( mpFile, "command" ); else fprintf( mpFile, "animation" ); break; default: { fprintf( mpFile, "unknown_node_%#lx", rNode.mnNodeType ); } break; } break; case mso_Anim_GroupType_MEDIA: fprintf( mpFile, "media" ); break; default: fprintf( mpFile, "unknown_group_%#lx", rNode.mnGroupType ); break; } if( bOpen ) { dump( rNode ); dump( rSet ); } fprintf(mpFile,">\n"); } void AnimationImporter::dump( const AnimationNode& rNode ) { // dump animation node if( rNode.mnRestart != 0 ) { fprintf(mpFile," restart=\"%s\"", rNode.mnRestart == 1 ? "always" : (rNode.mnRestart == 2 ? "whenOff" : (rNode.mnRestart == 3 ? "never" : "unknown")) ); } if( rNode.mnFill ) { fprintf(mpFile," fill=\"%s\"", rNode.mnFill == 1 ? "remove" : (rNode.mnFill == 3 ? "hold" : (rNode.mnFill == 2 ? "freeze" : "unknown")) ); } if( rNode.mnDuration > 0 ) { double fSeconds = rNode.mnDuration; fSeconds /= 1000.0; fprintf(mpFile, " dur=\"%g\"", fSeconds); } else if( rNode.mnDuration < 0 ) { fprintf(mpFile, " dur=\"indefinite\"" ); } if( rNode.mnU1 ) fprintf(mpFile," u1=\"%#lx\"", rNode.mnU1); if( rNode.mnU3 ) fprintf(mpFile," u3=\"%#lx\"", rNode.mnU3); if( rNode.mnU4 ) fprintf(mpFile," u4=\"%#lx\"", rNode.mnU4); } void AnimationImporter::dump( Any& rAny ) { Sequence< Any > aSeq; sal_Int32 nInt; double fDouble; OUString aString; sal_Bool bBool; Event aEvent; Timing aTiming; if( rAny >>= aSeq ) { const sal_Int32 nSize = aSeq.getLength(); sal_Int32 nIndex = 0; while( nIndex < nSize ) { dump( aSeq[nIndex++] ); if(nIndex < nSize) fprintf( mpFile, "," ); } } else if( rAny >>= aString ) { UniString aTmp(aString); ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); fprintf( mpFile, "%s", aStr.GetBuffer() ); } else if( rAny >>= nInt ) { fprintf( mpFile, "%ld", nInt ); } else if( rAny >>= bBool ) { fprintf( mpFile, "%s", bBool ? "true" : "false" ); } else if( rAny >>= fDouble ) { fprintf( mpFile, "%g", fDouble ); } else if( rAny >>= aTiming ) { fprintf( mpFile, "%s", aTiming == (Timing_INDEFINITE) ? "indefinite" : "media" ); } else if( rAny >>= aEvent ) { static const char* triggers[] = { "none","onbegin","onend","begin", "end","onclick","ondoubleclick","onmouseenter", "onmouseleave","onpptnext","onpptprev","onstopaudio" }; if( aEvent.Trigger != EventTrigger::NONE ) { if( aEvent.Source.hasValue() ) { dump_target( aEvent.Source ); dump( "." ); } dump( triggers[ aEvent.Trigger ] ); } if( aEvent.Offset.hasValue() ) { double fOffset; if( aEvent.Offset >>= fOffset ) fprintf( mpFile, "%g", fOffset ); else dump( "indefinite" ); } } } void AnimationImporter::dump( const PropertySet& rSet ) { // dump property set map< sal_Int32, Any >::const_iterator aIter( rSet.maProperties.begin() ); const map< sal_Int32, Any >::const_iterator aEnd( rSet.maProperties.end() ); while( aIter != aEnd ) { bool bKnown = false; const sal_Int32 nInstance = (*aIter).first; Any aAny( (*aIter).second ); switch ( nInstance ) { case DFF_ANIM_COLORSPACE: { sal_Int32 nColorSpace; if( aAny >>= nColorSpace ) { fprintf( mpFile, " colorSpace=\"%s\"", (nColorSpace == 0) ? "rgb" : (nColorSpace == 1) ? "hsl" : "unknown" ); bKnown = true; } } break; case DFF_ANIM_DIRECTION: { sal_Bool bDirection; if( aAny >>= bDirection ) { fprintf( mpFile, " direction=\"%s\"", bDirection ? "cclockwise" : "clockwise" ); bKnown = true; } else { sal_Int32 nMasterRel; if( aAny >>= nMasterRel ) { fprintf( mpFile, " direction=\"%s\"", nMasterRel == 0 ? "sameClick" : ( nMasterRel == 2 ? "nextClick" : "lastClick" ) ); bKnown = true; } } } break; case DFF_ANIM_OVERRIDE: // TODO { sal_Int32 nOverride; if( aAny >>= nOverride ) { fprintf( mpFile, " override=\"%s\"", (nOverride == 1) ? "childStyle" : (nOverride == 0) ? "normal" : "unknown" ); bKnown = true; } } break; case DFF_ANIM_PATH_EDIT_MODE: { sal_Bool bPathEditMode; if( aAny >>= bPathEditMode ) { fprintf( mpFile, " pptPathEditMode=\"%s\"", bPathEditMode ? "relative" : "fixed" ); bKnown = true; } } break; case DFF_ANIM_PRESET_ID : { sal_Int32 nPresetId ; if( aAny >>= nPresetId ) { fprintf(mpFile, " presetid=\"%ld\"", nPresetId ); bKnown = true; } } break; case DFF_ANIM_PRESET_SUB_TYPE : { sal_Int32 nPointsType ; if( aAny >>= nPointsType ) { fprintf(mpFile, " presetSubType=\"%ld\"", nPointsType ); bKnown = true; } } break; case DFF_ANIM_PRESET_CLASS : { sal_Int32 nPresetClass; if ( aAny >>= nPresetClass ) { const char* pMode; switch( nPresetClass ) { case DFF_ANIM_PRESS_CLASS_USER_DEFINED: pMode = "userdefined"; break; case DFF_ANIM_PRESS_CLASS_ENTRANCE: pMode = "entrance"; break; case DFF_ANIM_PRESS_CLASS_EXIT: pMode = "exit"; break; case DFF_ANIM_PRESS_CLASS_EMPHASIS: pMode = "emphasis"; break; case DFF_ANIM_PRESS_CLASS_MOTIONPATH: pMode = "motionpath"; break; case DFF_ANIM_PRESS_CLASS_OLE_ACTION: pMode = "oleaction"; break; case DFF_ANIM_PRESS_CLASS_MEDIACALL: pMode = "mediacall"; break; default: { static char buffer[128]; sprintf( buffer, "%ld", nPresetClass ); pMode = buffer; } break; } fprintf(mpFile, " class=\"%s\"", pMode); bKnown = true; } } break; case DFF_ANIM_NODE_TYPE : { sal_Int32 nNodeType; if ( aAny >>= nNodeType ) { const char* pNode; switch( nNodeType ) { case DFF_ANIM_NODE_TYPE_ON_CLICK: pNode = "onclick"; break; case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: pNode = "withprevious"; break; case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: pNode = "afterprevious"; break; case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: pNode = "mainsequence"; break; case DFF_ANIM_NODE_TYPE_TIMING_ROOT: pNode = "timingroot"; break; case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:pNode = "interactivesequence"; break; default : { static char buffer[128]; sprintf( buffer, "%ld", nNodeType ); pNode = buffer; } break; } fprintf(mpFile, " nodeType=\"%s\"", pNode); bKnown = true; } } break; case DFF_ANIM_GROUP_ID: { sal_Int32 nGroupId; if ( aAny >>= nGroupId ) { fprintf( mpFile, " groupId=\"%ld\"", nGroupId ); bKnown = true; } } break; case DFF_ANIM_ID: { rtl::OUString aString; if( aAny >>= aString ) { UniString aTmp(aString); ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); fprintf( mpFile, " id=\"%s\"", aStr.GetBuffer() ); bKnown = true; } } break; case DFF_ANIM_EVENT_FILTER: { rtl::OUString aString; if( aAny >>= aString ) { UniString aTmp(aString); ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); fprintf( mpFile, " eventFilter=\"%s\"", aStr.GetBuffer() ); bKnown = true; } } break; case DFF_ANIM_ENDAFTERSLIDE: { sal_Int32 nEndAfterSlide; if( aAny >>= nEndAfterSlide ) { fprintf(mpFile, " endAfterSlide=\"%ld\"", nEndAfterSlide ); bKnown = true; } } case DFF_ANIM_TIMEFILTER: { rtl::OUString aString; if( aAny >>= aString ) { UniString aTmp(aString); ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); fprintf( mpFile, " timeFilter=\"%s\"", aStr.GetBuffer() ); bKnown = true; } } break; case DFF_ANIM_RUNTIMECONTEXT: { rtl::OUString aString; if( aAny >>= aString ) { UniString aTmp(aString); ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); fprintf( mpFile, " runtimeContext=\"%s\"", aStr.GetBuffer() ); bKnown = true; } } break; case DFF_ANIM_VOLUME: { double fVolume(0.0); if( aAny >>= fVolume ) { fprintf( mpFile, " volume=\"%g%%\"", (double)(fVolume * 100.0) ); bKnown = true; } } break; case DFF_ANIM_AFTEREFFECT: { sal_Bool bAfterEffect; if( aAny >>= bAfterEffect ) { fprintf( mpFile, "afterEffect=\"%s\"", bAfterEffect ? "true" : "false" ); bKnown = true; } } break; } if( !bKnown ) { fprintf( mpFile, " unknown_%lu=\"", nInstance ); dump( aAny ); fprintf( mpFile, "\"" ); } ++aIter; } } void AnimationImporter::dump_target( Any& rAny ) { Any aSource, aSourceData; Sequence< Any > aSeq; if( rAny >>= aSeq ) { if( aSeq.getLength() >= 1 ) aSource = aSeq[0]; if( aSeq.getLength() >= 2 ) aSourceData = aSeq[1]; } else { aSource = rAny; } Reference< XShape > xShape; aSource >>= xShape; if( xShape.is() ) { OUString aStr( xShape->getShapeType() ); dump( aStr ); if( aSourceData.hasValue() ) { dump( "(" ); dump( aSourceData ); dump( ")" ); } } } void AnimationImporter::dump( const char * pText ) { fprintf( mpFile, "%s", pText ); } void AnimationImporter::dump( const rtl::OUString& rString ) { UniString aTmp( rString ); ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); fprintf( mpFile, aStr.GetBuffer() ); } void AnimationImporter::dump( const char * pText, sal_Int32 nInt ) { fprintf( mpFile, pText, nInt ); } void AnimationImporter::dump( const char * pText, double fDouble ) { fprintf( mpFile, pText, fDouble ); } void AnimationImporter::dump( const char * pText, const char * pText2 ) { fprintf( mpFile, pText, pText2 ); } void AnimationImporter::dump( const char * pText, const OUString& rString ) { UniString aTmp( rString ); ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); fprintf( mpFile, pText, aStr.GetBuffer() ); } #else void AnimationImporter::dump_atom_header( const Atom* , bool , bool ) { } void AnimationImporter::dump_atom( const Atom* , bool ) { } void AnimationImporter::dump_target( ::com::sun::star::uno::Any& ) { } void AnimationImporter::dump( ::com::sun::star::uno::Any& ) { } void AnimationImporter::dump( const PropertySet& ) { } void AnimationImporter::dump( const AnimationNode& ) { } void AnimationImporter::dump( const char * ) { } void AnimationImporter::dump( const char * , sal_Int32 ) { } void AnimationImporter::dump( const char * , double ) { } void AnimationImporter::dump( const char * , const char * ) { } void AnimationImporter::dump( const char * , const rtl::OUString& ) { } #endif } // namespace ppt; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */