Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/oox/source/ppt/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 37 kB image not shown  

Quelle  timenodelistcontext.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <oox/ppt/timenodelistcontext.hxx>

#include <rtl/math.hxx>
#include <sal/log.hxx>
#include <comphelper/diagnose_ex.hxx>

#include <com/sun/star/animations/AnimationTransformType.hpp>
#include <com/sun/star/animations/AnimationCalcMode.hpp>
#include <com/sun/star/animations/AnimationColorSpace.hpp>
#include <com/sun/star/animations/AnimationNodeType.hpp>
#include <com/sun/star/animations/ValuePair.hpp>
#include <com/sun/star/presentation/EffectCommands.hpp>
#include <com/sun/star/beans/NamedValue.hpp>

#include <oox/helper/attributelist.hxx>
#include <oox/core/xmlfilterbase.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <drawingml/colorchoicecontext.hxx>
#include <oox/ppt/slidetransition.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
#include <o3tl/string_view.hxx>
#include <sax/fastattribs.hxx>
#include <utility>

#include "animvariantcontext.hxx"
#include "commonbehaviorcontext.hxx"
#include "conditioncontext.hxx"
#include "commontimenodecontext.hxx"
#include "timeanimvaluecontext.hxx"
#include "animationtypes.hxx"
#include "timetargetelementcontext.hxx"

using namespace ::oox::core;
using namespace ::oox::drawingml;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::animations;
using namespace ::com::sun::star::presentation;
using namespace ::com::sun::star::xml::sax;
using ::com::sun::star::beans::NamedValue;

namespace {

    oox::ppt::AnimationAttributeEnum getAttributeEnumByAPIName(std::u16string_view rAPIName)
    {
        oox::ppt::AnimationAttributeEnum eResult = oox::ppt::AnimationAttributeEnum::UNKNOWN;
        const oox::ppt::ImplAttributeNameConversion *attrConv = oox::ppt::getAttributeConversionList();
        while(attrConv->mpAPIName != nullptr)
        {
            if(o3tl::equalsAscii(rAPIName, attrConv->mpAPIName))
            {
                eResult = attrConv->meAttribute;
                break;
            }
            attrConv++;
        }
        return eResult;
    }

    bool convertAnimationValueWithTimeNode(const oox::ppt::TimeNodePtr& pNode, css::uno::Any &rAny)
    {
        css::uno::Any aAny = pNode->getNodeProperties()[oox::ppt::NP_ATTRIBUTENAME];
        OUString aNameList;
        aAny >>= aNameList;

        // only get first token.
        return oox::ppt::convertAnimationValue(getAttributeEnumByAPIName(o3tl::getToken(aNameList, 0, ';')), rAny);
    }

    css::uno::Any convertPointPercent(const css::awt::Point& rPoint)
    {
        css::animations::ValuePair aPair;
        // rPoint.X and rPoint.Y are in 1000th of a percent, but we only need ratio.
        aPair.First <<= static_cast<double>(rPoint.X) / 100000.0;
        aPair.Second <<= static_cast<double>(rPoint.Y) / 100000.0;
        return Any(aPair);
    }
}

namespace oox::ppt {

    namespace {

    struct AnimColor
    {
        AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
            : colorSpace( cs ), one( o ), two( t ), three( th )
            {
            }

        Any get() const
            {
                sal_Int32 nColor;
                Any aColor;

                switch( colorSpace )
                {
                case AnimationColorSpace::HSL:
                    aColor <<= Sequence< double >{ one / 100000.0, two / 100000.0, three / 100000.0 };
                    break;
                case AnimationColorSpace::RGB:
                    nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
                        | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
                        | ( ( ( three * 128 ) / 1000 )  & 0xff );
                    aColor <<= nColor;
                    break;
                default:
                    nColor = 0;
                    aColor <<= nColor;
                    break;
                }
                return  aColor;
            }

        sal_Int16 colorSpace;
        sal_Int32 one;
        sal_Int32 two;
        sal_Int32 three;
    };

    /** CT_TLMediaNodeAudio
            CT_TLMediaNodeVideo */

