LCOV - code coverage report
Current view: top level - sd/source/filter/eppt - pptexanimations.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1200 0.0 %
Date: 2014-04-14 Functions: 0 41 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
      21             : #include <com/sun/star/animations/AnimationFill.hpp>
      22             : #include <com/sun/star/animations/AnimationRestart.hpp>
      23             : #include <com/sun/star/animations/Timing.hpp>
      24             : #include <com/sun/star/animations/Event.hpp>
      25             : #include <com/sun/star/animations/AnimationEndSync.hpp>
      26             : #include <com/sun/star/animations/EventTrigger.hpp>
      27             : #include <com/sun/star/presentation/EffectNodeType.hpp>
      28             : #include <com/sun/star/presentation/EffectPresetClass.hpp>
      29             : #include <com/sun/star/animations/AnimationNodeType.hpp>
      30             : #include <com/sun/star/animations/AnimationTransformType.hpp>
      31             : #include <com/sun/star/animations/AnimationCalcMode.hpp>
      32             : #include <com/sun/star/animations/AnimationValueType.hpp>
      33             : #include <com/sun/star/util/XCloneable.hpp>
      34             : #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
      35             : #include <com/sun/star/animations/XAnimateSet.hpp>
      36             : #include <com/sun/star/animations/XAudio.hpp>
      37             : #include <com/sun/star/animations/XTransitionFilter.hpp>
      38             : #include <com/sun/star/animations/XAnimateColor.hpp>
      39             : #include <com/sun/star/animations/XAnimateMotion.hpp>
      40             : #include <com/sun/star/animations/XAnimateTransform.hpp>
      41             : #include <com/sun/star/animations/TransitionType.hpp>
      42             : #include <com/sun/star/animations/TransitionSubType.hpp>
      43             : #include <com/sun/star/animations/ValuePair.hpp>
      44             : #include <com/sun/star/animations/AnimationColorSpace.hpp>
      45             : #include <com/sun/star/drawing/FillStyle.hpp>
      46             : #include <com/sun/star/drawing/LineStyle.hpp>
      47             : #include <com/sun/star/awt/FontWeight.hpp>
      48             : #include <com/sun/star/awt/FontUnderline.hpp>
      49             : #include <com/sun/star/awt/FontSlant.hpp>
      50             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      51             : #include <com/sun/star/presentation/ParagraphTarget.hpp>
      52             : #include <com/sun/star/text/XSimpleText.hpp>
      53             : #include <com/sun/star/animations/XIterateContainer.hpp>
      54             : #include <com/sun/star/presentation/TextAnimationType.hpp>
      55             : #include <com/sun/star/container/XChild.hpp>
      56             : #include <comphelper/processfactory.hxx>
      57             : #include <rtl/ustrbuf.hxx>
      58             : 
      59             : #include <vcl/vclenum.hxx>
      60             : #include <svx/svdotext.hxx>
      61             : #include <editeng/outlobj.hxx>
      62             : #include <editeng/editobj.hxx>
      63             : #include <pptexanimations.hxx>
      64             : #include <osl/endian.h>
      65             : 
      66             : #include <algorithm>
      67             : 
      68             : using ::std::map;
      69             : using ::com::sun::star::uno::Any;
      70             : using ::com::sun::star::container::XChild;
      71             : using ::com::sun::star::util::XCloneable;
      72             : using ::com::sun::star::uno::Reference;
      73             : using ::com::sun::star::uno::UNO_QUERY;
      74             : using ::com::sun::star::uno::UNO_QUERY_THROW;
      75             : using ::com::sun::star::uno::Sequence;
      76             : using ::com::sun::star::uno::makeAny;
      77             : using ::com::sun::star::uno::Exception;
      78             : using ::com::sun::star::uno::XInterface;
      79             : using ::com::sun::star::beans::NamedValue;
      80             : using ::com::sun::star::container::XEnumerationAccess;
      81             : using ::com::sun::star::container::XEnumeration;
      82             : using ::com::sun::star::lang::XMultiServiceFactory;
      83             : 
      84             : using namespace ::com::sun::star::text;
      85             : using namespace ::com::sun::star::drawing;
      86             : using namespace ::com::sun::star::animations;
      87             : using namespace ::com::sun::star::presentation;
      88             : 
      89             : namespace ppt
      90             : {
      91             : 
      92           0 : void ImplTranslateAttribute( OUString& rString, const TranslateMode eTranslateMode )
      93             : {
      94           0 :     if ( eTranslateMode != TRANSLATE_NONE )
      95             :     {
      96           0 :         if ( ( eTranslateMode & TRANSLATE_VALUE ) || ( eTranslateMode & TRANSLATE_ATTRIBUTE ) )
      97             :         {
      98           0 :             const ImplAttributeNameConversion* p = gImplConversionList;
      99           0 :             while( p->mpAPIName )
     100             :             {
     101           0 :                 if( rString.equalsAscii( p->mpAPIName ) )
     102           0 :                     break;
     103           0 :                 p++;
     104             :             }
     105           0 :             if( p->mpMSName )
     106             :             {
     107           0 :                 if ( eTranslateMode & TRANSLATE_VALUE )
     108             :                 {
     109           0 :                     rString = OUString( (sal_Unicode)'#' );
     110           0 :                     rString += OUString::createFromAscii( p->mpMSName );
     111             :                 }
     112             :                 else
     113           0 :                     rString = OUString::createFromAscii( p->mpMSName );
     114           0 :             }
     115             :         }
     116           0 :         else if ( eTranslateMode & TRANSLATE_MEASURE )
     117             :         {
     118           0 :             const sal_Char* pDest[] = { "#ppt_x", "#ppt_y", "#ppt_w", "#ppt_h", NULL };
     119           0 :             const sal_Char* pSource[] = { "x", "y", "width", "height", NULL };
     120           0 :             sal_Int32 nIndex = 0;
     121             : 
     122           0 :             const sal_Char** ps = pSource;
     123           0 :             const sal_Char** pd = pDest;
     124             : 
     125           0 :             while( *ps )
     126             :             {
     127           0 :                 const OUString aSearch( OUString::createFromAscii( *ps ) );
     128           0 :                 while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1  )
     129             :                 {
     130           0 :                     sal_Int32 nLength = aSearch.getLength();
     131           0 :                     if( nIndex && ( rString[nIndex-1] == '#' ) )
     132             :                     {
     133           0 :                         nIndex--;
     134           0 :                         nLength++;
     135             :                     }
     136             : 
     137           0 :                     const OUString aNew( OUString::createFromAscii( *pd ) );
     138           0 :                     rString = rString.replaceAt( nIndex, nLength, aNew );
     139           0 :                     nIndex += aNew.getLength();
     140           0 :                 }
     141           0 :                 ps++;
     142           0 :                 pd++;
     143           0 :             }
     144             :         }
     145             :     }
     146           0 : }
     147             : 
     148           0 : sal_uInt32 AnimationExporter::TranslatePresetSubType( const sal_uInt32 nPresetClass, const sal_uInt32 nPresetId, const OUString& rPresetSubType )
     149             : {
     150           0 :     sal_uInt32  nPresetSubType = 0;
     151           0 :     sal_Bool    bTranslated = sal_False;
     152             : 
     153           0 :     if ( ( nPresetClass == (sal_uInt32)EffectPresetClass::ENTRANCE ) || ( nPresetClass == (sal_uInt32)EffectPresetClass::EXIT ) )
     154             :     {
     155           0 :         if ( nPresetId != 21 )
     156             :         {
     157           0 :             switch( nPresetId )
     158             :             {
     159             :                 case 5 :
     160             :                 {
     161           0 :                     if ( rPresetSubType == "downward" )
     162             :                     {
     163           0 :                         nPresetSubType = 5;
     164           0 :                         bTranslated = sal_True;
     165             :                     }
     166           0 :                     else if ( rPresetSubType == "across" )
     167             :                     {
     168           0 :                         nPresetSubType = 10;
     169           0 :                         bTranslated = sal_True;
     170             :                     }
     171             :                 }
     172           0 :                 break;
     173             :                 case 17 :
     174             :                 {
     175           0 :                     if ( rPresetSubType == "across" )
     176             :                     {
     177           0 :                         nPresetSubType = 10;
     178           0 :                         bTranslated = sal_True;
     179             :                     }
     180             :                 }
     181           0 :                 break;
     182             :                 case 18 :
     183             :                 {
     184           0 :                     if ( rPresetSubType == "right-to-top" )
     185             :                     {
     186           0 :                         nPresetSubType = 3;
     187           0 :                         bTranslated = sal_True;
     188             :                     }
     189           0 :                     else if ( rPresetSubType == "right-to-bottom" )
     190             :                     {
     191           0 :                         nPresetSubType = 6;
     192           0 :                         bTranslated = sal_True;
     193             :                     }
     194           0 :                     else if ( rPresetSubType == "left-to-top" )
     195             :                     {
     196           0 :                         nPresetSubType = 9;
     197           0 :                         bTranslated = sal_True;
     198             :                     }
     199           0 :                     else if ( rPresetSubType == "left-to-bottom" )
     200             :                     {
     201           0 :                         nPresetSubType = 12;
     202           0 :                         bTranslated = sal_True;
     203             :                     }
     204             :                 }
     205           0 :                 break;
     206             :             }
     207             :         }
     208           0 :         if ( !bTranslated )
     209             :         {
     210           0 :             const convert_subtype* p = gConvertArray;
     211           0 :             while( p->mpStrSubType )
     212             :             {
     213           0 :                 if ( rPresetSubType.equalsAscii( p->mpStrSubType ) )
     214             :                 {
     215           0 :                     nPresetSubType = p->mnID;
     216           0 :                     bTranslated = sal_True;
     217           0 :                     break;
     218             :                 }
     219           0 :                 p++;
     220             :             }
     221             :         }
     222             :     }
     223           0 :     if ( !bTranslated )
     224           0 :         nPresetSubType = (sal_uInt32)rPresetSubType.toInt32();
     225           0 :     return nPresetSubType;
     226             : }
     227             : 
     228           0 : const sal_Char* AnimationExporter::FindTransitionName( const sal_Int16 nType, const sal_Int16 nSubType, const sal_Bool bDirection )
     229             : {
     230           0 :     const sal_Char* pRet = NULL;
     231           0 :     int             nFit = 0;
     232             : 
     233           0 :     const transition* p = gTransitions;
     234           0 :     while( p->mpName )
     235             :     {
     236           0 :         int nF = 0;
     237           0 :         if ( nType == p->mnType )
     238           0 :             nF += 4;
     239           0 :         if ( nSubType == p->mnSubType )
     240           0 :             nF += 2;
     241           0 :         if ( bDirection == p->mbDirection )
     242           0 :             nF += 1;
     243           0 :         if ( nF > nFit )
     244             :         {
     245           0 :             pRet = p->mpName;
     246           0 :             nFit = nF;
     247             :         }
     248           0 :         if ( nFit == 7 )    // maximum
     249           0 :             break;
     250           0 :         p++;
     251             :     }
     252           0 :     return pRet;
     253             : }
     254             : 
     255           0 : SvStream& WriteAnimationNode(SvStream& rOut, AnimationNode& rNode )
     256             : {
     257           0 :     rOut.WriteInt32( rNode.mnU1 );
     258           0 :     rOut.WriteInt32( rNode.mnRestart );
     259           0 :     rOut.WriteInt32( rNode.mnGroupType );
     260           0 :     rOut.WriteInt32( rNode.mnFill );
     261           0 :     rOut.WriteInt32( rNode.mnU3 );
     262           0 :     rOut.WriteInt32( rNode.mnU4 );
     263           0 :     rOut.WriteInt32( rNode.mnDuration );
     264           0 :     rOut.WriteInt32( rNode.mnNodeType );
     265             : 
     266           0 :     return rOut;
     267             : }
     268             : 
     269           0 : AnimationExporter::AnimationExporter( const EscherSolverContainer& rSolverContainer, ppt::ExSoundCollection& rExSoundCollection ) :
     270             :     mrSolverContainer   ( rSolverContainer ),
     271             :     mrExSoundCollection ( rExSoundCollection ),
     272           0 :     mnCurrentGroup(0)
     273             : {
     274           0 : }
     275             : 
     276             : 
     277             : 
     278           0 : sal_Int16 AnimationExporter::GetFillMode( const Reference< XAnimationNode >& xNode, const sal_Int16 nFillDefault )
     279             : {
     280           0 :     sal_Int16 nFill = xNode->getFill();
     281             :     //#i119699 <Animation> The animation effect "Emphasis->FlashBulb" play incorrectly in Aoo saves a .ppt to another .ppt and plays the saved one.
     282             :     //#i119740 <Animation> The animation effect "Entrance->Flash Once" fails to play in Aoo while Aoo saves a .ppt to another .ppt and plays the saved one.
     283           0 :     if ((xNode->getType() == AnimationNodeType::ANIMATE)
     284           0 :         ||(xNode->getType() == AnimationNodeType::SET)
     285           0 :         ||(xNode->getType() == AnimationNodeType::TRANSITIONFILTER))
     286             :     {
     287           0 :         if ( nFill == AnimationFill::DEFAULT )
     288           0 :             return nFill;
     289             :     }
     290             : 
     291           0 :     if ( ( nFill == AnimationFill::DEFAULT ) ||
     292             :         ( nFill == AnimationFill::INHERIT ) )
     293             :     {
     294           0 :         if ( nFill != AnimationFill::AUTO )
     295           0 :             nFill = nFillDefault;
     296             :     }
     297           0 :     if( nFill == AnimationFill::AUTO )
     298             :     {
     299           0 :         nFill = AnimationFill::REMOVE;
     300           0 :         sal_Bool bIsIndefiniteTiming = sal_True;
     301           0 :         Any aAny = xNode->getDuration();
     302           0 :         if( aAny.hasValue() )
     303             :         {
     304             :             Timing eTiming;
     305           0 :             if( aAny >>= eTiming )
     306           0 :                 bIsIndefiniteTiming = eTiming == Timing_INDEFINITE;
     307             :         }
     308           0 :         if ( bIsIndefiniteTiming )
     309             :         {
     310           0 :             aAny = xNode->getEnd();
     311           0 :             if( aAny.hasValue() )
     312             :             {
     313             :                 Timing eTiming;
     314           0 :                 if( aAny >>= eTiming )
     315           0 :                     bIsIndefiniteTiming = eTiming == Timing_INDEFINITE;
     316             :             }
     317           0 :             if ( bIsIndefiniteTiming )
     318             :             {
     319           0 :                 if ( !xNode->getRepeatCount().hasValue() )
     320             :                 {
     321           0 :                     aAny = xNode->getRepeatDuration();
     322           0 :                     if( aAny.hasValue() )
     323             :                     {
     324             :                         Timing eTiming;
     325           0 :                         if( aAny >>= eTiming )
     326           0 :                             bIsIndefiniteTiming = eTiming == Timing_INDEFINITE;
     327             :                     }
     328           0 :                     if ( bIsIndefiniteTiming )
     329           0 :                         nFill = AnimationFill::FREEZE;
     330             :                 }
     331             :             }
     332           0 :         }
     333             :     }
     334           0 :     return nFill;
     335             : }
     336             : 
     337           0 : void AnimationExporter::doexport( const Reference< XDrawPage >& xPage, SvStream& rStrm )
     338             : {
     339           0 :     Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY );
     340           0 :     if( xNodeSupplier.is() )
     341             :     {
     342           0 :         const Reference< XAnimationNode > xRootNode( xNodeSupplier->getAnimationNode() );
     343           0 :         if( xRootNode.is() )
     344             :         {
     345           0 :             processAfterEffectNodes( xRootNode );
     346           0 :             exportNode( rStrm, xRootNode, NULL, DFF_msofbtAnimGroup, 1, 0, sal_False, AnimationFill::AUTO );
     347           0 :         }
     348           0 :     }
     349           0 : }
     350             : 
     351           0 : void AnimationExporter::processAfterEffectNodes( const Reference< XAnimationNode >& xRootNode )
     352             : {
     353             :     try
     354             :     {
     355           0 :         Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
     356           0 :         Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
     357           0 :         while( xEnumeration->hasMoreElements() )
     358             :         {
     359           0 :             Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
     360             : 
     361           0 :             Reference< XEnumerationAccess > xEnumerationAccess2( xNode, UNO_QUERY );
     362           0 :             if ( xEnumerationAccess2.is() )
     363             :             {
     364           0 :                 Reference< XEnumeration > xEnumeration2( xEnumerationAccess2->createEnumeration(), UNO_QUERY_THROW );
     365           0 :                 while( xEnumeration2->hasMoreElements() )
     366             :                 {
     367           0 :                     Reference< XAnimationNode > xChildNode( xEnumeration2->nextElement(), UNO_QUERY_THROW );
     368             : 
     369           0 :                     Reference< XEnumerationAccess > xEnumerationAccess3( xChildNode, UNO_QUERY_THROW );
     370           0 :                     Reference< XEnumeration > xEnumeration3( xEnumerationAccess3->createEnumeration(), UNO_QUERY_THROW );
     371           0 :                     while( xEnumeration3->hasMoreElements() )
     372             :                     {
     373           0 :                         Reference< XAnimationNode > xChildNode2( xEnumeration3->nextElement(), UNO_QUERY_THROW );
     374             : 
     375           0 :                         Reference< XEnumerationAccess > xEnumerationAccess4( xChildNode2, UNO_QUERY_THROW );
     376           0 :                         Reference< XEnumeration > xEnumeration4( xEnumerationAccess4->createEnumeration(), UNO_QUERY_THROW );
     377           0 :                         while( xEnumeration4->hasMoreElements() )
     378             :                         {
     379           0 :                             Reference< XAnimationNode > xChildNode3( xEnumeration4->nextElement(), UNO_QUERY_THROW );
     380             : 
     381           0 :                             switch( xChildNode3->getType() )
     382             :                             {
     383             :                             // found an after effect
     384             :                             case AnimationNodeType::SET:
     385             :                             case AnimationNodeType::ANIMATECOLOR:
     386             :                                 {
     387           0 :                                     Reference< XAnimationNode > xMaster;
     388             : 
     389           0 :                                     Sequence< NamedValue > aUserData( xChildNode3->getUserData() );
     390           0 :                                     sal_Int32 nLength = aUserData.getLength();
     391           0 :                                     const NamedValue* p = aUserData.getConstArray();
     392             : 
     393           0 :                                     while( nLength-- )
     394             :                                     {
     395           0 :                                         if ( p->Name == "master-element" )
     396             :                                         {
     397           0 :                                             p->Value >>= xMaster;
     398           0 :                                             break;
     399             :                                         }
     400           0 :                                         p++;
     401             :                                     }
     402             : 
     403           0 :                                     AfterEffectNodePtr pAfterEffectNode( new AfterEffectNode( xChildNode3, xMaster ) );
     404           0 :                                     maAfterEffectNodes.push_back( pAfterEffectNode );
     405             :                                 }
     406           0 :                                 break;
     407             :                             }
     408           0 :                         }
     409           0 :                     }
     410           0 :                 }
     411             :             }
     412           0 :         }
     413             :     }
     414           0 :     catch( Exception& )
     415             :     {
     416             :         OSL_FAIL( "(@CL)AnimationExporter::processAfterEffectNodes(), exception cought!" );
     417             :     }
     418           0 : }
     419             : 
     420           0 : bool AnimationExporter::isAfterEffectNode( const Reference< XAnimationNode >& xNode ) const
     421             : {
     422           0 :     const std::list< AfterEffectNodePtr >::const_iterator aEnd( maAfterEffectNodes.end() );
     423           0 :     for (std::list< AfterEffectNodePtr >::const_iterator aIter( maAfterEffectNodes.begin() );
     424             :          aIter != aEnd ; ++aIter)
     425             :     {
     426           0 :         if( (*aIter)->mxNode == xNode )
     427           0 :             return true;
     428             :     }
     429           0 :     return false;
     430             : }
     431             : 
     432           0 : bool AnimationExporter::hasAfterEffectNode( const Reference< XAnimationNode >& xNode, Reference< XAnimationNode >& xAfterEffectNode ) const
     433             : {
     434           0 :     const std::list< AfterEffectNodePtr >::const_iterator aEnd( maAfterEffectNodes.end() );
     435           0 :     for (std::list< AfterEffectNodePtr >::const_iterator aIter( maAfterEffectNodes.begin() );
     436             :         aIter != aEnd ; ++aIter)
     437             :     {
     438           0 :         if( (*aIter)->mxMaster == xNode )
     439             :         {
     440           0 :             xAfterEffectNode = (*aIter)->mxNode;
     441           0 :             return true;
     442             :         }
     443             :     }
     444             : 
     445           0 :     return false;
     446             : }
     447             : 
     448             : // check if this group only contain empty groups. this may happen when
     449             : // after effect nodes are not exported at theire original position
     450           0 : bool AnimationExporter::isEmptyNode( const Reference< XAnimationNode >& xNode ) const
     451             : {
     452           0 :     if( xNode.is() ) switch( xNode->getType() )
     453             :     {
     454             :     case AnimationNodeType::PAR :
     455             :     case AnimationNodeType::SEQ :
     456             :     case AnimationNodeType::ITERATE :
     457             :         {
     458           0 :             Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
     459           0 :             if( xEnumerationAccess.is() )
     460             :             {
     461           0 :                 Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
     462           0 :                 if( xEnumeration.is() )
     463             :                 {
     464           0 :                     while( xEnumeration->hasMoreElements() )
     465             :                     {
     466           0 :                         Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
     467           0 :                         if( xChildNode.is() && !isEmptyNode( xChildNode ) )
     468           0 :                             return false;
     469           0 :                     }
     470           0 :                 }
     471           0 :             }
     472             :         }
     473           0 :         break;
     474             : 
     475             :     case AnimationNodeType::SET :
     476             :     case AnimationNodeType::ANIMATECOLOR :
     477           0 :         return isAfterEffectNode( xNode );
     478             :     default:
     479           0 :         return false;
     480             :     }
     481             : 
     482           0 :     return true;
     483             : }
     484             : 
     485           0 : void AnimationExporter::exportNode( SvStream& rStrm, Reference< XAnimationNode > xNode, const Reference< XAnimationNode >* pParent, const sal_uInt16 nContainerRecType,
     486             :                                     const sal_uInt16 nInstance, const sal_Int32 nGroupLevel, const sal_Bool bTakeBackInteractiveSequenceTiming, const sal_Int16 nFDef )
     487             : {
     488           0 :     if( (nGroupLevel == 4) && isEmptyNode( xNode ) )
     489           0 :         return;
     490             : 
     491           0 :     if ( ( nContainerRecType == DFF_msofbtAnimGroup ) && ( nGroupLevel == 2 ) && isEmptyNode( xNode ) )
     492           0 :         return;
     493             : 
     494           0 :     if( nContainerRecType == DFF_msofbtAnimGroup )
     495           0 :         mnCurrentGroup++;
     496             : 
     497           0 :     sal_Bool bTakeBackInteractiveSequenceTimingForChild = sal_False;
     498           0 :     sal_Int16 nFillDefault = GetFillMode( xNode, nFDef );
     499             : 
     500           0 :     bool bSkipChildren = false;
     501             : 
     502           0 :     Reference< XAnimationNode > xAudioNode;
     503             :     static sal_uInt32 nAudioGroup;
     504             : 
     505             :     {
     506           0 :         EscherExContainer aContainer( rStrm, nContainerRecType, nInstance );
     507           0 :         switch( xNode->getType() )
     508             :         {
     509             :             case AnimationNodeType::CUSTOM :
     510             :             {
     511           0 :                 exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     512           0 :                 exportAnimPropertySet( rStrm, xNode );
     513           0 :                 exportAnimEvent( rStrm, xNode, 0 );
     514           0 :                 exportAnimValue( rStrm, xNode, sal_False );
     515             :             }
     516           0 :             break;
     517             : 
     518             :             case AnimationNodeType::PAR :
     519             :             {
     520           0 :                 exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     521           0 :                 exportAnimPropertySet( rStrm, xNode );
     522           0 :                 sal_Int32 nFlags = nGroupLevel == 2 ? 0x10 : 0;
     523           0 :                 if ( bTakeBackInteractiveSequenceTiming )
     524           0 :                     nFlags |= 0x40;
     525           0 :                 exportAnimEvent( rStrm, xNode, nFlags );
     526           0 :                 exportAnimValue( rStrm, xNode, nGroupLevel == 4 );
     527             :             }
     528           0 :             break;
     529             : 
     530             :             case AnimationNodeType::SEQ :
     531             :             {
     532           0 :                 exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     533           0 :                 sal_Int16 nNodeType = exportAnimPropertySet( rStrm, xNode );
     534           0 :                 sal_Int32 nFlags = 12;
     535           0 :                 if ( ( nGroupLevel == 1 ) && ( nNodeType == ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE ) )
     536             :                 {
     537           0 :                     nFlags |= 0x20;
     538           0 :                     bTakeBackInteractiveSequenceTimingForChild = sal_True;
     539             :                 }
     540           0 :                 exportAnimAction( rStrm, xNode );
     541           0 :                 exportAnimEvent( rStrm, xNode, nFlags );
     542           0 :                 exportAnimValue( rStrm, xNode, sal_False );
     543             :             }
     544           0 :             break;
     545             : 
     546             :             case AnimationNodeType::ITERATE :
     547             :             {
     548             :                 {
     549           0 :                     EscherExAtom aAnimNodeExAtom( rStrm, DFF_msofbtAnimNode );
     550           0 :                     AnimationNode aAnim;
     551           0 :                     memset( &aAnim, 0, sizeof( aAnim ) );
     552           0 :                     aAnim.mnGroupType = mso_Anim_GroupType_PAR;
     553           0 :                     aAnim.mnNodeType = 1;
     554             :                     // attribute Restart
     555           0 :                     switch( xNode->getRestart() )
     556             :                     {
     557             :                         default:
     558           0 :                         case AnimationRestart::DEFAULT : aAnim.mnRestart = 0; break;
     559           0 :                         case AnimationRestart::ALWAYS  : aAnim.mnRestart = 1; break;
     560           0 :                         case AnimationRestart::WHEN_NOT_ACTIVE : aAnim.mnRestart = 2; break;
     561           0 :                         case AnimationRestart::NEVER : aAnim.mnRestart = 3; break;
     562             :                     }
     563             :                     // attribute Fill
     564           0 :                     switch( xNode->getFill() )
     565             :                     {
     566             :                         default:
     567           0 :                         case AnimationFill::DEFAULT : aAnim.mnFill = 0; break;
     568           0 :                         case AnimationFill::REMOVE : aAnim.mnFill = 1; break;
     569           0 :                         case AnimationFill::FREEZE : aAnim.mnFill = 2; break;
     570           0 :                         case AnimationFill::HOLD : aAnim.mnFill = 3; break;
     571           0 :                         case AnimationFill::TRANSITION : aAnim.mnFill = 4; break;
     572             :                     }
     573           0 :                     WriteAnimationNode( rStrm, aAnim );
     574             :                 }
     575           0 :                 exportIterate( rStrm, xNode );
     576           0 :                 exportAnimPropertySet( rStrm, xNode );
     577           0 :                 exportAnimEvent( rStrm, xNode, 0 );
     578           0 :                 exportAnimValue( rStrm, xNode, sal_False );
     579             :             }
     580           0 :             break;
     581             : 
     582             :             case AnimationNodeType::ANIMATE :
     583             :             {
     584           0 :                 exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     585           0 :                 exportAnimPropertySet( rStrm, xNode );
     586           0 :                 exportAnimEvent( rStrm, xNode, 0 );
     587           0 :                 exportAnimValue( rStrm, xNode, sal_False );
     588           0 :                 exportAnimate( rStrm, xNode );
     589             :             }
     590           0 :             break;
     591             : 
     592             :             case AnimationNodeType::SET :
     593             :             {
     594           0 :                 bool bIsAfterEffectNode( isAfterEffectNode( xNode ) );
     595           0 :                 if( (nGroupLevel != 4) || !bIsAfterEffectNode )
     596             :                 {
     597           0 :                     exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     598           0 :                     exportAnimPropertySet( rStrm, xNode );
     599           0 :                     exportAnimateSet( rStrm, xNode, bIsAfterEffectNode ? AFTEREFFECT_SET : AFTEREFFECT_NONE );
     600           0 :                     exportAnimEvent( rStrm, xNode, 0 );
     601           0 :                     exportAnimValue( rStrm, xNode, sal_False );
     602             :                 }
     603             :                 else
     604             :                 {
     605           0 :                     bSkipChildren = true;
     606             :                 }
     607             :             }
     608           0 :             break;
     609             : 
     610             :             case AnimationNodeType::ANIMATEMOTION :
     611             :             {
     612           0 :                 exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     613           0 :                 exportAnimPropertySet( rStrm, xNode );
     614           0 :                 exportAnimateMotion( rStrm, xNode );
     615           0 :                 exportAnimEvent( rStrm, xNode, 0 );
     616           0 :                 exportAnimValue( rStrm, xNode, sal_False );
     617             :             }
     618           0 :             break;
     619             : 
     620             :             case AnimationNodeType::ANIMATECOLOR :
     621             :             {
     622           0 :                 bool bIsAfterEffectNode( isAfterEffectNode( xNode ) );
     623           0 :                 if( (nGroupLevel != 4) || !bIsAfterEffectNode )
     624             :                 {
     625           0 :                     if( bIsAfterEffectNode )
     626           0 :                         xNode = createAfterEffectNodeClone( xNode );
     627             : 
     628           0 :                     exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     629           0 :                     exportAnimPropertySet( rStrm, xNode );
     630           0 :                     exportAnimateColor( rStrm, xNode, bIsAfterEffectNode ? AFTEREFFECT_COLOR : AFTEREFFECT_NONE );
     631           0 :                     exportAnimEvent( rStrm, xNode, 0 );
     632           0 :                     exportAnimValue( rStrm, xNode, sal_False );
     633             :                 }
     634             :                 else
     635             :                 {
     636           0 :                     bSkipChildren = true;
     637             :                 }
     638             :             }
     639           0 :             break;
     640             : 
     641             :             case AnimationNodeType::ANIMATETRANSFORM :
     642             :             {
     643           0 :                 exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     644           0 :                 exportAnimPropertySet( rStrm, xNode );
     645           0 :                 exportAnimateTransform( rStrm, xNode );
     646           0 :                 exportAnimEvent( rStrm, xNode, 0 );
     647           0 :                 exportAnimValue( rStrm, xNode, sal_False );
     648             :             }
     649           0 :             break;
     650             : 
     651             :             case AnimationNodeType::TRANSITIONFILTER :
     652             :             {
     653           0 :                 exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     654           0 :                 exportAnimPropertySet( rStrm, xNode );
     655           0 :                 exportAnimEvent( rStrm, xNode, 0 );
     656           0 :                 exportAnimValue( rStrm, xNode, sal_False );
     657           0 :                 exportTransitionFilter( rStrm, xNode );
     658             :             }
     659           0 :             break;
     660             : 
     661             :             case AnimationNodeType::AUDIO :     // #i58428#
     662             :             {
     663           0 :                 exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
     664           0 :                 exportAnimPropertySet( rStrm, xNode );
     665             : 
     666           0 :                 Reference< XAudio > xAudio( xNode, UNO_QUERY );
     667           0 :                 if( xAudio.is() )
     668             :                 {
     669           0 :                     Any aAny( xAudio->getSource() );
     670           0 :                     OUString aURL;
     671             : 
     672           0 :                     if ( ( aAny >>= aURL)  &&  !aURL.isEmpty()  )
     673             :                     {
     674           0 :                         sal_Int32 nU1 = 2;
     675           0 :                         sal_Int32 nTrigger = 3;
     676           0 :                         sal_Int32 nU3 = nAudioGroup;
     677           0 :                         sal_Int32 nBegin = 0;
     678             :                         {
     679           0 :                             EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, 1 );
     680             :                             {
     681           0 :                                 EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger );
     682           0 :                                 rStrm.WriteInt32( nU1 ).WriteInt32( nTrigger ).WriteInt32( nU3 ).WriteInt32( nBegin );
     683           0 :                             }
     684             :                         }
     685           0 :                         nU1 = 1;
     686           0 :                         nTrigger = 0xb;
     687           0 :                         nU3 = 0;
     688             :                         {
     689           0 :                             EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, 2 );
     690             :                             {
     691           0 :                                 EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger );
     692           0 :                                 rStrm.WriteInt32( nU1 ).WriteInt32( nTrigger ).WriteInt32( nU3 ).WriteInt32( nBegin );
     693           0 :                             }
     694             :                         }
     695           0 :                         EscherExContainer aAnimateTargetElement( rStrm, DFF_msofbtAnimateTargetElement );
     696             :                         {
     697           0 :                             sal_uInt32 nRefMode = 3;
     698           0 :                             sal_uInt32 nRefType = 2;
     699           0 :                             sal_uInt32 nRefId = mrExSoundCollection.GetId( aURL );
     700           0 :                             sal_Int32 begin = -1;
     701           0 :                             sal_Int32 end = -1;
     702             : 
     703           0 :                             EscherExAtom aAnimReference( rStrm, DFF_msofbtAnimReference );
     704           0 :                             rStrm.WriteUInt32( nRefMode ).WriteUInt32( nRefType ).WriteUInt32( nRefId ).WriteInt32( begin ).WriteInt32( end );
     705           0 :                         }
     706           0 :                     }
     707             :                 }
     708           0 :                 exportAnimValue( rStrm, xNode, sal_False );
     709             :             }
     710           0 :             break;
     711             :         }
     712           0 :         if( !bSkipChildren )
     713             :         {
     714             :             // export after effect node if one exists for this node
     715           0 :             Reference< XAnimationNode > xAfterEffectNode;
     716           0 :             if( hasAfterEffectNode( xNode, xAfterEffectNode ) )
     717             :             {
     718           0 :                 exportNode( rStrm, xAfterEffectNode, &xNode, DFF_msofbtAnimSubGoup, 1, nGroupLevel + 1, bTakeBackInteractiveSequenceTimingForChild, nFillDefault );
     719             :             }
     720             : 
     721           0 :             Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
     722           0 :             if( xEnumerationAccess.is() )
     723             :             {
     724           0 :                 Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
     725           0 :                 if( xEnumeration.is() )
     726             :                 {
     727           0 :                     while( xEnumeration->hasMoreElements() )
     728             :                     {
     729           0 :                         Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
     730           0 :                         if( xChildNode.is() )
     731             :                         {
     732           0 :                             if ( xChildNode->getType() == AnimationNodeType::AUDIO )
     733             :                             {
     734           0 :                                 xAudioNode = xChildNode;
     735           0 :                                 nAudioGroup = mnCurrentGroup;
     736             :                             }
     737             :                             else
     738           0 :                                 exportNode( rStrm, xChildNode, &xNode, DFF_msofbtAnimGroup, 1, nGroupLevel + 1, bTakeBackInteractiveSequenceTimingForChild, nFillDefault );
     739             :                         }
     740           0 :                     }
     741           0 :                 }
     742           0 :             }
     743           0 :         }
     744             :     }
     745           0 :     if ( xAudioNode.is() )
     746           0 :         exportNode( rStrm, xAudioNode, &xNode, DFF_msofbtAnimGroup, 1, nGroupLevel, bTakeBackInteractiveSequenceTimingForChild, nFillDefault );
     747             : 
     748           0 :     if( xNode->getType() == AnimationNodeType::ITERATE )
     749           0 :         aTarget = Any();
     750             : }
     751             : 
     752           0 : Reference< XAnimationNode > AnimationExporter::createAfterEffectNodeClone( const Reference< XAnimationNode >& xNode ) const
     753             : {
     754             :     try
     755             :     {
     756           0 :         Reference< ::com::sun::star::util::XCloneable > xClonable( xNode, UNO_QUERY_THROW );
     757           0 :         Reference< XAnimationNode > xCloneNode( xClonable->createClone(), UNO_QUERY_THROW );
     758             : 
     759           0 :         Any aEmpty;
     760           0 :         xCloneNode->setBegin( aEmpty );
     761             : 
     762           0 :         return xCloneNode;
     763             :     }
     764           0 :     catch( Exception& )
     765             :     {
     766             :         OSL_FAIL("(@CL)sd::ppt::AnimationExporter::createAfterEffectNodeClone(), could not create clone!" );
     767             :     }
     768           0 :     return xNode;
     769             : }
     770             : 
     771           0 : sal_Bool AnimationExporter::GetNodeType( const Reference< XAnimationNode >& xNode, sal_Int16& nType )
     772             : {
     773             :     // trying to get the nodetype
     774           0 :     Sequence< NamedValue > aUserData = xNode->getUserData();
     775           0 :     if ( aUserData.getLength() )
     776             :     {
     777           0 :     const NamedValue* p = aUserData.getConstArray();
     778           0 :     sal_Int32 nLength = aUserData.getLength();
     779           0 :     while( nLength-- )
     780             :     {
     781           0 :         if ( p->Name == "node-type" )
     782             :         {
     783           0 :         if ( p->Value >>= nType )
     784           0 :             return sal_True;
     785             :         }
     786             :     }
     787             :     }
     788             : 
     789           0 :     return sal_False;
     790             : }
     791             : 
     792           0 : void AnimationExporter::exportAnimNode( SvStream& rStrm, const Reference< XAnimationNode >& xNode,
     793             :         const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >*, const sal_Int32, const sal_Int16 nFillDefault )
     794             : {
     795           0 :     EscherExAtom    aAnimNodeExAtom( rStrm, DFF_msofbtAnimNode );
     796           0 :     AnimationNode   aAnim;
     797           0 :     memset( &aAnim, 0, sizeof( aAnim ) );
     798             : 
     799             :     // attribute Restart
     800           0 :     switch( xNode->getRestart() )
     801             :     {
     802             :         default:
     803           0 :         case AnimationRestart::DEFAULT : aAnim.mnRestart = 0; break;
     804           0 :         case AnimationRestart::ALWAYS  : aAnim.mnRestart = 1; break;
     805           0 :         case AnimationRestart::WHEN_NOT_ACTIVE : aAnim.mnRestart = 2; break;
     806           0 :         case AnimationRestart::NEVER : aAnim.mnRestart = 3; break;
     807             :     }
     808             : 
     809           0 :     switch( nFillDefault )
     810             :     {
     811             :         default:
     812           0 :         case AnimationFill::DEFAULT : aAnim.mnFill = 0; break;
     813           0 :         case AnimationFill::REMOVE : aAnim.mnFill = 1; break;
     814             :         case AnimationFill::FREEZE :
     815           0 :         case AnimationFill::HOLD :   aAnim.mnFill = 3; break;
     816           0 :         case AnimationFill::TRANSITION : aAnim.mnFill = 4; break;
     817             :     }
     818             :     // attribute Duration
     819           0 :     double fDuration = 0.0;
     820             :     com::sun::star::animations::Timing eTiming;
     821           0 :     if ( xNode->getDuration() >>= eTiming )
     822             :     {
     823           0 :         if ( eTiming == Timing_INDEFINITE )
     824           0 :             aAnim.mnDuration = -1;
     825             :     }
     826           0 :     else if ( xNode->getDuration() >>= fDuration )
     827             :     {
     828           0 :         aAnim.mnDuration = (sal_Int32)( fDuration * 1000.0 );
     829             :     }
     830             :     else
     831           0 :         aAnim.mnDuration = -1;
     832             : 
     833             :     // NodeType, NodeGroup
     834           0 :     aAnim.mnNodeType = 1;
     835           0 :     aAnim.mnGroupType = mso_Anim_GroupType_SEQ;
     836           0 :     switch( xNode->getType() )
     837             :     {
     838             :         case AnimationNodeType::PAR :       // PASSTROUGH!!! (as it was intended)
     839           0 :             aAnim.mnGroupType = mso_Anim_GroupType_PAR;
     840             :         case AnimationNodeType::SEQ :
     841             :         {
     842           0 :             sal_Int16 nType = 0;
     843           0 :             if( GetNodeType( xNode, nType ) )
     844           0 :             switch( nType )
     845             :             {
     846           0 :                 case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT : aAnim.mnNodeType = 0x12; break;
     847           0 :                 case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE : aAnim.mnNodeType = 0x18; break;
     848             :             }
     849             :         }
     850           0 :         break;
     851             : 
     852             :         case AnimationNodeType::ANIMATE :
     853             :         case AnimationNodeType::SET :
     854             : 
     855             :         case AnimationNodeType::CUSTOM :
     856             :         case AnimationNodeType::ITERATE :
     857             :         case AnimationNodeType::ANIMATEMOTION :
     858             :         case AnimationNodeType::ANIMATECOLOR :
     859             :         case AnimationNodeType::ANIMATETRANSFORM :
     860             :         {
     861           0 :             aAnim.mnGroupType = mso_Anim_GroupType_NODE;
     862           0 :             aAnim.mnNodeType  = mso_Anim_Behaviour_ANIMATION;
     863             :         }
     864           0 :         break;
     865             : 
     866             :         case AnimationNodeType::AUDIO :
     867             :         {
     868           0 :             aAnim.mnGroupType = mso_Anim_GroupType_MEDIA;
     869           0 :             aAnim.mnNodeType  = mso_Anim_Behaviour_ANIMATION;
     870             :         }
     871           0 :         break;
     872             : 
     873             :         case AnimationNodeType::TRANSITIONFILTER :
     874             :         {
     875           0 :             aAnim.mnGroupType = mso_Anim_GroupType_NODE;
     876           0 :             aAnim.mnNodeType  = mso_Anim_Behaviour_FILTER;
     877             :         }
     878           0 :         break;
     879             :     }
     880             : 
     881           0 :     WriteAnimationNode( rStrm, aAnim );
     882           0 : }
     883             : 
     884           0 : void AnimationExporter::GetUserData( const Sequence< NamedValue >& rUserData, const Any ** pAny, sal_Size nLen )
     885             : {
     886             :     // storing user data into pAny, to allow direct access later
     887           0 :     memset( pAny, 0, nLen );
     888           0 :     if ( rUserData.getLength() )
     889             :     {
     890           0 :     const NamedValue* p = rUserData.getConstArray();
     891           0 :     sal_Int32 nLength = rUserData.getLength();
     892           0 :     while( nLength-- )
     893             :     {
     894           0 :         if ( p->Name == "node-type" )
     895             :         {
     896           0 :         pAny[ DFF_ANIM_NODE_TYPE ] = &(p->Value);
     897             :         }
     898           0 :         else if ( p->Name == "preset-class" )
     899             :         {
     900           0 :         pAny[ DFF_ANIM_PRESET_CLASS ] = &(p->Value);
     901             :         }
     902           0 :         else if ( p->Name == "preset-id" )
     903             :         {
     904           0 :         pAny[ DFF_ANIM_PRESET_ID ] = &(p->Value);
     905             :         }
     906           0 :         else if ( p->Name == "preset-sub-type" )
     907             :         {
     908           0 :         pAny[ DFF_ANIM_PRESET_SUB_TYPE ] = &(p->Value);
     909             :         }
     910           0 :         else if ( p->Name == "master-element" )
     911             :         {
     912           0 :         pAny[ DFF_ANIM_AFTEREFFECT ] = &(p->Value);;
     913             :         }
     914           0 :         p++;
     915             :     }
     916             :     }
     917           0 : }
     918             : 
     919           0 : sal_uInt32 AnimationExporter::GetPresetID( const OUString& rPreset, sal_uInt32 nAPIPresetClass, sal_Bool& bPresetId )
     920             : {
     921           0 :     sal_uInt32 nPresetId = 0;
     922           0 :     bPresetId = sal_False;
     923             : 
     924           0 :     if ( rPreset.match( OUString( "ppt_" ), 0 ) )
     925             :     {
     926           0 :     sal_Int32 nLast = rPreset.lastIndexOf( '_' );
     927           0 :     if ( ( nLast != -1 ) && ( ( nLast + 1 ) < rPreset.getLength() ) )
     928             :     {
     929           0 :         OUString aNumber( rPreset.copy( nLast + 1 ) );
     930           0 :         nPresetId = aNumber.toInt32();
     931           0 :         bPresetId = sal_True;
     932             :     }
     933             :     }
     934             :     else
     935             :     {
     936           0 :     const preset_maping* p = gPresetMaping;
     937           0 :     while( p->mpStrPresetId && ((p->mnPresetClass != (sal_Int32)nAPIPresetClass) || !rPreset.equalsAscii( p->mpStrPresetId )) )
     938           0 :         p++;
     939             : 
     940           0 :     if( p->mpStrPresetId )
     941             :     {
     942           0 :         nPresetId = p->mnPresetId;
     943           0 :         bPresetId = sal_True;
     944             :     }
     945             :     }
     946             : 
     947           0 :     return nPresetId;
     948             : }
     949             : 
     950           0 : sal_Int16 AnimationExporter::exportAnimPropertySet( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
     951             : {
     952           0 :     sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT;
     953             : 
     954           0 :     EscherExContainer aAnimPropertySet( rStrm, DFF_msofbtAnimPropertySet );
     955             : 
     956           0 :     Reference< XAnimationNode > xMaster;
     957             : 
     958           0 :     Any aMasterRel, aOverride, aRunTimeContext;
     959             : 
     960             :     // storing user data into pAny, to allow direct access later
     961           0 :     const Sequence< NamedValue > aUserData = xNode->getUserData();
     962             :     const ::com::sun::star::uno::Any* pAny[ DFF_ANIM_PROPERTY_ID_COUNT ];
     963           0 :     GetUserData( aUserData, pAny, sizeof( pAny ) );
     964             : 
     965           0 :     if( pAny[ DFF_ANIM_AFTEREFFECT ] )
     966           0 :         ( *pAny[ DFF_ANIM_AFTEREFFECT ] ) >>= xMaster;
     967             : 
     968             :     // calculate master-rel
     969           0 :     if( xMaster.is() )
     970             :     {
     971           0 :         sal_Int32 nMasterRel = 2;
     972           0 :         if( xNode.is() && xMaster.is() && (xNode->getParent() == xMaster->getParent() ) )
     973           0 :             nMasterRel = 0;
     974             : 
     975           0 :         aMasterRel <<= nMasterRel;
     976             : 
     977           0 :         pAny[ DFF_ANIM_MASTERREL ] = &aMasterRel;
     978             : 
     979           0 :         aOverride <<= (sal_Int32)1;
     980           0 :         pAny[ DFF_ANIM_OVERRIDE ] = &aOverride;
     981             : 
     982           0 :         aRunTimeContext <<= (sal_Int32)1;
     983           0 :         pAny[ DFF_ANIM_RUNTIMECONTEXT ] = &aRunTimeContext;
     984             :     }
     985             : 
     986             :     // the order is important
     987           0 :     if ( pAny[ DFF_ANIM_NODE_TYPE ] )
     988             :     {
     989           0 :         if ( *pAny[ DFF_ANIM_NODE_TYPE ] >>= nNodeType )
     990             :         {
     991           0 :             sal_uInt32 nPPTNodeType = DFF_ANIM_NODE_TYPE_ON_CLICK;
     992           0 :             switch( nNodeType )
     993             :             {
     994           0 :                 case ::com::sun::star::presentation::EffectNodeType::ON_CLICK : nPPTNodeType = DFF_ANIM_NODE_TYPE_ON_CLICK; break;
     995           0 :                 case ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS : nPPTNodeType = DFF_ANIM_NODE_TYPE_WITH_PREVIOUS; break;
     996           0 :                 case ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS : nPPTNodeType = DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS; break;
     997           0 :                 case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE : nPPTNodeType = DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE; break;
     998           0 :                 case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT : nPPTNodeType = DFF_ANIM_NODE_TYPE_TIMING_ROOT; break;
     999           0 :                 case ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE: nPPTNodeType = DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ; break;
    1000             :             }
    1001           0 :             exportAnimPropertyuInt32( rStrm, DFF_ANIM_NODE_TYPE, nPPTNodeType, TRANSLATE_NONE );
    1002             :         }
    1003             :     }
    1004           0 :     sal_uInt32 nPresetId = 0;
    1005           0 :     sal_uInt32 nPresetSubType = 0;
    1006           0 :     sal_uInt32 nAPIPresetClass = EffectPresetClass::CUSTOM;
    1007           0 :     sal_uInt32 nPresetClass = DFF_ANIM_PRESS_CLASS_USER_DEFINED;
    1008             :     sal_Bool bPresetClass, bPresetId, bPresetSubType;
    1009           0 :     bPresetId = bPresetClass = bPresetSubType = sal_False;
    1010             : 
    1011           0 :     if ( pAny[ DFF_ANIM_PRESET_CLASS ] )
    1012             :     {
    1013           0 :         if ( *pAny[ DFF_ANIM_PRESET_CLASS ] >>= nAPIPresetClass )
    1014             :         {
    1015             :             sal_uInt8 nPPTPresetClass;
    1016           0 :             switch( nAPIPresetClass )
    1017             :             {
    1018           0 :                 case EffectPresetClass::ENTRANCE : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_ENTRANCE; break;
    1019           0 :                 case EffectPresetClass::EXIT : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_EXIT; break;
    1020           0 :                 case EffectPresetClass::EMPHASIS : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_EMPHASIS; break;
    1021           0 :                 case EffectPresetClass::MOTIONPATH : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_MOTIONPATH; break;
    1022           0 :                 case EffectPresetClass::OLEACTION : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_OLE_ACTION; break;
    1023           0 :                 case EffectPresetClass::MEDIACALL : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_MEDIACALL; break;
    1024             :                 default :
    1025           0 :                     nPPTPresetClass = DFF_ANIM_PRESS_CLASS_USER_DEFINED;
    1026             :             }
    1027           0 :             nPresetClass = nPPTPresetClass;
    1028           0 :             bPresetClass = sal_True;
    1029             :         }
    1030             :     }
    1031           0 :     if ( pAny[ DFF_ANIM_PRESET_ID ] )
    1032             :     {
    1033           0 :         OUString sPreset;
    1034           0 :         if ( *pAny[ DFF_ANIM_PRESET_ID ] >>= sPreset )
    1035           0 :             nPresetId = GetPresetID( sPreset, nAPIPresetClass, bPresetId );
    1036             :     }
    1037             : 
    1038           0 :     if ( pAny[ DFF_ANIM_PRESET_SUB_TYPE ] )
    1039             :     {
    1040           0 :         OUString sPresetSubType;
    1041           0 :         if ( *pAny[ DFF_ANIM_PRESET_SUB_TYPE ] >>= sPresetSubType )
    1042             :         {
    1043           0 :             nPresetSubType = TranslatePresetSubType( nPresetClass, nPresetId, sPresetSubType );
    1044           0 :             bPresetSubType = sal_True;
    1045           0 :         }
    1046             :     }
    1047           0 :     if ( bPresetId )
    1048           0 :         exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_ID, nPresetId, TRANSLATE_NONE );
    1049           0 :     if ( bPresetSubType )
    1050           0 :         exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_SUB_TYPE, nPresetSubType, TRANSLATE_NONE );
    1051           0 :     if ( bPresetClass )
    1052           0 :         exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_CLASS, nPresetClass, TRANSLATE_NONE );
    1053             : 
    1054           0 :     if ( pAny[ DFF_ANIM_ID ] )
    1055             :     {
    1056             :         // TODO DFF_ANIM_ID
    1057             :     }
    1058             : 
    1059           0 :     if ( pAny[ DFF_ANIM_AFTEREFFECT ] )
    1060             :     {
    1061           0 :         sal_Bool bAfterEffect = sal_False;
    1062           0 :         if ( *pAny[ DFF_ANIM_AFTEREFFECT ] >>= bAfterEffect )
    1063           0 :             exportAnimPropertyByte( rStrm, DFF_ANIM_AFTEREFFECT, bAfterEffect, TRANSLATE_NONE );
    1064             :     }
    1065             : 
    1066           0 :     if ( pAny[ DFF_ANIM_RUNTIMECONTEXT ] )
    1067             :     {
    1068           0 :         sal_Int32 nRunTimeContext = 0;
    1069           0 :         if ( *pAny[ DFF_ANIM_RUNTIMECONTEXT ] >>= nRunTimeContext )
    1070           0 :             exportAnimPropertyuInt32( rStrm, DFF_ANIM_RUNTIMECONTEXT, nRunTimeContext, TRANSLATE_NONE );
    1071             :     }
    1072           0 :     if ( pAny[ DFF_ANIM_PATH_EDIT_MODE ] )
    1073             :     {
    1074             :         // TODO DFF_ANIM_ID
    1075             :     }
    1076             : 
    1077           0 :     if( !xMaster.is() )
    1078             :     {
    1079           0 :         Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
    1080           0 :         if( xColor.is() )
    1081             :         {
    1082             : 
    1083           0 :             sal_Bool bDirection = !xColor->getDirection();
    1084           0 :             exportAnimPropertyuInt32( rStrm, DFF_ANIM_DIRECTION, bDirection, TRANSLATE_NONE );
    1085           0 :         }
    1086             :     }
    1087             : 
    1088           0 :     if ( pAny[ DFF_ANIM_OVERRIDE ] )
    1089             :     {
    1090           0 :         sal_Int32 nOverride = 0;
    1091           0 :         if ( *pAny[ DFF_ANIM_OVERRIDE ] >>= nOverride )
    1092           0 :             exportAnimPropertyuInt32( rStrm, DFF_ANIM_OVERRIDE, nOverride, TRANSLATE_NONE );
    1093             :     }
    1094             : 
    1095           0 :     if ( pAny[ DFF_ANIM_MASTERREL ] )
    1096             :     {
    1097           0 :         sal_Int32 nMasterRel = 0;
    1098           0 :         if ( *pAny[ DFF_ANIM_MASTERREL ] >>= nMasterRel )
    1099           0 :             exportAnimPropertyuInt32( rStrm, DFF_ANIM_MASTERREL, nMasterRel, TRANSLATE_NONE );
    1100             :     }
    1101             : 
    1102             : /* todo
    1103             :     Reference< XAudio > xAudio( xNode, UNO_QUERY );
    1104             :     if( xAudio.is() )
    1105             :     {
    1106             :         sal_Int16 nEndAfterSlide = 0;
    1107             :         nEndAfterSlide = xAudio->getEndAfterSlide();
    1108             :         exportAnimPropertyuInt32( rStrm, DFF_ANIM_ENDAFTERSLIDE, nEndAfterSlide, TRANSLATE_NONE );
    1109             :     }
    1110             : */
    1111           0 :     Reference< XAnimate > xAnim( xNode, UNO_QUERY );
    1112           0 :     if( xAnim.is() )
    1113             :     {
    1114             :         // TODO: DFF_ANIM_TIMEFILTER
    1115             :     }
    1116           0 :     if ( pAny[ DFF_ANIM_EVENT_FILTER ] )
    1117             :     {
    1118             :         // TODO DFF_ANIM_EVENT_FILTER
    1119             :     }
    1120           0 :     if ( pAny[ DFF_ANIM_VOLUME ] )
    1121             :     {
    1122             :         // TODO DFF_ANIM_VOLUME
    1123             :     }
    1124           0 :     return nNodeType;
    1125             : }
    1126             : 
    1127           0 : sal_Bool AnimationExporter::exportAnimProperty( SvStream& rStrm, const sal_uInt16 nPropertyId, const ::com::sun::star::uno::Any& rAny, const TranslateMode eTranslateMode )
    1128             : {
    1129           0 :     sal_Bool bRet = sal_False;
    1130           0 :     if ( rAny.hasValue() )
    1131             :     {
    1132           0 :         switch( rAny.getValueType().getTypeClass() )
    1133             :         {
    1134             :             case ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT :
    1135             :             case ::com::sun::star::uno::TypeClass_SHORT :
    1136             :             case ::com::sun::star::uno::TypeClass_UNSIGNED_LONG :
    1137             :             case ::com::sun::star::uno::TypeClass_LONG :
    1138             :             {
    1139           0 :                 sal_Int32 nVal = 0;
    1140           0 :                 if ( rAny >>= nVal )
    1141             :                 {
    1142           0 :                     exportAnimPropertyuInt32( rStrm, nPropertyId, nVal, eTranslateMode );
    1143           0 :                     bRet = sal_True;
    1144             :                 }
    1145             :             }
    1146           0 :             break;
    1147             : 
    1148             :             case ::com::sun::star::uno::TypeClass_DOUBLE :
    1149             :             {
    1150           0 :                 double fVal = 0.0;
    1151           0 :                 if ( rAny >>= fVal )
    1152             :                 {
    1153           0 :                     exportAnimPropertyFloat( rStrm, nPropertyId, fVal, eTranslateMode );
    1154           0 :                     bRet = sal_True;
    1155             :                 }
    1156             :             }
    1157           0 :             break;
    1158             :             case ::com::sun::star::uno::TypeClass_FLOAT :
    1159             :             {
    1160           0 :                 float fVal = 0.0;
    1161           0 :                 if ( rAny >>= fVal )
    1162             :                 {
    1163           0 :                     if ( eTranslateMode & TRANSLATE_NUMBER_TO_STRING )
    1164             :                     {
    1165           0 :                         Any aAny;
    1166           0 :                         OUString aNumber( OUString::number( fVal ) );
    1167           0 :                         aAny <<= aNumber;
    1168           0 :                         exportAnimPropertyString( rStrm, nPropertyId, aNumber, eTranslateMode );
    1169             :                     }
    1170             :                     else
    1171             :                     {
    1172           0 :                         exportAnimPropertyFloat( rStrm, nPropertyId, fVal, eTranslateMode );
    1173           0 :                         bRet = sal_True;
    1174             :                     }
    1175             :                 }
    1176             :             }
    1177           0 :             break;
    1178             :             case ::com::sun::star::uno::TypeClass_STRING :
    1179             :             {
    1180           0 :                 OUString aStr;
    1181           0 :                 if ( rAny >>= aStr )
    1182             :                 {
    1183           0 :                     exportAnimPropertyString( rStrm, nPropertyId, aStr, eTranslateMode );
    1184           0 :                     bRet = sal_True;
    1185           0 :                 }
    1186             :             }
    1187           0 :             break;
    1188             :             default:
    1189           0 :                 break;
    1190             :         }
    1191             :     }
    1192           0 :     return bRet;
    1193             : }
    1194           0 : void AnimationExporter::exportAnimPropertyString( SvStream& rStrm, const sal_uInt16 nPropertyId, const OUString& rVal, const TranslateMode eTranslateMode )
    1195             : {
    1196           0 :     EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId );
    1197           0 :     sal_uInt8 nType = DFF_ANIM_PROP_TYPE_UNISTRING;
    1198           0 :     rStrm.WriteUChar( nType );
    1199           0 :     OUString aStr( rVal );
    1200           0 :     if ( eTranslateMode != TRANSLATE_NONE )
    1201           0 :         ImplTranslateAttribute( aStr, eTranslateMode );
    1202           0 :     writeZString( rStrm, aStr );
    1203           0 : }
    1204             : 
    1205           0 : void AnimationExporter::exportAnimPropertyFloat( SvStream& rStrm, const sal_uInt16 nPropertyId, const double& rVal, const TranslateMode )
    1206             : {
    1207           0 :     EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId );
    1208           0 :     sal_uInt8 nType = DFF_ANIM_PROP_TYPE_FLOAT;
    1209           0 :     float fFloat = (float)rVal;
    1210           0 :     rStrm.WriteUChar( nType )
    1211           0 :          .WriteFloat( fFloat );
    1212           0 : }
    1213             : 
    1214           0 : void AnimationExporter::exportAnimPropertyuInt32( SvStream& rStrm, const sal_uInt16 nPropertyId, const sal_uInt32 nVal, const TranslateMode )
    1215             : {
    1216           0 :     EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId );
    1217           0 :     sal_uInt8 nType = DFF_ANIM_PROP_TYPE_INT32 ;
    1218           0 :     rStrm.WriteUChar( nType )
    1219           0 :          .WriteUInt32( nVal );
    1220           0 : }
    1221             : 
    1222           0 : void AnimationExporter::exportAnimPropertyByte( SvStream& rStrm, const sal_uInt16 nPropertyId, const sal_uInt8 nVal, const TranslateMode )
    1223             : {
    1224           0 :     EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId );
    1225           0 :     sal_uInt8 nType = DFF_ANIM_PROP_TYPE_BYTE;
    1226           0 :     rStrm.WriteUChar( nType )
    1227           0 :          .WriteUChar( nVal );
    1228           0 : }
    1229             : 
    1230           0 : void AnimationExporter::writeZString( SvStream& rStrm, const OUString& rVal )
    1231             : {
    1232             :     sal_Int32 i;
    1233           0 :     for ( i = 0; i < rVal.getLength(); i++ )
    1234           0 :         rStrm.WriteUInt16( rVal[ i ] );
    1235           0 :     rStrm.WriteUInt16( (sal_Unicode)0 );
    1236           0 : }
    1237             : 
    1238           0 : void AnimationExporter::exportAnimAction( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
    1239             : {
    1240           0 :     EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAction );
    1241             : 
    1242           0 :     sal_Int32 nConcurrent = 1;
    1243           0 :     sal_Int32 nNextAction = 1;
    1244           0 :     sal_Int32 nEndSync = 0;
    1245           0 :     sal_Int32 nU4 = 0;
    1246           0 :     sal_Int32 nU5 = 3;
    1247             : 
    1248           0 :     sal_Int16 nAnimationEndSync = 0;
    1249           0 :     if ( xNode->getEndSync() >>= nAnimationEndSync )
    1250             :     {
    1251           0 :         if ( nAnimationEndSync == AnimationEndSync::ALL )
    1252           0 :             nEndSync = 1;
    1253             :     }
    1254           0 :     rStrm.WriteInt32( nConcurrent )
    1255           0 :          .WriteInt32( nNextAction )
    1256           0 :          .WriteInt32( nEndSync )
    1257           0 :          .WriteInt32( nU4 )
    1258           0 :          .WriteInt32( nU5 );
    1259             : 
    1260           0 : }
    1261             : 
    1262             : // nFlags Bit 6 = fixInteractiveSequenceTiming (for child)
    1263             : // nFlags Bit 5 = fixInteractiveSequenceTiming (for root)
    1264             : // nFlags Bit 4 = first node of main sequence -> begin event next has to be replaced to indefinite
    1265           0 : void AnimationExporter::exportAnimEvent( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const sal_Int32 nFlags )
    1266             : {
    1267             :     sal_uInt16 i;
    1268           0 :     for ( i = 0; i < 4; i++ )
    1269             :     {
    1270           0 :         sal_Int32 nU1 = 0;
    1271           0 :         sal_Int32 nTrigger = 0;
    1272           0 :         sal_Int32 nU3 = 0;
    1273           0 :         sal_Int32 nBegin = 0;
    1274             : 
    1275           0 :         sal_Bool bCreateEvent = sal_False;
    1276           0 :         Any aSource;
    1277             : 
    1278           0 :         switch( i )
    1279             :         {
    1280             :             case 0 :
    1281             :             case 1 :
    1282             :             {
    1283           0 :                 Any aAny;
    1284           0 :                 Event aEvent;
    1285             :                 com::sun::star::animations::Timing eTiming;
    1286           0 :                 if ( i == 0 )
    1287             :                 {
    1288           0 :                     if ( nFlags & 0x20 )
    1289             :                     {
    1290             :                         // taking the first child
    1291           0 :                         Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
    1292           0 :                         Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
    1293           0 :                         if ( xE.is() && xE->hasMoreElements() )
    1294             :                         {
    1295             :                             {
    1296           0 :                                 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
    1297           0 :                                 aAny = xClickNode->getBegin();
    1298             :                             }
    1299           0 :                         }
    1300             :                     }
    1301           0 :                     else if ( nFlags & 0x40 )
    1302             :                     {
    1303             :                         // begin has to be replaced with void, so don't do anything
    1304             :                     }
    1305             :                     else
    1306             :                     {
    1307           0 :                         aAny = xNode->getBegin();
    1308           0 :                         if ( nFlags & 0x10 )    // replace ON_NEXT with IDEFINITE
    1309             :                         {
    1310           0 :                             if ( ( aAny >>= aEvent ) && ( aEvent.Trigger == EventTrigger::ON_NEXT ) )
    1311             :                             {
    1312           0 :                                 eTiming = Timing_INDEFINITE;
    1313           0 :                                 aAny <<= eTiming;
    1314             :                             }
    1315             :                         }
    1316             :                     }
    1317             :                 }
    1318             :                 else
    1319           0 :                     aAny = xNode->getEnd();
    1320             : 
    1321           0 :                 double fTiming = 0.0;
    1322           0 :                 if ( aAny >>= aEvent )
    1323             :                 {
    1324           0 :                     bCreateEvent = sal_True;
    1325           0 :                     switch( aEvent.Trigger )
    1326             :                     {
    1327           0 :                         case EventTrigger::NONE : nTrigger = 0; break;
    1328           0 :                         case EventTrigger::ON_BEGIN : nTrigger = 1; break;
    1329           0 :                         case EventTrigger::ON_END : nTrigger = 2; break;
    1330           0 :                         case EventTrigger::BEGIN_EVENT : nTrigger = 3; break;
    1331           0 :                         case EventTrigger::END_EVENT : nTrigger = 4; nU1 = 2; nU3 = mnCurrentGroup; break;
    1332           0 :                         case EventTrigger::ON_CLICK : nTrigger = 5; break;
    1333           0 :                         case EventTrigger::ON_DBL_CLICK : nTrigger = 6; break;
    1334           0 :                         case EventTrigger::ON_MOUSE_ENTER : nTrigger = 7; break;
    1335           0 :                         case EventTrigger::ON_MOUSE_LEAVE : nTrigger = 8; break;
    1336           0 :                         case EventTrigger::ON_NEXT : nTrigger = 9; break;
    1337           0 :                         case EventTrigger::ON_PREV : nTrigger = 10; break;
    1338           0 :                         case EventTrigger::ON_STOP_AUDIO : nTrigger = 11; break;
    1339             :                     }
    1340           0 :                     if ( aEvent.Offset.hasValue() )
    1341             :                     {
    1342           0 :                         if ( aEvent.Offset >>= eTiming )
    1343             :                         {
    1344           0 :                             if ( eTiming == Timing_INDEFINITE )
    1345           0 :                                 nBegin = -1;
    1346             :                         }
    1347           0 :                         else if ( aEvent.Offset >>= fTiming )
    1348           0 :                             nBegin = (sal_Int32)( fTiming * 1000.0 );
    1349             :                     }
    1350           0 :                     aSource = aEvent.Source;
    1351             :                 }
    1352           0 :                 else if ( aAny >>= eTiming )
    1353             :                 {
    1354           0 :                     bCreateEvent = sal_True;
    1355           0 :                     if ( eTiming == Timing_INDEFINITE )
    1356           0 :                         nBegin = -1;
    1357             :                 }
    1358           0 :                 else if ( aAny >>= fTiming )
    1359             :                 {
    1360           0 :                     bCreateEvent = sal_True;
    1361           0 :                     nBegin = (sal_Int32)( fTiming * 1000.0 );
    1362           0 :                 }
    1363             :             }
    1364           0 :             break;
    1365             : 
    1366             :             case 2 :
    1367             :             {
    1368           0 :                 if ( nFlags & ( 1 << i ) )
    1369             :                 {
    1370           0 :                     bCreateEvent = sal_True;
    1371           0 :                     nU1 = 1;
    1372           0 :                     nTrigger = 9;
    1373             :                 }
    1374             :             }
    1375           0 :             break;
    1376             :             case 3 :
    1377             :             {
    1378           0 :                 if ( nFlags & ( 1 << i ) )
    1379             :                 {
    1380           0 :                     bCreateEvent = sal_True;
    1381           0 :                     nU1 = 1;
    1382           0 :                     nTrigger = 10;
    1383             :                 }
    1384             :             }
    1385           0 :             break;
    1386             :         };
    1387           0 :         if ( bCreateEvent )
    1388             :         {
    1389           0 :             EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, i + 1 );
    1390             :             {
    1391           0 :                 EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger );
    1392           0 :                 rStrm.WriteInt32( nU1 )
    1393           0 :                      .WriteInt32( nTrigger )
    1394           0 :                      .WriteInt32( nU3 )
    1395           0 :                      .WriteInt32( nBegin );
    1396             :             }
    1397           0 :             exportAnimateTargetElement( rStrm, aSource, ( nFlags & ( 1 << i ) ) != 0 );
    1398             :         }
    1399           0 :     }
    1400           0 : }
    1401             : 
    1402           0 : Any AnimationExporter::convertAnimateValue( const Any& rSourceValue, const OUString& rAttributeName )
    1403             : {
    1404           0 :     OUString aDest;
    1405           0 :     if ( rAttributeName == "X"
    1406           0 :             || rAttributeName == "Y"
    1407           0 :             || rAttributeName == "Width"
    1408           0 :             || rAttributeName == "Height"
    1409             :         )
    1410             :     {
    1411           0 :         OUString aStr;
    1412           0 :         if ( rSourceValue >>= aStr )
    1413             :         {
    1414           0 :             ImplTranslateAttribute( aStr, TRANSLATE_MEASURE );
    1415           0 :             aDest += aStr;
    1416           0 :         }
    1417             :     }
    1418           0 :     else if ( rAttributeName == "Rotate"         // "r" or "style.rotation" ?
    1419           0 :             || rAttributeName == "SkewX"
    1420           0 :             || rAttributeName == "Opacity"
    1421           0 :             || rAttributeName == "CharHeight"
    1422             :         )
    1423             :     {
    1424           0 :         double fNumber = 0.0;
    1425           0 :         if ( rSourceValue >>= fNumber )
    1426           0 :             aDest += OUString::number( fNumber );
    1427             :     }
    1428           0 :     else if ( rAttributeName == "Color"
    1429           0 :             || rAttributeName == "FillColor"     // "Fillcolor" or "FillColor" ?
    1430           0 :             || rAttributeName == "LineColor"
    1431           0 :             || rAttributeName == "CharColor"
    1432             :         )
    1433             :     {
    1434           0 :         sal_Int32 nColor = 0;
    1435           0 :         Sequence< double > aHSL( 3 );
    1436           0 :         OUString aP( "," );
    1437           0 :         if ( rSourceValue >>= aHSL )
    1438             :         {
    1439           0 :             aDest += "hsl(";
    1440           0 :             aDest += OUString::number( (sal_Int32)( aHSL[ 0 ] / ( 360.0 / 255 ) ) );
    1441           0 :             aDest += aP;
    1442           0 :             aDest += OUString::number( (sal_Int32)( aHSL[ 1 ] * 255.0 ) );
    1443           0 :             aDest += aP;
    1444           0 :             aDest += OUString::number( (sal_Int32)( aHSL[ 2 ] * 255.0 ) );
    1445           0 :             aDest += ")";
    1446             :         }
    1447           0 :         else if ( rSourceValue >>= nColor )
    1448             :         {
    1449           0 :             aDest += "rgb(";
    1450           0 :             aDest += OUString::number( ( (sal_Int8)nColor ) );
    1451           0 :             aDest += aP;
    1452           0 :             aDest += OUString::number( ( (sal_Int8)( nColor >> 8 ) ) );
    1453           0 :             aDest += aP;
    1454           0 :             aDest += OUString::number( ( (sal_Int8)( nColor >> 16 ) ) );
    1455           0 :             aDest += ")";
    1456           0 :         }
    1457             :     }
    1458           0 :     else if ( rAttributeName == "FillStyle" )
    1459             :     {
    1460             :         ::com::sun::star::drawing::FillStyle eFillStyle;
    1461           0 :         if ( rSourceValue >>= eFillStyle )
    1462             :         {
    1463           0 :             if ( eFillStyle == ::com::sun::star::drawing::FillStyle_NONE )
    1464           0 :                 aDest += "none";    // ?
    1465             :             else
    1466           0 :                 aDest += "solid";
    1467             :         }
    1468             :     }
    1469           0 :     else if ( rAttributeName == "LineStyle" )
    1470             :     {
    1471             :         ::com::sun::star::drawing::LineStyle eLineStyle;
    1472           0 :         if ( rSourceValue >>= eLineStyle )
    1473             :         {
    1474           0 :             if ( eLineStyle == ::com::sun::star::drawing::LineStyle_NONE )
    1475           0 :                 aDest += "false";
    1476             :             else
    1477           0 :                 aDest += "true";
    1478             :         }
    1479             :     }
    1480           0 :     else if ( rAttributeName == "CharWeight" )
    1481             :     {
    1482           0 :         float fFontWeight = 0.0;
    1483           0 :         if ( rSourceValue >>= fFontWeight )
    1484             :         {
    1485           0 :             if ( fFontWeight == com::sun::star::awt::FontWeight::BOLD )
    1486           0 :                 aDest += "bold";
    1487             :             else
    1488           0 :                 aDest += "normal";
    1489             :         }
    1490             :     }
    1491           0 :     else if ( rAttributeName == "CharUnderline" )
    1492             :     {
    1493           0 :         sal_Int16 nFontUnderline = 0;
    1494           0 :         if ( rSourceValue >>= nFontUnderline )
    1495             :         {
    1496           0 :             if ( nFontUnderline == com::sun::star::awt::FontUnderline::NONE )
    1497           0 :                 aDest += "false";
    1498             :             else
    1499           0 :                 aDest += "true";
    1500             :         }
    1501             :     }
    1502           0 :     else if ( rAttributeName == "CharPosture" )
    1503             :     {
    1504             :         ::com::sun::star::awt::FontSlant eFontSlant;
    1505           0 :         if ( rSourceValue >>= eFontSlant )
    1506             :         {
    1507           0 :             if ( eFontSlant == com::sun::star::awt::FontSlant_ITALIC )
    1508           0 :                 aDest += "italic";
    1509             :             else
    1510           0 :                 aDest += "normal";  // ?
    1511             :         }
    1512             :     }
    1513           0 :     else if ( rAttributeName == "Visibility" )
    1514             :     {
    1515           0 :         sal_Bool bVisible = sal_True;
    1516           0 :         if ( rSourceValue >>= bVisible )
    1517             :         {
    1518           0 :             if ( bVisible )
    1519           0 :                 aDest += "visible";
    1520             :             else
    1521           0 :                 aDest += "hidden";
    1522             :         }
    1523             :     }
    1524           0 :     Any aRet;
    1525           0 :     if ( !aDest.isEmpty() )
    1526           0 :         aRet <<= aDest;
    1527             :     else
    1528           0 :         aRet = rSourceValue;
    1529           0 :     return aRet;
    1530             : }
    1531             : 
    1532           0 : void AnimationExporter::exportAnimateSet( SvStream& rStrm, const Reference< XAnimationNode >& xNode, int nAfterEffectType )
    1533             : {
    1534           0 :     Reference< XAnimateSet > xSet( xNode, UNO_QUERY );
    1535           0 :     if( xSet.is() )
    1536             :     {
    1537           0 :         EscherExContainer aAnimateSet( rStrm, DFF_msofbtAnimateSet, 0 );
    1538             :         {
    1539           0 :             EscherExAtom aAnimateSetData( rStrm, DFF_msofbtAnimateSetData );
    1540           0 :             sal_uInt32 nId1 = 1;            // ??
    1541           0 :             sal_uInt32 nId2 = 1;            // ??
    1542           0 :             rStrm.WriteUInt32( nId1 ).WriteUInt32( nId2 );
    1543             :         }
    1544           0 :         Any aConvertedValue( convertAnimateValue( xSet->getTo(), xSet->getAttributeName() ) );
    1545           0 :         if ( aConvertedValue.hasValue() )
    1546           0 :             exportAnimProperty( rStrm, 1, aConvertedValue, TRANSLATE_NONE );
    1547           0 :         exportAnimateTarget( rStrm, xNode, 0, nAfterEffectType );
    1548           0 :     }
    1549           0 : }
    1550             : 
    1551           0 : sal_uInt32 AnimationExporter::GetValueTypeForAttributeName( const OUString& rAttributeName )
    1552             : {
    1553           0 :     sal_uInt32 nValueType = 0;
    1554             : 
    1555             :     struct Entry
    1556             :     {
    1557             :         const sal_Char* pName;
    1558             :         sal_uInt8       nType;
    1559             :     };
    1560             :     static const Entry lcl_attributeMap[] =
    1561             :     {
    1562             :         { "charcolor", 2 },
    1563             :         { "charfontname", 0 },
    1564             :         { "charheight", 1 },
    1565             :         { "charposture", 0 },
    1566             :         // TODO(Q1): This should prolly be changed in PPT import
    1567             :         // { "charrotation", ATTRIBUTE_CHAR_ROTATION },
    1568             :         { "charrotation", 1 },
    1569             :         { "charunderline", 0 },
    1570             :         { "charweight", 0 },
    1571             :         { "color", 2 },
    1572             :         { "dimcolor", 2 },
    1573             :         { "fillcolor", 2 },
    1574             :         { "fillstyle", 0 },
    1575             :         { "height", 1 },
    1576             :         { "linecolor", 2 },
    1577             :         { "linestyle", 0 },
    1578             :         { "opacity", 0 },
    1579             :         { "rotate", 1 },
    1580             :         { "skewx", 1 },
    1581             :         { "skewy", 1 },
    1582             :         { "visibility", 1 },
    1583             :         { "width", 1 },
    1584             :         { "x", 1 },
    1585             :         { "y", 1 },
    1586             :         { NULL, 0 }
    1587             :     };
    1588           0 :     const Entry* pPtr = &lcl_attributeMap[ 0 ];
    1589           0 :     while( pPtr->pName )
    1590             :     {
    1591           0 :         if ( rAttributeName.equalsIgnoreAsciiCaseAscii( pPtr->pName ) )
    1592             :         {
    1593           0 :             nValueType = pPtr->nType;
    1594           0 :             break;
    1595             :         }
    1596           0 :         pPtr++;
    1597             :     }
    1598             :     DBG_ASSERT( pPtr->pName, "GetValueTypeForAttributeName, unknown property value!" );
    1599           0 :     return nValueType;
    1600             : }
    1601             : 
    1602           0 : void AnimationExporter::exportAnimate( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
    1603             : {
    1604           0 :     Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
    1605           0 :     if ( xAnimate.is() )
    1606             :     {
    1607           0 :         Any aBy  ( xAnimate->getBy() );
    1608           0 :         Any aFrom( xAnimate->getFrom() );
    1609           0 :         Any aTo  ( xAnimate->getTo() );
    1610             : 
    1611           0 :         EscherExContainer aContainer( rStrm, DFF_msofbtAnimate, 0 );
    1612             :         {
    1613           0 :             EscherExAtom    aAnimateData( rStrm, DFF_msofbtAnimateData );
    1614           0 :             sal_uInt32 nBits = 0x38;
    1615           0 :             sal_Int16 nTmp = xAnimate->getCalcMode();
    1616           0 :             sal_uInt32 nCalcMode = /* (nTmp == AnimationCalcMode::FORMULA) ? 2 : */ (nTmp == AnimationCalcMode::LINEAR) ? 1 : 0;
    1617           0 :             nTmp = xAnimate->getValueType();
    1618           0 :             sal_uInt32 nValueType = GetValueTypeForAttributeName( xAnimate->getAttributeName() );
    1619             : 
    1620           0 :             if ( aBy.hasValue() )
    1621           0 :                 nBits |= 1;
    1622           0 :             if ( aFrom.hasValue() )
    1623           0 :                 nBits |= 2;
    1624           0 :             if ( aTo.hasValue() )
    1625           0 :                 nBits |= 4;
    1626             : 
    1627           0 :             rStrm.WriteUInt32( nCalcMode )
    1628           0 :                  .WriteUInt32( nBits )
    1629           0 :                  .WriteUInt32( nValueType );
    1630             :         }
    1631           0 :         if ( aBy.hasValue() )
    1632           0 :             exportAnimProperty( rStrm, 1, aBy, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE );
    1633           0 :         if ( aFrom.hasValue() )
    1634           0 :             exportAnimProperty( rStrm, 2, aFrom, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE );
    1635           0 :         if ( aTo.hasValue() )
    1636           0 :             exportAnimProperty( rStrm, 3, aTo, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE );
    1637             : 
    1638           0 :         exportAnimateKeyPoints( rStrm, xAnimate );
    1639           0 :         exportAnimateTarget( rStrm, xNode );
    1640           0 :     }
    1641           0 : }
    1642             : 
    1643           0 : void AnimationExporter::exportAnimateTarget( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const sal_uInt32 nForceAttributeNames, int nAfterEffectType )
    1644             : {
    1645           0 :     EscherExContainer aAnimateTarget( rStrm, DFF_msofbtAnimateTarget, 0 );
    1646           0 :     Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
    1647           0 :     if ( xAnimate.is() )
    1648             :     {
    1649             :         {
    1650           0 :             EscherExAtom aAnimateTargetSettings( rStrm, DFF_msofbtAnimateTargetSettings, 0 );
    1651             :             // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype
    1652             :             // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none
    1653             :             // nAccumulate 0 = none, 1 = always
    1654             :             // nTransformType 0: "property" else "image"
    1655           0 :             sal_uInt32 nBits = 0;
    1656           0 :             sal_uInt32 nAdditive = 0;
    1657           0 :             sal_uInt32 nAccumulate = 0;
    1658           0 :             sal_uInt32 nTransformType = 0;
    1659           0 :             if ( xAnimate.is() )
    1660             :             {
    1661           0 :                 if ( !xAnimate->getAttributeName().isEmpty() )
    1662           0 :                     nBits |= 4;     // what is attributeName ?, maybe this is set if a DFF_msofbtAnimateAttributeNames is written
    1663           0 :                 sal_Int16 nAdditiveMode = xAnimate->getAdditive();
    1664           0 :                 if ( nAdditiveMode != AnimationAdditiveMode::BASE )
    1665             :                 {
    1666           0 :                     nBits |= 1;
    1667           0 :                     switch( nAdditiveMode )
    1668             :                     {
    1669           0 :                         case AnimationAdditiveMode::SUM : nAdditive = 1; break;
    1670           0 :                         case AnimationAdditiveMode::REPLACE : nAdditive = 2; break;
    1671           0 :                         case AnimationAdditiveMode::MULTIPLY : nAdditive = 3; break;
    1672           0 :                         case AnimationAdditiveMode::NONE : nAdditive = 4; break;
    1673             :                     }
    1674             :                 }
    1675           0 :                 if ( xAnimate->getAccumulate() )
    1676             :                 {
    1677           0 :                     nBits  |= 2;
    1678           0 :                     nAccumulate = 1;
    1679             :                 }
    1680             :             }
    1681           0 :             rStrm.WriteUInt32( nBits )
    1682           0 :                .WriteUInt32( nAdditive )
    1683           0 :                .WriteUInt32( nAccumulate )
    1684           0 :                .WriteUInt32( nTransformType );
    1685             :         }
    1686           0 :         if ( !xAnimate->getAttributeName().isEmpty() || nForceAttributeNames )
    1687             :         {
    1688           0 :             EscherExContainer aAnimateAttributeNames( rStrm, DFF_msofbtAnimateAttributeNames, 1 );
    1689           0 :             OUString aAttributeName( xAnimate->getAttributeName() );
    1690           0 :             if ( nForceAttributeNames )
    1691             :             {
    1692           0 :                 if( nForceAttributeNames == 1 )
    1693             :                 {
    1694           0 :                     aAttributeName = "r";
    1695             :                 }
    1696             :             }
    1697           0 :             sal_Int32 nIndex = 0;
    1698           0 :             do
    1699             :             {
    1700           0 :                 OUString aToken( aAttributeName.getToken( 0, ';', nIndex ) );
    1701           0 :                 exportAnimPropertyString( rStrm, 0, aToken, TRANSLATE_ATTRIBUTE );
    1702             :             }
    1703           0 :             while ( nIndex >= 0 );
    1704             :         }
    1705             : 
    1706           0 :         if( nAfterEffectType != AFTEREFFECT_NONE )
    1707             :         {
    1708           0 :             EscherExContainer aAnimPropertySet( rStrm, DFF_msofbtAnimPropertySet );
    1709           0 :             exportAnimPropertyuInt32( rStrm, 6, 1, TRANSLATE_NONE );
    1710           0 :             if( nAfterEffectType == AFTEREFFECT_COLOR )
    1711             :             {
    1712           0 :                 exportAnimPropertyuInt32( rStrm, 4, 0, TRANSLATE_NONE );
    1713           0 :                 exportAnimPropertyuInt32( rStrm, 5, 0, TRANSLATE_NONE );
    1714           0 :             }
    1715             :         }
    1716           0 :         exportAnimateTargetElement( rStrm, aTarget.hasValue() ? aTarget : xAnimate->getTarget(), sal_False );
    1717           0 :     }
    1718           0 : }
    1719             : 
    1720           0 : Reference< XShape > AnimationExporter::getTargetElementShape( const Any& rAny, sal_Int32& rBegin, sal_Int32& rEnd, sal_Bool& rParagraphTarget )
    1721             : {
    1722           0 :     Reference< XShape > xShape;
    1723           0 :     rAny >>= xShape;
    1724             : 
    1725           0 :     rParagraphTarget = sal_False;
    1726             : 
    1727           0 :     if( !xShape.is() )
    1728             :     {
    1729           0 :     ParagraphTarget aParaTarget;
    1730           0 :     if( rAny >>= aParaTarget )
    1731           0 :         xShape = aParaTarget.Shape;
    1732           0 :     if ( xShape.is() )
    1733             :     {
    1734             :         // now calculating the character range for the paragraph
    1735           0 :         sal_Int16 nParagraph = aParaTarget.Paragraph;
    1736           0 :         Reference< XSimpleText > xText( xShape, UNO_QUERY );
    1737           0 :         if ( xText.is() )
    1738             :         {
    1739           0 :         rParagraphTarget = sal_True;
    1740           0 :         Reference< XEnumerationAccess > xTextParagraphEnumerationAccess( xText, UNO_QUERY );
    1741           0 :         if ( xTextParagraphEnumerationAccess.is() )
    1742             :         {
    1743           0 :             Reference< XEnumeration > xTextParagraphEnumeration( xTextParagraphEnumerationAccess->createEnumeration() );
    1744           0 :             if ( xTextParagraphEnumeration.is() )
    1745             :             {
    1746             :             sal_Int16 nCurrentParagraph;
    1747           0 :             rBegin = rEnd = nCurrentParagraph = 0;
    1748           0 :             while ( xTextParagraphEnumeration->hasMoreElements() )
    1749             :             {
    1750           0 :                 Reference< XTextRange > xTextRange( xTextParagraphEnumeration->nextElement(), UNO_QUERY );
    1751           0 :                 if ( xTextRange.is() )
    1752             :                 {
    1753           0 :                 OUString aParaText( xTextRange->getString() );
    1754           0 :                 sal_Int32 nLength = aParaText.getLength() + 1;
    1755           0 :                 rEnd += nLength;
    1756           0 :                 if ( nCurrentParagraph == nParagraph )
    1757           0 :                     break;
    1758           0 :                 nCurrentParagraph++;
    1759           0 :                 rBegin += nLength;
    1760             :                 }
    1761           0 :             }
    1762           0 :             }
    1763           0 :         }
    1764           0 :         }
    1765           0 :     }
    1766             :     }
    1767             : 
    1768           0 :     return xShape;
    1769             : }
    1770             : 
    1771           0 : void AnimationExporter::exportAnimateTargetElement( SvStream& rStrm, const Any aAny, const sal_Bool bCreate2b01Atom )
    1772             : {
    1773           0 :     sal_uInt32 nRefMode = 0;    // nRefMode == 2 -> Paragraph
    1774           0 :     sal_Int32 begin = -1;
    1775           0 :     sal_Int32 end = -1;
    1776             :     sal_Bool bParagraphTarget;
    1777             : 
    1778           0 :     Reference< XShape > xShape = getTargetElementShape( aAny, begin, end, bParagraphTarget );
    1779             : 
    1780           0 :     if( bParagraphTarget )
    1781           0 :         nRefMode = 2;
    1782             : 
    1783           0 :     if ( xShape.is() || bCreate2b01Atom )
    1784             :     {
    1785           0 :         EscherExContainer aAnimateTargetElement( rStrm, DFF_msofbtAnimateTargetElement );
    1786           0 :         if ( xShape.is() )
    1787             :         {
    1788           0 :             EscherExAtom aAnimReference( rStrm, DFF_msofbtAnimReference );
    1789             : 
    1790           0 :             sal_uInt32 nRefType = 1;    // TODO: nRefType == 2 -> Sound;
    1791           0 :             sal_uInt32 nRefId = ((EscherSolverContainer&)mrSolverContainer).GetShapeId( xShape );
    1792             : 
    1793           0 :             rStrm.WriteUInt32( nRefMode )
    1794           0 :                  .WriteUInt32( nRefType )
    1795           0 :                  .WriteUInt32( nRefId )
    1796           0 :                  .WriteInt32( begin )
    1797           0 :                  .WriteInt32( end );
    1798             :         }
    1799           0 :         if ( bCreate2b01Atom )
    1800             :         {
    1801           0 :             EscherExAtom a2b01Atom( rStrm, 0x2b01 );
    1802           0 :             rStrm.WriteUInt32( (sal_uInt32)1 );     // ?
    1803           0 :         }
    1804           0 :     }
    1805           0 : }
    1806             : 
    1807           0 : void AnimationExporter::exportAnimateKeyPoints( SvStream& rStrm, const Reference< XAnimate >& xAnimate )
    1808             : {
    1809           0 :     Sequence< double > aKeyTimes( xAnimate->getKeyTimes() );
    1810           0 :     Sequence< Any > aValues( xAnimate->getValues() );
    1811           0 :     OUString aFormula( xAnimate->getFormula() );
    1812           0 :     if ( aKeyTimes.getLength() )
    1813             :     {
    1814           0 :         EscherExContainer aAnimKeyPoints( rStrm, DFF_msofbtAnimKeyPoints );
    1815             :         sal_Int32 i;
    1816           0 :         for ( i = 0; i < aKeyTimes.getLength(); i++ )
    1817             :         {
    1818             :             {
    1819           0 :                 EscherExAtom aAnimKeyTime( rStrm, DFF_msofbtAnimKeyTime );
    1820           0 :                 sal_Int32 nKeyTime = (sal_Int32)( aKeyTimes[ i ] * 1000.0 );
    1821           0 :                 rStrm.WriteInt32( nKeyTime );
    1822             :             }
    1823           0 :             Any aAny[ 2 ];
    1824           0 :             if ( aValues[ i ].hasValue() )
    1825             :             {
    1826           0 :                 ValuePair aPair;
    1827           0 :                 if ( aValues[ i ] >>= aPair )
    1828             :                 {
    1829           0 :                     aAny[ 0 ] = convertAnimateValue( aPair.First, xAnimate->getAttributeName() );
    1830           0 :                     aAny[ 1 ] = convertAnimateValue( aPair.Second, xAnimate->getAttributeName() );
    1831             :                 }
    1832             :                 else
    1833             :                 {
    1834           0 :                     aAny[ 0 ] = convertAnimateValue( aValues[ i ], xAnimate->getAttributeName() );
    1835             :                 }
    1836           0 :                 if ( !i && !aFormula.isEmpty() )
    1837             :                 {
    1838           0 :                     ImplTranslateAttribute( aFormula, TRANSLATE_MEASURE );
    1839           0 :                     aAny[ 1 ] <<= aFormula;
    1840             :                 }
    1841           0 :                 exportAnimProperty( rStrm, 0, aAny[ 0 ], TRANSLATE_NONE );
    1842           0 :                 exportAnimProperty( rStrm, 1, aAny[ 1 ], TRANSLATE_NONE );
    1843             :             }
    1844           0 :         }
    1845           0 :     }
    1846           0 : }
    1847             : 
    1848           0 : void AnimationExporter::exportAnimValue( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const sal_Bool bExportAlways )
    1849             : {
    1850           0 :     Any aAny;
    1851             :     // repeat count (0)
    1852           0 :     double fRepeat = 0.0;
    1853           0 :     float fRepeatCount = 0.0;
    1854             :     com::sun::star::animations::Timing eTiming;
    1855           0 :     aAny = xNode->getRepeatCount();
    1856           0 :     if ( aAny >>= eTiming )
    1857             :     {
    1858           0 :         if ( eTiming == Timing_INDEFINITE )
    1859           0 :             fRepeatCount = ((float)3.40282346638528860e+38);
    1860             :     }
    1861           0 :     else if ( aAny >>= fRepeat )
    1862           0 :         fRepeatCount = (float)fRepeat;
    1863           0 :     if ( fRepeatCount != 0.0 )
    1864             :     {
    1865           0 :         EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue );
    1866           0 :         sal_uInt32 nType = 0;
    1867           0 :         rStrm.WriteUInt32( nType )
    1868           0 :              .WriteFloat( fRepeatCount );
    1869             :     }
    1870             :     // accelerate (3)
    1871           0 :     float fAccelerate = (float)xNode->getAcceleration();
    1872           0 :     if ( bExportAlways || ( fAccelerate != 0.0 ) )
    1873             :     {
    1874           0 :         EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue );
    1875           0 :         sal_uInt32 nType = 3;
    1876           0 :         rStrm.WriteUInt32( nType )
    1877           0 :              .WriteFloat( fAccelerate );
    1878             :     }
    1879             : 
    1880             :     // decelerate (4)
    1881           0 :     float fDecelerate = (float)xNode->getDecelerate();
    1882           0 :     if ( bExportAlways || ( fDecelerate != 0.0 ) )
    1883             :     {
    1884           0 :         EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue );
    1885           0 :         sal_uInt32 nType = 4;
    1886           0 :         rStrm.WriteUInt32( nType )
    1887           0 :              .WriteFloat( fDecelerate );
    1888             :     }
    1889             : 
    1890             :     // autoreverse (5)
    1891           0 :     sal_Bool bAutoReverse = xNode->getAutoReverse();
    1892           0 :     if ( bExportAlways || bAutoReverse )
    1893             :     {
    1894           0 :         EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue );
    1895           0 :         sal_uInt32 nType = 5;
    1896           0 :         sal_uInt32 nVal  = bAutoReverse ? 1 : 0;
    1897           0 :         rStrm.WriteUInt32( nType )
    1898           0 :              .WriteUInt32( nVal );
    1899           0 :     }
    1900           0 : }
    1901             : 
    1902           0 : void AnimationExporter::exportTransitionFilter( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
    1903             : {
    1904           0 :     Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
    1905           0 :     if ( xFilter.is() )
    1906             :     {
    1907           0 :         EscherExContainer aAnimateFilter( rStrm, DFF_msofbtAnimateFilter );
    1908             :         {
    1909           0 :             EscherExAtom aAnimateFilterData( rStrm, DFF_msofbtAnimateFilterData );
    1910           0 :             sal_uInt32 nBits = 3;       // bit 0 -> use AnimAttributeValue
    1911             :                                         // bit 1 -> use nTransition
    1912             : 
    1913           0 :             sal_uInt32 nTransition = xFilter->getMode() ? 0 : 1;
    1914           0 :             rStrm.WriteUInt32( nBits )
    1915           0 :                  .WriteUInt32( nTransition );
    1916             :         }
    1917           0 :         const sal_Char* pFilter = FindTransitionName( xFilter->getTransition(), xFilter->getSubtype(), xFilter->getDirection() );
    1918           0 :         if ( pFilter )
    1919             :         {
    1920           0 :             const OUString aStr( OUString::createFromAscii( pFilter ) );
    1921           0 :             exportAnimPropertyString( rStrm, 1, aStr, TRANSLATE_NONE );
    1922             :         }
    1923           0 :         exportAnimateTarget( rStrm, xNode );
    1924           0 :     }
    1925           0 : }
    1926             : 
    1927           0 : void AnimationExporter::exportAnimateMotion( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
    1928             : {
    1929           0 :     Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY );
    1930           0 :     if ( xMotion.is() )
    1931             :     {
    1932           0 :         EscherExContainer aAnimateMotion( rStrm, DFF_msofbtAnimateMotion );
    1933             :         {
    1934             :             {   //SJ: Ignored from import filter
    1935           0 :                 EscherExAtom aAnimateMotionData( rStrm, DFF_msofbtAnimateMotionData );
    1936           0 :                 sal_uInt32 nBits = 0x98;
    1937           0 :                 sal_uInt32 nOrigin = 0x2;
    1938           0 :                 float fByX = 100.0; // nBits&1
    1939           0 :                 float fByY = 100.0; // nBits&1
    1940           0 :                 float fFromX = 0.0; // nBits&2
    1941           0 :                 float fFromY = 0.0; // nBits&2
    1942           0 :                 float fToX = 100.0; // nBits&4
    1943           0 :                 float fToY = 100.0; // nBits&4
    1944           0 :                 rStrm.WriteUInt32( nBits ).WriteFloat( fByX ).WriteFloat( fByY ).WriteFloat( fFromX ).WriteFloat( fFromY ).WriteFloat( fToX ).WriteFloat( fToY ).WriteUInt32( nOrigin );
    1945             :             }
    1946             : 
    1947           0 :             OUString aStr;
    1948           0 :             if ( xMotion->getPath() >>= aStr )
    1949             :             {
    1950           0 :                 if ( !aStr.isEmpty() )
    1951           0 :                     exportAnimPropertyString( rStrm, 1, aStr, TRANSLATE_NONE );
    1952             :             }
    1953           0 :             exportAnimateTarget( rStrm, xNode );
    1954           0 :         }
    1955           0 :     }
    1956           0 : }
    1957             : 
    1958           0 : void AnimationExporter::exportAnimateTransform( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
    1959             : {
    1960           0 :     Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
    1961           0 :     if ( xTransform.is() )
    1962             :     {
    1963           0 :         if ( xTransform->getTransformType() ==  AnimationTransformType::SCALE )
    1964             :         {
    1965           0 :             EscherExContainer aAnimateScale( rStrm, DFF_msofbtAnimateScale );
    1966             :             {
    1967           0 :                 EscherExAtom aAnimateScaleData( rStrm, DFF_msofbtAnimateScaleData );
    1968           0 :                 sal_uInt32 nBits = 0;
    1969           0 :                 sal_uInt32 nZoomContents = 1;
    1970           0 :                 float fByX = 100.0;
    1971           0 :                 float fByY = 100.0;
    1972           0 :                 float fFromX = 0.0;
    1973           0 :                 float fFromY = 0.0;
    1974           0 :                 float fToX = 100.0;
    1975           0 :                 float fToY = 100.0;
    1976             : 
    1977           0 :                 double fX = 0.0, fY = 0.0;
    1978           0 :                 ValuePair aPair;
    1979           0 :                 if ( xTransform->getBy() >>= aPair )
    1980             :                 {
    1981           0 :                     if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) )
    1982             :                     {
    1983           0 :                         nBits |= 1;
    1984           0 :                         fByX = (float)( fX * 100 );
    1985           0 :                         fByY = (float)( fY * 100 );
    1986             :                     }
    1987             :                 }
    1988           0 :                 if ( xTransform->getFrom() >>= aPair )
    1989             :                 {
    1990           0 :                     if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) )
    1991             :                     {
    1992           0 :                         nBits |= 2;
    1993           0 :                         fFromX = (float)( fX * 100 );
    1994           0 :                         fFromY = (float)( fY * 100 );
    1995             :                     }
    1996             :                 }
    1997           0 :                 if( xTransform->getTo() >>= aPair )
    1998             :                 {
    1999           0 :                     if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) )
    2000             :                     {
    2001           0 :                         nBits |= 4;
    2002           0 :                         fToX = (float)( fX * 100 );
    2003           0 :                         fToY = (float)( fY * 100 );
    2004             :                     }
    2005             :                 }
    2006             : 
    2007             :                 // TODO: ZoomContents:
    2008             :                 //if( nBits & 8 )
    2009             :                 //( fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" );
    2010             : 
    2011           0 :                 rStrm.WriteUInt32( nBits ).WriteFloat( fByX ).WriteFloat( fByY ).WriteFloat( fFromX ).WriteFloat( fFromY ).WriteFloat( fToX ).WriteFloat( fToY ).WriteUInt32( nZoomContents );
    2012             :             }
    2013           0 :             exportAnimateTarget( rStrm, xNode );
    2014             :         }
    2015           0 :         else if ( xTransform->getTransformType() ==  AnimationTransformType::ROTATE )
    2016             :         {
    2017           0 :             EscherExContainer aAnimateRotation( rStrm, DFF_msofbtAnimateRotation );
    2018             :             {
    2019           0 :                 EscherExAtom aAnimateRotationData( rStrm, DFF_msofbtAnimateRotationData );
    2020           0 :                 sal_uInt32 nBits = 0;
    2021           0 :                 sal_uInt32 nU1 = 0;
    2022           0 :                 float fBy = 360.0;
    2023           0 :                 float fFrom = 0.0;
    2024           0 :                 float fTo = 360.0;
    2025             : 
    2026           0 :                 double fVal = 0.0;
    2027           0 :                 if ( xTransform->getBy() >>= fVal )
    2028             :                 {
    2029           0 :                     nBits |= 1;
    2030           0 :                     fBy = (float)fVal;
    2031             :                 }
    2032           0 :                 if ( xTransform->getFrom() >>= fVal )
    2033             :                 {
    2034           0 :                     nBits |= 2;
    2035           0 :                     fFrom = (float)fVal;
    2036             :                 }
    2037           0 :                 if ( xTransform->getTo() >>= fVal )
    2038             :                 {
    2039           0 :                     nBits |= 4;
    2040           0 :                     fTo = (float)fVal;
    2041             :                 }
    2042           0 :                 rStrm.WriteUInt32( nBits ).WriteFloat( fBy ).WriteFloat( fFrom ).WriteFloat( fTo ).WriteUInt32( nU1 );
    2043             :             }
    2044           0 :             exportAnimateTarget( rStrm, xNode, 1 );
    2045             :         }
    2046           0 :     }
    2047           0 : }
    2048             : 
    2049           0 : sal_Bool AnimationExporter::getColorAny( const Any& rAny, const sal_Int16 nColorSpace, sal_Int32& rMode, sal_Int32& rA, sal_Int32& rB, sal_Int32& rC ) const
    2050             : {
    2051           0 :     sal_Bool bIsColor = sal_True;
    2052             : 
    2053           0 :     rMode = 0;
    2054           0 :     if ( nColorSpace == AnimationColorSpace::HSL )
    2055           0 :         rMode = 1;
    2056             : 
    2057           0 :     sal_Int32 nColor = 0;
    2058           0 :     Sequence< double > aHSL( 3 );
    2059           0 :     if ( rAny >>= nColor )      // RGB color
    2060             :     {
    2061           0 :         rA = (sal_uInt8)( nColor >> 16 );
    2062           0 :         rB = (sal_uInt8)( nColor >> 8 );
    2063           0 :         rC = (sal_uInt8)( nColor );
    2064             :     }
    2065           0 :     else if ( rAny >>= aHSL )   // HSL
    2066             :     {
    2067           0 :         rA = (sal_Int32) ( aHSL[ 0 ] * 255.0 / 360.0 );
    2068           0 :         rB = (sal_Int32) ( aHSL[ 1 ] * 255.0 );
    2069           0 :         rC = (sal_Int32) ( aHSL[ 2 ] * 255.0 );
    2070             :     }
    2071             :     else
    2072           0 :         bIsColor = sal_False;
    2073           0 :     return bIsColor;
    2074             : }
    2075             : 
    2076           0 : void AnimationExporter::exportAnimateColor( SvStream& rStrm, const Reference< XAnimationNode >& xNode, int nAfterEffectType )
    2077             : {
    2078           0 :     Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
    2079           0 :     if ( xColor.is() )
    2080             :     {
    2081           0 :         EscherExContainer aAnimateColor( rStrm, DFF_msofbtAnimateColor );
    2082             :         {
    2083           0 :             EscherExAtom aAnimateColorData( rStrm, DFF_msofbtAnimateColorData );
    2084           0 :             sal_uInt32 nBits = 8;
    2085             : 
    2086             :             sal_Int32 nByMode, nByA, nByB, nByC;
    2087           0 :             nByMode = nByA = nByB = nByC = 0;
    2088             : 
    2089             :             sal_Int32 nFromMode, nFromA, nFromB, nFromC;
    2090           0 :             nFromMode = nFromA = nFromB = nFromC = 0;
    2091             : 
    2092             :             sal_Int32 nToMode, nToA, nToB, nToC;
    2093           0 :             nToMode = nToA = nToB = nToC = 0;
    2094             : 
    2095           0 :             sal_Int16 nColorSpace = xColor->getColorInterpolation();
    2096             : 
    2097           0 :             Any aAny( xColor->getBy() );
    2098           0 :             if ( aAny.hasValue() )
    2099             :             {
    2100           0 :                 if ( getColorAny( aAny, nColorSpace, nByMode, nByA, nByB, nByC ) )
    2101           0 :                     nBits |= 0x11;
    2102             :             }
    2103           0 :             aAny = xColor->getFrom();
    2104           0 :             if ( aAny.hasValue() )
    2105             :             {
    2106           0 :                 if ( getColorAny( aAny, nColorSpace, nFromMode, nFromA, nFromB, nFromC ) )
    2107           0 :                     nBits |= 0x12;
    2108             :             }
    2109           0 :             aAny = xColor->getTo();
    2110           0 :             if ( aAny.hasValue() )
    2111             :             {
    2112           0 :                 if ( getColorAny( aAny, nColorSpace, nToMode, nToA, nToB, nToC ) )
    2113           0 :                     nBits |= 0x14;
    2114             :             }
    2115           0 :             rStrm  .WriteUInt32( nBits )
    2116           0 :                    .WriteInt32( nByMode ).WriteInt32( nByA ).WriteInt32( nByB ).WriteInt32( nByC )
    2117           0 :                    .WriteInt32( nFromMode ).WriteInt32( nFromA ).WriteInt32( nFromB ).WriteInt32( nFromC )
    2118           0 :                    .WriteInt32( nToMode ).WriteInt32( nToA ).WriteInt32( nToB ).WriteInt32( nToC );
    2119             :         }
    2120           0 :         exportAnimateTarget( rStrm, xNode, 0, nAfterEffectType );
    2121           0 :     }
    2122           0 : }
    2123             : 
    2124           0 : void AnimationExporter::exportIterate( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
    2125             : {
    2126           0 :     Reference< XIterateContainer > xIterate( xNode, UNO_QUERY );
    2127           0 :     if ( xIterate.is() )
    2128             :     {
    2129           0 :         EscherExAtom aAnimIteration( rStrm, DFF_msofbtAnimIteration );
    2130             : 
    2131           0 :         float       fInterval = 10.0;
    2132           0 :         sal_Int32   nTextUnitEffect = 0;
    2133           0 :         sal_Int32   nU1 = 1;
    2134           0 :         sal_Int32   nU2 = 1;
    2135           0 :         sal_Int32   nU3 = 0xe;
    2136             : 
    2137           0 :         sal_Int16 nIterateType = xIterate->getIterateType();
    2138           0 :         switch( nIterateType )
    2139             :         {
    2140           0 :             case TextAnimationType::BY_WORD : nTextUnitEffect = 1; break;
    2141           0 :             case TextAnimationType::BY_LETTER : nTextUnitEffect = 2; break;
    2142             :         }
    2143             : 
    2144           0 :         fInterval = (float)xIterate->getIterateInterval();
    2145             : 
    2146             :         // convert interval from absolute to percentage
    2147           0 :         double fDuration = 0.0;
    2148             : 
    2149           0 :         Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
    2150           0 :         if( xEnumerationAccess.is() )
    2151             :         {
    2152           0 :             Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
    2153           0 :             if( xEnumeration.is() )
    2154             :             {
    2155           0 :                 while( xEnumeration->hasMoreElements() )
    2156             :                 {
    2157           0 :                     Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
    2158           0 :                     if( xChildNode.is() )
    2159             :                     {
    2160           0 :                         double fChildBegin = 0.0;
    2161           0 :                         double fChildDuration = 0.0;
    2162           0 :                         xChildNode->getBegin() >>= fChildBegin;
    2163           0 :                         xChildNode->getDuration() >>= fChildDuration;
    2164             : 
    2165           0 :                         fChildDuration += fChildBegin;
    2166           0 :                         if( fChildDuration > fDuration )
    2167           0 :                             fDuration = fChildDuration;
    2168             :                     }
    2169           0 :                 }
    2170           0 :             }
    2171             :         }
    2172             : 
    2173           0 :         if( fDuration )
    2174           0 :             fInterval = (float)(100.0 * fInterval / fDuration);
    2175             : 
    2176           0 :         rStrm.WriteFloat( fInterval ).WriteInt32( nTextUnitEffect ).WriteInt32( nU1 ).WriteInt32( nU2 ).WriteInt32( nU3 );
    2177           0 :         aTarget = xIterate->getTarget();
    2178           0 :     }
    2179           0 : }
    2180             : 
    2181             : } // namespace ppt;
    2182             : 
    2183             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10