    class MediaNodeContext
        : public TimeNodeContext
    {
    public:
        MediaNodeContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                            const Reference< XFastAttributeList >& xAttribs,
                            const TimeNodePtr & pNode )
            : TimeNodeContext( rParent, aElement, pNode )
                , mbIsNarration( false )
                , mbFullScrn( false )
                , mbHideDuringShow(false)
            {
                AttributeList attribs( xAttribs );

                switch( aElement )
                {
                case PPT_TOKEN( audio ):
                    mbIsNarration = attribs.getBool( XML_isNarration, false );
                    break;
                case PPT_TOKEN( video ):
                    mbFullScrn = attribs.getBool( XML_fullScrn, false );
                    break;
                default:
                    break;
                }
            }

        virtual void onEndElement() override
            {
                sal_Int32 aElement = getCurrentElement();
                if( aElement == PPT_TOKEN( audio ) )
                {
                    mpNode->getNodeProperties()[NP_ISNARRATION] <<= mbIsNarration;
                }
                else if( aElement == PPT_TOKEN( video ) )
                {
                    // TODO deal with mbFullScrn
                }
                else if (aElement == PPT_TOKEN(cMediaNode))
                {
                    mpNode->getNodeProperties()[NP_HIDEDURINGSHOW] <<= mbHideDuringShow;
                }
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cTn ):
                    return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
                case PPT_TOKEN( tgtEl ):
                    return new TimeTargetElementContext( *this, mpNode->getTarget() );
                case PPT_TOKEN(cMediaNode):
                    mbHideDuringShow = !rAttribs.getBool(XML_showWhenStopped, true);
                    break;
                default:
                    break;
                }

                return this;
            }

    private:
        bool mbIsNarration;
        bool mbFullScrn;
        bool mbHideDuringShow;
    };

    /** CT_TLSetBehavior
     */

    class SetTimeNodeContext
        : public TimeNodeContext
    {
    public:
        SetTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                            const TimeNodePtr & pNode )
            : TimeNodeContext( rParent, aElement, pNode )
            {

            }

        virtual ~SetTimeNodeContext() noexcept override
            {
                if(maTo.hasValue())
                {
                    convertAnimationValueWithTimeNode(mpNode, maTo);
                    mpNode->setTo(maTo);
                }

            }

            virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cBhvr ):
                    return new CommonBehaviorContext ( *this, mpNode );
                case PPT_TOKEN( to ):
                    // CT_TLAnimVariant
                    return new AnimVariantContext( *this, aElementToken, maTo );
                default:
                    break;
                }

                return this;
            }
    private:
        Any  maTo;
    };

    /** CT_TLCommandBehavior
     */

    class CmdTimeNodeContext
        : public TimeNodeContext
    {
    public:
        CmdTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                            const Reference< XFastAttributeList >& xAttribs,
                            const TimeNodePtr & pNode )
            : TimeNodeContext( rParent, aElement, pNode )
                , maType(0)
            {
                switch ( aElement )
                {
                case PPT_TOKEN( cmd ):
                    msCommand = xAttribs->getOptionalValue( XML_cmd );
                    maType = xAttribs->getOptionalValueToken( XML_type, 0 );
                    break;
                default:
                    break;
                }
            }

        virtual void onEndElement() override
            {
                if( !isCurrentElement( PPT_TOKEN( cmd ) ) )
                    return;

                try {
                    // see sd/source/filter/ppt/pptinanimations.cxx
                    // in AnimationImporter::importCommandContainer()
                    // REFACTOR?
                    // a good chunk of this code has been copied verbatim *sigh*
                    sal_Int16 nCommand = EffectCommands::CUSTOM;
                    NamedValue aParamValue;

                    switch( maType )
                    {
                    case XML_verb:
                        aParamValue.Name = "Verb";
                        // TODO make sure msCommand has what we want
                        aParamValue.Value <<= msCommand.toInt32();
                        nCommand = EffectCommands::VERB;
                        break;
                    case XML_evt:
                    case XML_call:
                        if ( msCommand == "onstopaudio" )
                        {
                            nCommand = EffectCommands::STOPAUDIO;
                        }
                        else if ( msCommand == "play" )
                        {
                            nCommand = EffectCommands::PLAY;
                        }
                        else if (msCommand.startsWith("playFrom"))
                        {
                            std::u16string_view aMediaTime( msCommand.subView( 9, msCommand.getLength() - 10 ) );
                            rtl_math_ConversionStatus eStatus;
                            double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, u'.', u',', &eStatus );
                            if( eStatus == rtl_math_ConversionStatus_Ok )
                            {
                                aParamValue.Name = "MediaTime";
                                aParamValue.Value <<= fMediaTime;
                            }
                            nCommand = EffectCommands::PLAY;
                        }
                        else if ( msCommand == "togglePause" )
                        {
                            nCommand = EffectCommands::TOGGLEPAUSE;
                        }
                        else if ( msCommand == "stop" )
                        {
                            nCommand = EffectCommands::STOP;
                        }
                        break;
                    }
                    mpNode->getNodeProperties()[ NP_COMMAND ] <<= nCommand;
                    if( nCommand == EffectCommands::CUSTOM )
                    {
                        SAL_WARN("oox.ppt""OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
                        aParamValue.Name = "UserDefined";
                        aParamValue.Value <<= msCommand;
                    }
                    if( aParamValue.Value.hasValue() )
                    {
                        Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
                        mpNode->getNodeProperties()[ NP_PARAMETER ] <<= aParamSeq;
                    }
                }
                catch( RuntimeException& )
                {
                    TOOLS_WARN_EXCEPTION("oox.ppt""OOX: Exception in CmdTimeNodeContext::endFastElement()" );
                }
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cBhvr ):
                    return new CommonBehaviorContext ( *this, mpNode );
                default:
                    break;
                }

                return this;
            }

    private:
        OUString msCommand;
        sal_Int32 maType;
    };

    /** CT_TLTimeNodeSequence
     */

    class SequenceTimeNodeContext
        : public TimeNodeContext
    {
    public:
        SequenceTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                                 const Reference< XFastAttributeList >& xAttribs,
                                 const TimeNodePtr & pNode )
            : TimeNodeContext( rParent, aElement, pNode )
                , mnNextAc(0)
                , mnPrevAc(0)
            {
                AttributeList attribs(xAttribs);
                mbConcurrent = attribs.getBool( XML_concurrent, false );
                mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
                mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cTn ):
                    return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
                case PPT_TOKEN( nextCondLst ):
                    return new CondListContext( *this, aElementToken, mpNode, mpNode->getNextCondition() );
                case PPT_TOKEN( prevCondLst ):
                    return new CondListContext( *this, aElementToken, mpNode, mpNode->getPrevCondition() );
                default:
                    break;
                }

                return this;
            }
    private:
        bool mbConcurrent;
        sal_Int32 mnNextAc, mnPrevAc;
    };

    /** CT_TLTimeNodeParallel
     *  CT_TLTimeNodeExclusive
     */

    class ParallelExclTimeNodeContext
        : public TimeNodeContext
    {
    public:
        ParallelExclTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                                     const TimeNodePtr & pNode )
            : TimeNodeContext( rParent, aElement, pNode )
            {
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cTn ):
                    return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
                default:
                    break;
                }

                return this;
            }

    protected:

    };

    /** CT_TLAnimateColorBehavior */
    class AnimColorContext
        : public TimeNodeContext
    {
    public:
        AnimColorContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                            const Reference< XFastAttributeList >& xAttribs,
                            const TimeNodePtr & pNode ) noexcept
            : TimeNodeContext( rParent, aElement, pNode )
            , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
            , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
            , mbHasByColor( false )
            , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
            {
            }

        virtual void onEndElement() override
            {
                //xParentNode
                if( !isCurrentElement( mnElement ) )
                    return;

                NodePropertyMap & rProps(mpNode->getNodeProperties());
                rProps[ NP_DIRECTION ] <<= mnDir == XML_cw;
                rProps[ NP_COLORINTERPOLATION ] <<= mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB;
                const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
                if( maToClr.isUsed() )
                    mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) );
                if( maFromClr.isUsed() )
                    mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) );
                if( mbHasByColor )
                    mpNode->setBy( m_byColor.get() );
            }

            virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( hsl ):
                    // CT_TLByHslColorTransform
                {
                    if( mbHasByColor )
                    {
                        m_byColor.colorSpace = AnimationColorSpace::HSL;
                        m_byColor.one = rAttribs.getInteger( XML_h, 0 );
                        m_byColor.two = rAttribs.getInteger( XML_s, 0 );
                        m_byColor.three = rAttribs.getInteger( XML_l, 0 );
                    }
                    return this;
                }
                case PPT_TOKEN( rgb ):
                {
                    if( mbHasByColor )
                    {
                        // CT_TLByRgbColorTransform
                        m_byColor.colorSpace = AnimationColorSpace::RGB;
                        m_byColor.one = rAttribs.getInteger( XML_r, 0 );
                        m_byColor.two = rAttribs.getInteger( XML_g, 0 );
                        m_byColor.three = rAttribs.getInteger( XML_b, 0 );
                    }
                    return this;
                }
                case PPT_TOKEN( by ):
                    // CT_TLByAnimateColorTransform
                    mbHasByColor = true;
                    return this;
                case PPT_TOKEN( cBhvr ):
                    return new CommonBehaviorContext ( *this, mpNode );
                case PPT_TOKEN( to ):
                    // CT_Color
                    return new ColorContext( *this, maToClr );
                case PPT_TOKEN( from ):
                    // CT_Color
                    return new ColorContext( *this, maFromClr );

                default:
                    break;
                }

                return this;
            }

    private:
        sal_Int32 mnColorSpace;
        sal_Int32 mnDir;
        bool mbHasByColor;
        AnimColor m_byColor;
        oox::drawingml::Color maToClr;
        oox::drawingml::Color maFromClr;
    };

    /** CT_TLAnimateBehavior */
    class AnimContext
        : public TimeNodeContext
    {
    public:
        AnimContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                     const Reference< XFastAttributeList >& xAttribs,
                      const TimeNodePtr & pNode ) noexcept
            : TimeNodeContext( rParent, aElement, pNode )
            {
                NodePropertyMap & aProps( pNode->getNodeProperties() );
                sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
                if(nCalcMode)
                {
                    sal_Int16 nEnum = 0;
                    switch(nCalcMode)
                    {
                    case XML_lin:
                        nEnum = AnimationCalcMode::LINEAR;
                        break;
                    case XML_discrete:
                    case XML_fmla:
                    default:
                        // TODO what value is good ?
                        nEnum = AnimationCalcMode::DISCRETE;
                        break;
                    }
                    aProps[ NP_CALCMODE ] <<= nEnum;
                }

                msFrom = xAttribs->getOptionalValue(XML_from);
                msTo = xAttribs->getOptionalValue(XML_to);
                msBy = xAttribs->getOptionalValue(XML_by);

                mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
            }

        virtual ~AnimContext() noexcept override
            {
                if (!msFrom.isEmpty())
                {
                    css::uno::Any aAny;
                    aAny <<= msFrom;
                    convertAnimationValueWithTimeNode(mpNode, aAny);
                    mpNode->setFrom(aAny);
                }

                if (!msTo.isEmpty())
                {
                    css::uno::Any aAny;
                    aAny <<= msTo;
                    convertAnimationValueWithTimeNode(mpNode, aAny);
                    mpNode->setTo(aAny);
                }

                if (!msBy.isEmpty())
                {
                    css::uno::Any aAny;
                    aAny <<= msBy;
                    convertAnimationValueWithTimeNode(mpNode, aAny);
                    mpNode->setBy(aAny);
                }

                int nKeyTimes = maTavList.size();
                if( nKeyTimes <= 0)
                    return;

                int i=0;
                Sequence< double > aKeyTimes( nKeyTimes );
                auto pKeyTimes = aKeyTimes.getArray();
                Sequence< Any > aValues( nKeyTimes );
                auto pValues = aValues.getArray();

                NodePropertyMap & aProps( mpNode->getNodeProperties() );
                for (auto const& tav : maTavList)
                {
                    // TODO what to do if it is Timing_INFINITE ?
                    Any aTime = GetTimeAnimateValueTime( tav.msTime );
                    aTime >>= pKeyTimes[i];
                    pValues[i] = tav.maValue;
                    convertAnimationValueWithTimeNode(mpNode, pValues[i]);

                    // Examine pptx documents and find that only the first tav
                    // has the formula set. The formula can be used for the whole.
                    if (!tav.msFormula.isEmpty())
                    {
                        OUString sFormula = tav.msFormula;
                        (void)convertMeasure(sFormula);
                        aProps[NP_FORMULA] <<= sFormula;
                    }

                    ++i;
                }
                aProps[ NP_VALUES ] <<= aValues;
                aProps[ NP_KEYTIMES ] <<= aKeyTimes;
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cBhvr ):
                    return new CommonBehaviorContext ( *this, mpNode );
                case PPT_TOKEN( tavLst ):
                    return new TimeAnimValueListContext ( *this, maTavList );
                default:
                    break;
                }

                return this;
            }
    private:
        sal_Int32              mnValueType;
        TimeAnimationValueList maTavList;
        OUString msFrom;
        OUString msTo;
        OUString msBy;
    };

    /** CT_TLAnimateScaleBehavior */
    class AnimScaleContext
        : public TimeNodeContext
    {
    public:
        AnimScaleContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                            const Reference< XFastAttributeList >& xAttribs,
                            const TimeNodePtr & pNode )
            : TimeNodeContext( rParent, aElement, pNode )
                , mbZoomContents( false )
            {
                AttributeList attribs( xAttribs );
                // TODO what to do with mbZoomContents
                mbZoomContents = attribs.getBool( XML_zoomContents, false );
                pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
                    <<= sal_Int16(AnimationTransformType::SCALE);
            }

        virtual void onEndElement() override
            {
                if( !isCurrentElement( mnElement ) )
                    return;

                if( maTo.hasValue() )
                {
                    mpNode->setTo( maTo );
                }
                if( maBy.hasValue() )
                {
                    mpNode->setBy( maBy );
                }
                if( maFrom.hasValue() )
                {
                    mpNode->setFrom( maFrom );
                }
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cBhvr ):
                    return new CommonBehaviorContext ( *this, mpNode );
                case PPT_TOKEN( to ):
                {
                    // CT_TLPoint
                    maTo = convertPointPercent(GetPointPercent(rAttribs.getFastAttributeList()));
                    return this;
                }
                case PPT_TOKEN( from ):
                {
                    // CT_TLPoint
                    maFrom  = convertPointPercent(GetPointPercent(rAttribs.getFastAttributeList()));
                    return this;
                }
                case PPT_TOKEN( by ):
                {
                    // CT_TLPoint
                    css::awt::Point aPoint = GetPointPercent(rAttribs.getFastAttributeList());
                    // We got ending values instead of offset values, so subtract 100% from them.
                    aPoint.X -= 100000;
                    aPoint.Y -= 100000;
                    maBy = convertPointPercent(aPoint);
                    return this;
                }
                default:
                    break;
                }

                return this;
            }
    private:
        Any maBy;
        Any maFrom;
        Any maTo;
        bool mbZoomContents;
    };

    /** CT_TLAnimateRotationBehavior */
    class AnimRotContext
        : public TimeNodeContext
    {
    public:
        AnimRotContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                        const Reference< XFastAttributeList >& xAttribs,
                         const TimeNodePtr & pNode ) noexcept
            : TimeNodeContext( rParent, aElement, pNode )
            {
                AttributeList attribs( xAttribs );

                pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
                    <<= sal_Int16(AnimationTransformType::ROTATE);
                // see also DFF_msofbtAnimateRotationData in
                // sd/source/filter/ppt/pptinanimations.cxx
                if(attribs.hasAttribute( XML_by ) )
                {
                    double fBy = attribs.getDouble( XML_by, 0.0 ) / PER_DEGREE; //1 PowerPoint-angle-unit = 1/60000 degree
                    pNode->setBy( Any( fBy ) );
                }
                if(attribs.hasAttribute( XML_from ) )
                {
                    double fFrom = attribs.getDouble( XML_from, 0.0 ) / PER_DEGREE;
                    pNode->setFrom( Any( fFrom ) );
                }
                if(attribs.hasAttribute( XML_to ) )
                {
                    double fTo = attribs.getDouble( XML_to, 0.0 ) / PER_DEGREE;
                    pNode->setTo( Any( fTo ) );
                }
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cBhvr ):
                    return new CommonBehaviorContext ( *this, mpNode );
                default:
                    break;
                }

                return this;
            }
    };

    /** CT_TLAnimateMotionBehavior */
    class AnimMotionContext
        : public TimeNodeContext
    {
    public:
        AnimMotionContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                         const Reference< XFastAttributeList >& xAttribs,
                          const TimeNodePtr & pNode ) noexcept
            : TimeNodeContext( rParent, aElement, pNode )
            {
                pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
                    <<= sal_Int16(AnimationTransformType::TRANSLATE);

                AttributeList attribs( xAttribs );
                sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
                if( nOrigin != 0 )
                {
                    switch(nOrigin)
                    {
                    case XML_layout:
                    case XML_parent:
                        break;
                    }
                    // TODO
                }

                OUString aStr = xAttribs->getOptionalValue( XML_path );
                // E can appear inside a number, so we only check for its presence at the end
                aStr = aStr.trim();
                if (aStr.endsWith("E"))
                    aStr = aStr.copy(0, aStr.getLength() - 1);
                aStr = aStr.trim();
                pNode->getNodeProperties()[ NP_PATH ] <<= aStr;
                mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
                msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
                mnAngle = attribs.getInteger( XML_rAng, 0 );
                // TODO make sure the units are right. Likely not.
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cBhvr ):
                    return new CommonBehaviorContext ( *this, mpNode );
                case PPT_TOKEN( to ):
                {
                    // CT_TLPoint
                    awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
                    Any rAny;
                    rAny <<= p.X;
                    rAny <<= p.Y;
                    mpNode->setTo( rAny );
                    return this;
                }
                case PPT_TOKEN( from ):
                {
                    // CT_TLPoint
                    awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
                    Any rAny;
                    rAny <<= p.X;
                    rAny <<= p.Y;
                    mpNode->setFrom( rAny );
                    return this;
                }
                case PPT_TOKEN( by ):
                {
                    // CT_TLPoint
                    awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
                    Any rAny;
                    rAny <<= p.X;
                    rAny <<= p.Y;
                    mpNode->setBy( rAny );
                    return this;
                }
                case PPT_TOKEN( rCtr ):
                {
                    // CT_TLPoint
                    awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
                    // TODO push
                    (void)p;
                    return this;
                }
                default:
                    break;
                }

                return this;
            }
    private:
        OUString msPtsTypes;
        sal_Int32 mnPathEditMode;
        sal_Int32 mnAngle;
    };

    /** CT_TLAnimateEffectBehavior */
    class AnimEffectContext
        : public TimeNodeContext
    {
    public:
        AnimEffectContext( FragmentHandler2 const & rParent, sal_Int32  aElement,
                             const Reference< XFastAttributeList >& xAttribs,
                             const TimeNodePtr & pNode ) noexcept
            : TimeNodeContext( rParent, aElement, pNode )
            {
                sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
                OUString sFilter = xAttribs->getOptionalValue( XML_filter );
                // TODO
//              OUString sPrList = xAttribs->getOptionalValue( XML_prLst );

                if( !sFilter.isEmpty() )
                {
                    SlideTransition aFilter( sFilter );
                    aFilter.setMode( nDir != XML_out );
                    pNode->setTransitionFilter( aFilter );
                }
            }

        virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
            {
                switch ( aElementToken )
                {
                case PPT_TOKEN( cBhvr ):
                    return new CommonBehaviorContext ( *this, mpNode );
                case PPT_TOKEN( progress ):
                    return new AnimVariantContext( *this, aElementToken, maProgress );
                    // TODO handle it.
                default:
                    break;
                }

                return this;
            }
    private:
        Any maProgress;
    };

    }

    rtl::Reference<TimeNodeContext> TimeNodeContext::makeContext(
            FragmentHandler2 const & rParent, sal_Int32  aElement,
            const Reference< XFastAttributeList >& xAttribs,
            const TimeNodePtr & pNode )
    {
        rtl::Reference<TimeNodeContext> pCtx;
        switch( aElement )
        {
        case PPT_TOKEN( animClr ):
            pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
            break;
        case PPT_TOKEN( seq ):
            pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
            break;
        case PPT_TOKEN( par ):
        case PPT_TOKEN( excl ):
            pCtx = new ParallelExclTimeNodeContext( rParent, aElement, pNode );
            break;
        case PPT_TOKEN( anim ):
            pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
            break;
        case PPT_TOKEN( animEffect ):
            pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
            break;
        case PPT_TOKEN( animMotion ):
            pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
            break;
        case PPT_TOKEN( animRot ):
            pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
            break;
        case PPT_TOKEN( animScale ):
            pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
            break;
        case PPT_TOKEN( cmd ):
            pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
            break;
        case PPT_TOKEN( set ):
            pCtx = new SetTimeNodeContext( rParent, aElement, pNode );
            break;
        case PPT_TOKEN( audio ):
        case PPT_TOKEN( video ):
            pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
            break;
        default:
            break;
        }
        return pCtx;
    }

    TimeNodeContext::TimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
            TimeNodePtr pNode ) noexcept
        : FragmentHandler2( rParent )
        , mnElement( aElement )
        , mpNode(std::move( pNode ))
    {
    }

    TimeNodeContext::~TimeNodeContext( ) noexcept
    {

    }

    TimeNodeListContext::TimeNodeListContext( FragmentHandler2 const & rParent, TimeNodePtrList & aList )
        noexcept
        : FragmentHandler2( rParent )
            , maList( aList )
    {
    }

    TimeNodeListContext::~TimeNodeListContext( ) noexcept
    {
    }

    ::oox::core::ContextHandlerRef TimeNodeListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
    {
        sal_Int16 nNodeType;

        switch( aElementToken )
        {
        case PPT_TOKEN( seq ):
            nNodeType = AnimationNodeType::SEQ;
            break;
        case PPT_TOKEN( par ):
        case PPT_TOKEN( excl ):
            // TODO pick the right type. We choose parallel for now as
            // there does not seem to be an "Exclusive"
            nNodeType = AnimationNodeType::PAR;
            break;
        case PPT_TOKEN( anim ):
            nNodeType = AnimationNodeType::ANIMATE;
            break;
        case PPT_TOKEN( animClr ):
            nNodeType = AnimationNodeType::ANIMATECOLOR;
            break;
        case PPT_TOKEN( animEffect ):
            nNodeType = AnimationNodeType::TRANSITIONFILTER;
            break;
        case PPT_TOKEN( animMotion ):
            nNodeType = AnimationNodeType::ANIMATEMOTION;
            break;
        case PPT_TOKEN( animRot ):
        case PPT_TOKEN( animScale ):
            nNodeType = AnimationNodeType::ANIMATETRANSFORM;
            break;
        case PPT_TOKEN( cmd ):
            nNodeType = AnimationNodeType::COMMAND;
            break;
        case PPT_TOKEN( set ):
            nNodeType = AnimationNodeType::SET;
            break;
        case PPT_TOKEN( audio ):
            nNodeType = AnimationNodeType::AUDIO;
            break;
        case PPT_TOKEN( video ):
            nNodeType = AnimationNodeType::AUDIO;
            SAL_WARN("oox.ppt""OOX: video requested, gave Audio instead" );
            break;

        default:
            nNodeType = AnimationNodeType::CUSTOM;
            SAL_INFO("oox.ppt""unhandled token " << aElementToken);
            break;
        }

        TimeNodePtr pNode = std::make_shared<TimeNode>(nNodeType);
        maList.push_back( pNode );
        rtl::Reference<FragmentHandler2> pContext = TimeNodeContext::makeContext( *this, aElementToken, rAttribs.getFastAttributeList(), pNode );

        return pContext ? pContext : this;
    }

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=97 H=95 G=95

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.