Since it is now possible to use C++14, it's time to replace the temporary solution with the standard one Change-Id: Ib3201f865d43f372007cdf381c7e244e9cbeae26 Reviewed-on: https://gerrit.libreoffice.org/67474 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
1382 lines
50 KiB
C++
1382 lines
50 KiB
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 <memory>
|
|
#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
|
|
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
|
#include <com/sun/star/lang/XServiceInfo.hpp>
|
|
#include <com/sun/star/lang/XInitialization.hpp>
|
|
#include <com/sun/star/animations/AnimationTransformType.hpp>
|
|
#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
|
|
#include <com/sun/star/animations/AnimationNodeType.hpp>
|
|
#include <com/sun/star/animations/SequenceTimeContainer.hpp>
|
|
#include <com/sun/star/animations/XIterateContainer.hpp>
|
|
#include <com/sun/star/animations/XAnimateMotion.hpp>
|
|
#include <com/sun/star/animations/XAnimateColor.hpp>
|
|
#include <com/sun/star/animations/XAnimateTransform.hpp>
|
|
#include <com/sun/star/animations/XTransitionFilter.hpp>
|
|
#include <com/sun/star/animations/XCommand.hpp>
|
|
#include <com/sun/star/animations/XAudio.hpp>
|
|
#include <com/sun/star/animations/ValuePair.hpp>
|
|
#include <com/sun/star/animations/AnimationColorSpace.hpp>
|
|
#include <com/sun/star/presentation/EffectPresetClass.hpp>
|
|
#include <com/sun/star/animations/Timing.hpp>
|
|
#include <com/sun/star/animations/Event.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/xml/sax/XAttributeList.hpp>
|
|
#include <com/sun/star/text/XTextCursor.hpp>
|
|
#include <com/sun/star/text/XTextRangeCompare.hpp>
|
|
#include <com/sun/star/presentation/ParagraphTarget.hpp>
|
|
#include <com/sun/star/container/XEnumerationAccess.hpp>
|
|
#include <com/sun/star/animations/EventTrigger.hpp>
|
|
#include <com/sun/star/presentation/EffectCommands.hpp>
|
|
#include <com/sun/star/util/Duration.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <comphelper/string.hxx>
|
|
|
|
#include <sax/tools/converter.hxx>
|
|
|
|
#include <vector>
|
|
|
|
#include <xmloff/xmltypes.hxx>
|
|
#include "sdpropls.hxx"
|
|
#include <xmloff/xmltoken.hxx>
|
|
#include <xmloff/xmlimp.hxx>
|
|
#include <xmloff/xmlnmspe.hxx>
|
|
#include <xmloff/xmluconv.hxx>
|
|
#include <osl/diagnose.h>
|
|
#include <xmloff/nmspmap.hxx>
|
|
#include <xmloff/xmlprhdl.hxx>
|
|
#include <anim.hxx>
|
|
#include <facreg.hxx>
|
|
|
|
#include <animations.hxx>
|
|
#include <animationimport.hxx>
|
|
|
|
using namespace ::std;
|
|
using namespace ::cppu;
|
|
using namespace ::com::sun::star::beans;
|
|
using namespace ::com::sun::star::animations;
|
|
using namespace ::com::sun::star::presentation;
|
|
using namespace ::com::sun::star::drawing;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::xmloff::token;
|
|
|
|
using ::com::sun::star::xml::sax::XAttributeList;
|
|
using ::com::sun::star::beans::NamedValue;
|
|
using ::com::sun::star::text::XTextRange;
|
|
using ::com::sun::star::text::XTextCursor;
|
|
using ::com::sun::star::text::XTextRangeCompare;
|
|
using ::com::sun::star::container::XEnumerationAccess;
|
|
using ::com::sun::star::container::XEnumeration;
|
|
using ::com::sun::star::lang::XMultiServiceFactory;
|
|
using ::com::sun::star::lang::XInitialization;
|
|
|
|
Sequence< OUString > AnimationsImport_getSupportedServiceNames() throw()
|
|
{
|
|
return Sequence< OUString > { "com.sun.star.comp.Xmloff.AnimationsImport" };
|
|
}
|
|
|
|
OUString AnimationsImport_getImplementationName() throw()
|
|
{
|
|
return OUString( "xmloff::AnimationsImport" );
|
|
}
|
|
|
|
static OUString
|
|
lcl_GetMediaReference(SvXMLImport const& rImport, OUString const& rURL)
|
|
{
|
|
if (rImport.IsPackageURL(rURL))
|
|
return "vnd.sun.star.Package:" + rURL;
|
|
|
|
return rImport.GetAbsoluteReference(rURL);
|
|
}
|
|
|
|
namespace xmloff
|
|
{
|
|
|
|
class AnimationsImportHelperImpl
|
|
{
|
|
private:
|
|
SvXMLImport& mrImport;
|
|
|
|
std::unique_ptr<SvXMLTokenMap> mpAnimationNodeTokenMap;
|
|
std::unique_ptr<SvXMLTokenMap> mpAnimationNodeAttributeTokenMap;
|
|
|
|
public:
|
|
explicit AnimationsImportHelperImpl( SvXMLImport& rImport );
|
|
|
|
const SvXMLTokenMap& getAnimationNodeTokenMap();
|
|
const SvXMLTokenMap& getAnimationNodeAttributeTokenMap();
|
|
|
|
Any convertValue( XMLTokenEnum eAttributeName, const OUString& rValue );
|
|
Sequence< Any > convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue );
|
|
|
|
Any convertTarget( const OUString& rValue );
|
|
static Any convertPath( const OUString& rValue );
|
|
Any convertTiming( const OUString& rValue );
|
|
static Sequence< double > convertKeyTimes( const OUString& rValue );
|
|
static Sequence< TimeFilterPair > convertTimeFilter( const OUString& rValue );
|
|
};
|
|
|
|
AnimationsImportHelperImpl::AnimationsImportHelperImpl( SvXMLImport& rImport )
|
|
: mrImport( rImport )
|
|
{
|
|
}
|
|
|
|
const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeTokenMap()
|
|
{
|
|
if( mpAnimationNodeTokenMap == nullptr )
|
|
{
|
|
static const SvXMLTokenMapEntry aAnimationNodeTokenMap[] =
|
|
{
|
|
{ XML_NAMESPACE_ANIMATION, XML_PAR, sal_uInt16(AnimationNodeType::PAR) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_SEQ, sal_uInt16(AnimationNodeType::SEQ) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_ITERATE, sal_uInt16(AnimationNodeType::ITERATE) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_ANIMATE, sal_uInt16(AnimationNodeType::ANIMATE) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_SET, sal_uInt16(AnimationNodeType::SET) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_ANIMATEMOTION, sal_uInt16(AnimationNodeType::ANIMATEMOTION) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_ANIMATECOLOR, sal_uInt16(AnimationNodeType::ANIMATECOLOR) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_ANIMATETRANSFORM, sal_uInt16(AnimationNodeType::ANIMATETRANSFORM) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_TRANSITIONFILTER, sal_uInt16(AnimationNodeType::TRANSITIONFILTER) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_AUDIO, sal_uInt16(AnimationNodeType::AUDIO) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_COMMAND, sal_uInt16(AnimationNodeType::COMMAND) },
|
|
XML_TOKEN_MAP_END
|
|
};
|
|
|
|
mpAnimationNodeTokenMap = std::make_unique<SvXMLTokenMap>( aAnimationNodeTokenMap );
|
|
}
|
|
|
|
return *mpAnimationNodeTokenMap;
|
|
}
|
|
|
|
enum AnimationNodeAttributes
|
|
{
|
|
ANA_Begin,
|
|
ANA_Dur,
|
|
ANA_End,
|
|
ANA_Fill,
|
|
ANA_FillDefault,
|
|
ANA_Restart,
|
|
ANA_RestartDefault,
|
|
ANA_Accelerate,
|
|
ANA_Decelerate,
|
|
ANA_AutoReverse,
|
|
ANA_RepeatCount,
|
|
ANA_RepeatDur,
|
|
ANA_EndSync,
|
|
ANA_Node_Type,
|
|
ANA_Preset_ID,
|
|
ANA_Preset_Sub_Type,
|
|
ANA_Preset_Class,
|
|
ANA_After_Effect,
|
|
ANA_Target,
|
|
ANA_XLink,
|
|
ANA_MasterElement,
|
|
ANA_SubItem,
|
|
ANA_AttributeName,
|
|
ANA_Values,
|
|
ANA_From,
|
|
ANA_By,
|
|
ANA_To,
|
|
ANA_KeyTimes,
|
|
ANA_CalcMode,
|
|
ANA_Accumulate,
|
|
ANA_AdditiveMode,
|
|
ANA_KeySplines,
|
|
ANA_Path,
|
|
ANA_ColorSpace,
|
|
ANA_ColorDirection,
|
|
ANA_TransformType,
|
|
ANA_TransitionType,
|
|
ANA_TransitionSubType,
|
|
ANA_Mode,
|
|
ANA_Direction,
|
|
ANA_FadeColor,
|
|
ANA_IterateType,
|
|
ANA_IterateInterval,
|
|
ANA_Formula,
|
|
ANA_ANIMID,
|
|
ANA_XMLID,
|
|
ANA_Group_Id,
|
|
ANA_Command,
|
|
ANA_Volume
|
|
};
|
|
|
|
const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeAttributeTokenMap()
|
|
{
|
|
if( mpAnimationNodeAttributeTokenMap == nullptr )
|
|
{
|
|
static const SvXMLTokenMapEntry aAnimationNodeAttributeTokenMap[] =
|
|
{
|
|
{ XML_NAMESPACE_SMIL, XML_BEGIN, sal_uInt16(ANA_Begin) },
|
|
{ XML_NAMESPACE_SMIL, XML_DUR, sal_uInt16(ANA_Dur) },
|
|
{ XML_NAMESPACE_SMIL, XML_END, sal_uInt16(ANA_End) },
|
|
{ XML_NAMESPACE_SMIL, XML_FILL, sal_uInt16(ANA_Fill) },
|
|
{ XML_NAMESPACE_SMIL, XML_FILLDEFAULT, sal_uInt16(ANA_FillDefault) },
|
|
{ XML_NAMESPACE_SMIL, XML_RESTART, sal_uInt16(ANA_Restart) },
|
|
{ XML_NAMESPACE_SMIL, XML_RESTARTDEFAULT, sal_uInt16(ANA_RestartDefault) },
|
|
{ XML_NAMESPACE_SMIL, XML_ACCELERATE, sal_uInt16(ANA_Accelerate) },
|
|
{ XML_NAMESPACE_SMIL, XML_DECELERATE, sal_uInt16(ANA_Decelerate) },
|
|
{ XML_NAMESPACE_SMIL, XML_AUTOREVERSE, sal_uInt16(ANA_AutoReverse) },
|
|
{ XML_NAMESPACE_SMIL, XML_REPEATCOUNT, sal_uInt16(ANA_RepeatCount) },
|
|
{ XML_NAMESPACE_SMIL, XML_REPEATDUR, sal_uInt16(ANA_RepeatDur) },
|
|
{ XML_NAMESPACE_SMIL, XML_ENDSYNC, sal_uInt16(ANA_EndSync) },
|
|
{ XML_NAMESPACE_PRESENTATION, XML_NODE_TYPE, sal_uInt16(ANA_Node_Type) },
|
|
{ XML_NAMESPACE_PRESENTATION, XML_PRESET_ID, sal_uInt16(ANA_Preset_ID) },
|
|
{ XML_NAMESPACE_PRESENTATION, XML_PRESET_SUB_TYPE, sal_uInt16(ANA_Preset_Sub_Type) },
|
|
{ XML_NAMESPACE_PRESENTATION, XML_PRESET_CLASS, sal_uInt16(ANA_Preset_Class) },
|
|
{ XML_NAMESPACE_PRESENTATION, XML_AFTER_EFFECT, sal_uInt16(ANA_After_Effect) },
|
|
{ XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sal_uInt16(ANA_Target) },
|
|
{ XML_NAMESPACE_XLINK, XML_HREF, sal_uInt16(ANA_XLink) },
|
|
{ XML_NAMESPACE_PRESENTATION, XML_MASTER_ELEMENT, sal_uInt16(ANA_MasterElement) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, sal_uInt16(ANA_SubItem) },
|
|
{ XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, sal_uInt16(ANA_AttributeName) },
|
|
{ XML_NAMESPACE_SMIL, XML_VALUES, sal_uInt16(ANA_Values) },
|
|
{ XML_NAMESPACE_SMIL, XML_FROM, sal_uInt16(ANA_From) },
|
|
{ XML_NAMESPACE_SMIL, XML_BY, sal_uInt16(ANA_By) },
|
|
{ XML_NAMESPACE_SMIL, XML_TO, sal_uInt16(ANA_To) },
|
|
{ XML_NAMESPACE_SMIL, XML_KEYTIMES, sal_uInt16(ANA_KeyTimes) },
|
|
{ XML_NAMESPACE_SMIL, XML_CALCMODE, sal_uInt16(ANA_CalcMode) },
|
|
{ XML_NAMESPACE_SMIL, XML_ACCUMULATE, sal_uInt16(ANA_Accumulate) },
|
|
{ XML_NAMESPACE_PRESENTATION, XML_ADDITIVE, sal_uInt16(ANA_AdditiveMode) },
|
|
{ XML_NAMESPACE_SMIL, XML_ADDITIVE, sal_uInt16(ANA_AdditiveMode) },
|
|
{ XML_NAMESPACE_SMIL, XML_KEYSPLINES, sal_uInt16(ANA_KeySplines) },
|
|
{ XML_NAMESPACE_SVG, XML_PATH, sal_uInt16(ANA_Path) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION, sal_uInt16(ANA_ColorSpace) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION_DIRECTION, sal_uInt16(ANA_ColorDirection) },
|
|
{ XML_NAMESPACE_SVG, XML_TYPE, sal_uInt16(ANA_TransformType) },
|
|
{ XML_NAMESPACE_SMIL, XML_TYPE, sal_uInt16(ANA_TransitionType) },
|
|
{ XML_NAMESPACE_SMIL, XML_SUBTYPE, sal_uInt16(ANA_TransitionSubType) },
|
|
{ XML_NAMESPACE_SMIL, XML_MODE, sal_uInt16(ANA_Mode) },
|
|
{ XML_NAMESPACE_SMIL, XML_DIRECTION, sal_uInt16(ANA_Direction) },
|
|
{ XML_NAMESPACE_SMIL, XML_FADECOLOR, sal_uInt16(ANA_FadeColor) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_ITERATE_TYPE, sal_uInt16(ANA_IterateType) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_ITERATE_INTERVAL, sal_uInt16(ANA_IterateInterval) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_FORMULA, sal_uInt16(ANA_Formula) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_ID, sal_uInt16(ANA_ANIMID) },
|
|
{ XML_NAMESPACE_XML, XML_ID, sal_uInt16(ANA_XMLID) },
|
|
{ XML_NAMESPACE_PRESENTATION, XML_GROUP_ID, sal_uInt16(ANA_Group_Id) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_AUDIO_LEVEL, sal_uInt16(ANA_Volume) },
|
|
{ XML_NAMESPACE_ANIMATION, XML_COMMAND, sal_uInt16(ANA_Command) },
|
|
|
|
XML_TOKEN_MAP_END
|
|
};
|
|
|
|
mpAnimationNodeAttributeTokenMap = std::make_unique<SvXMLTokenMap>( aAnimationNodeAttributeTokenMap );
|
|
}
|
|
|
|
return *mpAnimationNodeAttributeTokenMap;
|
|
}
|
|
|
|
static bool isDouble( const OUString& rValue )
|
|
{
|
|
sal_Int32 nLength = rValue.getLength();
|
|
const sal_Unicode * pStr = rValue.getStr();
|
|
while( nLength )
|
|
{
|
|
if( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' )
|
|
{
|
|
pStr++;
|
|
nLength--;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool isTime( const OUString& rValue )
|
|
{
|
|
sal_Int32 nLength = rValue.getLength();
|
|
const sal_Unicode * pStr;
|
|
for( pStr = rValue.getStr(); nLength; pStr++, nLength-- )
|
|
{
|
|
if( !( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) )
|
|
break;
|
|
}
|
|
|
|
// return true if this is a double (if someone forgot the 's' we silently ignore it)
|
|
// or if it's a double that ends with a 's' or 'S'
|
|
return (nLength == 0) || ((*pStr == 's' || *pStr == 'S') && (nLength == 1));
|
|
}
|
|
|
|
Any AnimationsImportHelperImpl::convertTarget( const OUString& rValue )
|
|
{
|
|
try
|
|
{
|
|
Reference< XInterface > xRef( mrImport.getInterfaceToIdentifierMapper().getReference( rValue ) );
|
|
|
|
Reference< XShape > _xShape( xRef, UNO_QUERY );
|
|
if( _xShape.is() )
|
|
return makeAny( _xShape );
|
|
|
|
Reference< XTextCursor > xTextCursor( xRef, UNO_QUERY );
|
|
if( xTextCursor.is() )
|
|
{
|
|
Reference< XTextRange > xStart( xTextCursor->getStart() ), xRange;
|
|
Reference< XShape > xShape( xTextCursor->getText(), UNO_QUERY_THROW );
|
|
Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW );
|
|
Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
sal_Int16 nParagraph = 0;
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
{
|
|
xEnumeration->nextElement() >>= xRange;
|
|
|
|
// break if start of selection is prior to end of current paragraph
|
|
if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) )
|
|
{
|
|
return makeAny( ParagraphTarget( xShape, nParagraph ) );
|
|
}
|
|
|
|
nParagraph++;
|
|
}
|
|
}
|
|
}
|
|
catch (const RuntimeException&)
|
|
{
|
|
OSL_FAIL( "xmloff::AnimationsImportImpl::convertTarget(), RuntimeException caught!" );
|
|
}
|
|
|
|
Any aAny;
|
|
return aAny;
|
|
}
|
|
|
|
Any AnimationsImportHelperImpl::convertValue( XMLTokenEnum eAttributeName, const OUString& rValue )
|
|
{
|
|
sal_Int32 nCommaPos = -1, nPos;
|
|
sal_Int32 nOpenBrakets = 0;
|
|
for( nPos = 0; (nPos < rValue.getLength()) && (nCommaPos == -1); nPos++ )
|
|
{
|
|
switch( rValue[nPos] )
|
|
{
|
|
case ',':
|
|
if( nOpenBrakets == 0 )
|
|
nCommaPos = nPos;
|
|
break;
|
|
case '(':
|
|
case '[':
|
|
case '{':
|
|
nOpenBrakets++;
|
|
break;
|
|
case ')':
|
|
case ']':
|
|
case '}':
|
|
nOpenBrakets--;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( nCommaPos >= 0 )
|
|
{
|
|
ValuePair aPair;
|
|
aPair.First = convertValue( eAttributeName, rValue.copy( 0, nCommaPos ) );
|
|
aPair.Second = convertValue( eAttributeName, rValue.copy( nCommaPos+1 ) );
|
|
return makeAny( aPair );
|
|
}
|
|
else
|
|
{
|
|
Any aAny;
|
|
sal_Int32 nType = XML_TYPE_STRING;
|
|
|
|
if( rValue.getLength() ) switch( eAttributeName )
|
|
{
|
|
case XML_X:
|
|
case XML_Y:
|
|
case XML_WIDTH:
|
|
case XML_HEIGHT:
|
|
case XML_TRANSLATE:
|
|
{
|
|
return makeAny( rValue );
|
|
}
|
|
|
|
case XML_SCALE:
|
|
case XML_SKEWY:
|
|
case XML_SKEWX:
|
|
case XML_OPACITY:
|
|
case XML_ROTATE: nType = XML_TYPE_DOUBLE; break;
|
|
case XML_TEXT_ROTATION_ANGLE:nType = XML_TYPE_TEXT_ROTATION_ANGLE; break;
|
|
case XML_FILL_COLOR:
|
|
case XML_STROKE_COLOR:
|
|
case XML_DIM:
|
|
case XML_COLOR: nType = XML_TYPE_COLOR; break;
|
|
case XML_FILL: nType = XML_SD_TYPE_FILLSTYLE; break;
|
|
case XML_STROKE: nType = XML_SD_TYPE_STROKE; break;
|
|
case XML_FONT_WEIGHT: nType = XML_TYPE_TEXT_WEIGHT; break;
|
|
case XML_FONT_STYLE: nType = XML_TYPE_TEXT_POSTURE; break;
|
|
case XML_TEXT_UNDERLINE: nType = XML_TYPE_TEXT_UNDERLINE_STYLE; break;
|
|
case XML_FONT_SIZE: nType = XML_TYPE_DOUBLE_PERCENT; break;
|
|
case XML_VISIBILITY: nType = XML_SD_TYPE_PRESPAGE_VISIBILITY; break;
|
|
|
|
default:
|
|
if( !rValue.isEmpty() )
|
|
aAny <<= rValue;
|
|
return aAny;
|
|
}
|
|
|
|
const XMLPropertyHandler* pHandler = mrImport.GetShapeImport()->GetSdPropHdlFactory()->GetPropertyHandler( nType );
|
|
if( pHandler )
|
|
pHandler->importXML( rValue, aAny, mrImport.GetMM100UnitConverter() );
|
|
|
|
return aAny;
|
|
}
|
|
}
|
|
|
|
Sequence< Any > AnimationsImportHelperImpl::convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue )
|
|
{
|
|
Sequence< Any > aValues;
|
|
|
|
const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
|
|
if ( nElements>0 )
|
|
{
|
|
// prepare the sequence
|
|
aValues.realloc( nElements );
|
|
|
|
// fill the sequence
|
|
Any* pValues = aValues.getArray();
|
|
for (sal_Int32 nIndex = 0; nIndex >= 0; )
|
|
*pValues++ = convertValue( eAttributeName, rValue.getToken( 0, ';', nIndex ) );
|
|
}
|
|
|
|
return aValues;
|
|
}
|
|
|
|
Any AnimationsImportHelperImpl::convertTiming( const OUString& rValue )
|
|
{
|
|
Any aAny;
|
|
|
|
const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
|
|
if ( nElements>0 )
|
|
{
|
|
if( nElements == 1 )
|
|
{
|
|
if( IsXMLToken( rValue, XML_MEDIA ) )
|
|
{
|
|
aAny <<= Timing_MEDIA;
|
|
}
|
|
else if( IsXMLToken( rValue, XML_INDEFINITE ) )
|
|
{
|
|
aAny <<= Timing_INDEFINITE;
|
|
}
|
|
else if( isTime( rValue ) )
|
|
{
|
|
aAny <<= rValue.toDouble();
|
|
}
|
|
else
|
|
{
|
|
Event aEvent;
|
|
aEvent.Repeat = 0;
|
|
aEvent.Trigger = 0;
|
|
|
|
OUString aEventTrigger;
|
|
|
|
sal_Int32 nPos = rValue.indexOf( '+' );
|
|
if( nPos == -1 )
|
|
{
|
|
aEventTrigger = rValue;
|
|
}
|
|
else
|
|
{
|
|
aEventTrigger = rValue.copy( 0, nPos );
|
|
|
|
// convert offset
|
|
aEvent.Offset = convertTiming( rValue.copy( nPos + 1 ) );
|
|
}
|
|
|
|
nPos = aEventTrigger.indexOf( '.' );
|
|
if( nPos != -1 )
|
|
{
|
|
aEvent.Source <<= mrImport.getInterfaceToIdentifierMapper().getReference( aEventTrigger.copy( 0, nPos ) );
|
|
aEventTrigger = aEventTrigger.copy( nPos + 1 );
|
|
}
|
|
|
|
sal_Int16 nEnum;
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, aEventTrigger, aAnimations_EnumMap_EventTrigger ) )
|
|
{
|
|
aEvent.Trigger = nEnum;
|
|
}
|
|
else
|
|
{
|
|
OSL_FAIL("AnimationsImportHelperImpl::convertTiming(), unknown event trigger!");
|
|
}
|
|
|
|
aAny <<= aEvent;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// fill the sequence
|
|
Sequence< Any > aValues( nElements );
|
|
Any* pValues = aValues.getArray();
|
|
for (sal_Int32 nIndex = 0; nIndex >= 0; )
|
|
*pValues++ = convertTiming( rValue.getToken( 0, ';', nIndex ) );
|
|
|
|
aAny <<= aValues;
|
|
}
|
|
}
|
|
return aAny;
|
|
}
|
|
|
|
Sequence< double > AnimationsImportHelperImpl::convertKeyTimes( const OUString& rValue )
|
|
{
|
|
const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
|
|
|
|
Sequence< double > aKeyTimes( nElements );
|
|
|
|
if( nElements )
|
|
{
|
|
double* pValues = aKeyTimes.getArray();
|
|
for (sal_Int32 nIndex = 0; nIndex >= 0; )
|
|
*pValues++ = rValue.getToken( 0, ';', nIndex ).toDouble();
|
|
}
|
|
|
|
return aKeyTimes;
|
|
}
|
|
|
|
Sequence< TimeFilterPair > AnimationsImportHelperImpl::convertTimeFilter( const OUString& rValue )
|
|
{
|
|
const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
|
|
|
|
Sequence< TimeFilterPair > aTimeFilter( nElements );
|
|
|
|
if( nElements )
|
|
{
|
|
TimeFilterPair* pValues = aTimeFilter.getArray();
|
|
for (sal_Int32 nIndex = 0; nIndex >= 0; )
|
|
{
|
|
const OUString aToken( rValue.getToken( 0, ';', nIndex ) );
|
|
|
|
sal_Int32 nPos = aToken.indexOf( ',' );
|
|
if( nPos >= 0 )
|
|
{
|
|
pValues->Time = aToken.copy( 0, nPos ).toDouble();
|
|
pValues->Progress = aToken.copy( nPos+1 ).toDouble();
|
|
}
|
|
pValues++;
|
|
}
|
|
}
|
|
|
|
return aTimeFilter;
|
|
}
|
|
|
|
Any AnimationsImportHelperImpl::convertPath( const OUString& rValue )
|
|
{
|
|
return makeAny( rValue );
|
|
}
|
|
|
|
|
|
AnimationNodeContext::AnimationNodeContext(
|
|
const Reference< XAnimationNode >& xParentNode,
|
|
SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLocalName,
|
|
const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
|
|
const std::shared_ptr<AnimationsImportHelperImpl>& pHelper )
|
|
: SvXMLImportContext(rImport, nPrfx, rLocalName),
|
|
mpHelper( pHelper )
|
|
{
|
|
bool bRootContext = !pHelper;
|
|
try
|
|
{
|
|
if( bRootContext )
|
|
{
|
|
mpHelper = std::make_shared<AnimationsImportHelperImpl>( rImport );
|
|
mxNode = xParentNode;
|
|
}
|
|
else
|
|
{
|
|
sal_Int16 nPresetClass = EffectPresetClass::CUSTOM;
|
|
|
|
const sal_Char* pServiceName = nullptr;
|
|
|
|
sal_Int16 nNodeType = static_cast<sal_Int16>(mpHelper->getAnimationNodeTokenMap().Get( nPrfx, rLocalName ));
|
|
switch( nNodeType )
|
|
{
|
|
case AnimationNodeType::SEQ: pServiceName = "com.sun.star.animations.SequenceTimeContainer"; break;
|
|
case AnimationNodeType::ITERATE: pServiceName = "com.sun.star.animations.IterateContainer"; break;
|
|
case AnimationNodeType::ANIMATE: pServiceName = "com.sun.star.animations.Animate"; break;
|
|
case AnimationNodeType::SET: pServiceName = "com.sun.star.animations.AnimateSet"; break;
|
|
case AnimationNodeType::ANIMATEMOTION: pServiceName = "com.sun.star.animations.AnimateMotion"; break;
|
|
case AnimationNodeType::ANIMATECOLOR: pServiceName = "com.sun.star.animations.AnimateColor"; break;
|
|
case AnimationNodeType::ANIMATETRANSFORM: pServiceName = "com.sun.star.animations.AnimateTransform"; break;
|
|
case AnimationNodeType::TRANSITIONFILTER: pServiceName = "com.sun.star.animations.TransitionFilter"; break;
|
|
case AnimationNodeType::AUDIO: pServiceName = "com.sun.star.animations.Audio"; break;
|
|
case AnimationNodeType::COMMAND: pServiceName = "com.sun.star.animations.Command"; break;
|
|
case AnimationNodeType::PAR:
|
|
{
|
|
const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0;
|
|
sal_Int16 nAttribute;
|
|
for( nAttribute = 0; nAttribute < nCount; nAttribute++ )
|
|
{
|
|
OUString aLocalName;
|
|
sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttribute ), &aLocalName );
|
|
if( (nPrefix == XML_NAMESPACE_PRESENTATION) && IsXMLToken( aLocalName, XML_PRESET_ID ) )
|
|
{
|
|
const OUString& rValue = xAttrList->getValueByIndex( nAttribute );
|
|
if ( rValue == "ooo-entrance-random" )
|
|
{
|
|
nPresetClass = EffectPresetClass::ENTRANCE;
|
|
}
|
|
else if ( rValue == "ooo-exit-random" )
|
|
{
|
|
nPresetClass = EffectPresetClass::EXIT;
|
|
}
|
|
|
|
if( nPresetClass != EffectPresetClass::CUSTOM )
|
|
{
|
|
pServiceName = "com.sun.star.comp.sd.RandomAnimationNode";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if( !pServiceName )
|
|
pServiceName = "com.sun.star.animations.ParallelTimeContainer";
|
|
}
|
|
break;
|
|
default:
|
|
pServiceName = nullptr;
|
|
}
|
|
|
|
if( pServiceName )
|
|
{
|
|
Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
|
|
|
|
mxNode.set(
|
|
xContext->getServiceManager()->createInstanceWithContext(OUString::createFromAscii(pServiceName), xContext),
|
|
UNO_QUERY_THROW );
|
|
|
|
if( nPresetClass != EffectPresetClass::CUSTOM )
|
|
{
|
|
Reference< XInitialization > xInit( mxNode, UNO_QUERY_THROW );
|
|
const Any aAny( makeAny( nPresetClass ) );
|
|
Sequence< Any > aArgs( &aAny, 1 ) ;
|
|
xInit->initialize( aArgs );
|
|
}
|
|
|
|
init_node( xAttrList );
|
|
|
|
Reference< XTimeContainer > xParentContainer( xParentNode, UNO_QUERY_THROW );
|
|
xParentContainer->appendChild( mxNode );
|
|
}
|
|
}
|
|
}
|
|
catch (const RuntimeException&)
|
|
{
|
|
OSL_FAIL( "xmloff::AnimationsImportImpl::AnimationsImportImpl(), RuntimeException caught!" );
|
|
}
|
|
}
|
|
|
|
void AnimationNodeContext::StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& )
|
|
{
|
|
// code of StartElement is moved to init_node that is now called
|
|
// in c'tor before appending this node to its parent.
|
|
// This is needed for random nodes that need the correct target
|
|
// set when child nodes are appended.
|
|
}
|
|
|
|
void AnimationNodeContext::init_node( const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList )
|
|
{
|
|
if( mxNode.is() ) try
|
|
{
|
|
const sal_Int16 nNodeType = mxNode->getType();
|
|
|
|
// query for optional interfaces that are often used later
|
|
Reference< XAnimate > xAnimate( mxNode, UNO_QUERY );
|
|
Reference< XCommand > xCommand( mxNode, UNO_QUERY );
|
|
Reference< XTransitionFilter > xTransitionFilter( mxNode, UNO_QUERY );
|
|
Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
|
|
|
|
std::vector< NamedValue > aUserData;
|
|
XMLTokenEnum meAttributeName = XML_TOKEN_INVALID;
|
|
OUString aFrom, aBy, aTo, aValues;
|
|
bool bHaveXmlId( false );
|
|
OUString sXmlId;
|
|
|
|
const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0;
|
|
sal_Int16 nEnum;
|
|
sal_Int16 nAttribute;
|
|
for( nAttribute = 0; nAttribute < nCount; nAttribute++ )
|
|
{
|
|
const OUString& rAttrName = xAttrList->getNameByIndex( nAttribute );
|
|
const OUString& rValue = xAttrList->getValueByIndex( nAttribute );
|
|
|
|
OUString aLocalName;
|
|
sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
|
|
switch( mpHelper->getAnimationNodeAttributeTokenMap().Get( nPrefix, aLocalName ) )
|
|
{
|
|
case ANA_Begin:
|
|
{
|
|
mxNode->setBegin( mpHelper->convertTiming( rValue ) );
|
|
}
|
|
break;
|
|
case ANA_Dur:
|
|
{
|
|
mxNode->setDuration( mpHelper->convertTiming( rValue ) );
|
|
}
|
|
break;
|
|
case ANA_End:
|
|
{
|
|
mxNode->setEnd( mpHelper->convertTiming( rValue ) );
|
|
}
|
|
break;
|
|
case ANA_Fill:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_Fill ) )
|
|
mxNode->setFill( nEnum );
|
|
}
|
|
break;
|
|
case ANA_FillDefault:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_FillDefault ) )
|
|
mxNode->setFillDefault( nEnum );
|
|
}
|
|
break;
|
|
case ANA_Restart:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_Restart ) )
|
|
mxNode->setRestart( nEnum );
|
|
}
|
|
break;
|
|
case ANA_RestartDefault:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_RestartDefault ) )
|
|
mxNode->setRestartDefault( nEnum );
|
|
}
|
|
break;
|
|
case ANA_Accelerate:
|
|
{
|
|
if( isDouble( rValue ) )
|
|
mxNode->setAcceleration( rValue.toDouble() );
|
|
}
|
|
break;
|
|
case ANA_Decelerate:
|
|
{
|
|
if( isDouble( rValue ) )
|
|
mxNode->setDecelerate( rValue.toDouble() );
|
|
}
|
|
break;
|
|
case ANA_AutoReverse:
|
|
{
|
|
bool bTemp;
|
|
if (::sax::Converter::convertBool( bTemp, rValue ))
|
|
mxNode->setAutoReverse( bTemp );
|
|
}
|
|
break;
|
|
case ANA_RepeatCount:
|
|
{
|
|
mxNode->setRepeatCount( mpHelper->convertTiming( rValue ) );
|
|
}
|
|
break;
|
|
case ANA_RepeatDur:
|
|
{
|
|
mxNode->setRepeatDuration( mpHelper->convertTiming( rValue ) );
|
|
}
|
|
break;
|
|
case ANA_EndSync:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_Endsync ) )
|
|
mxNode->setEndSync( makeAny( nEnum ) );
|
|
}
|
|
break;
|
|
case ANA_Node_Type:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_EffectNodeType ) )
|
|
aUserData.emplace_back( GetXMLToken( XML_NODE_TYPE ), makeAny( nEnum ) );
|
|
}
|
|
break;
|
|
case ANA_Preset_ID:
|
|
{
|
|
aUserData.emplace_back( GetXMLToken( XML_PRESET_ID ), makeAny( rValue ) );
|
|
}
|
|
break;
|
|
case ANA_Preset_Sub_Type:
|
|
{
|
|
aUserData.emplace_back( GetXMLToken( XML_PRESET_SUB_TYPE ), makeAny( rValue ) );
|
|
}
|
|
break;
|
|
case ANA_Preset_Class:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_EffectPresetClass ) )
|
|
aUserData.emplace_back( GetXMLToken( XML_PRESET_CLASS ), makeAny( nEnum ) );
|
|
}
|
|
break;
|
|
case ANA_After_Effect:
|
|
{
|
|
bool bTemp;
|
|
if (::sax::Converter::convertBool( bTemp, rValue ))
|
|
aUserData.emplace_back( GetXMLToken( XML_AFTER_EFFECT ), makeAny( bTemp ) );
|
|
}
|
|
break;
|
|
case ANA_XLink:
|
|
{
|
|
if( nNodeType == AnimationNodeType::AUDIO )
|
|
{
|
|
Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
|
|
xAudio->setSource( makeAny(lcl_GetMediaReference(GetImport(), rValue)) );
|
|
break;
|
|
}
|
|
[[fallthrough]];
|
|
}
|
|
case ANA_Target:
|
|
{
|
|
Any aTarget( mpHelper->convertTarget( rValue ) );
|
|
|
|
if( xAnimate.is() )
|
|
{
|
|
xAnimate->setTarget( aTarget );
|
|
}
|
|
else if( xIter.is() )
|
|
{
|
|
xIter->setTarget( aTarget );
|
|
}
|
|
else if( xCommand.is() )
|
|
{
|
|
xCommand->setTarget( aTarget );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_Volume:
|
|
{
|
|
if( nNodeType == AnimationNodeType::AUDIO )
|
|
{
|
|
if( isDouble( rValue ) )
|
|
{
|
|
Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
|
|
xAudio->setVolume( rValue.toDouble() );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_MasterElement:
|
|
{
|
|
Reference< XAnimationNode > xMaster( GetImport().getInterfaceToIdentifierMapper().getReference( rValue ), UNO_QUERY );
|
|
aUserData.emplace_back( GetXMLToken( XML_MASTER_ELEMENT ), makeAny( xMaster ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_SubItem:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_SubItem ) )
|
|
{
|
|
if( xAnimate.is() )
|
|
{
|
|
xAnimate->setSubItem( nEnum );
|
|
}
|
|
else if( xIter.is() )
|
|
{
|
|
xIter->setSubItem( nEnum );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_AttributeName:
|
|
{
|
|
if( xAnimate.is() )
|
|
{
|
|
OUString aName( rValue );
|
|
|
|
const struct ImplAttributeNameConversion* p = getAnimationAttributeNamesConversionList();
|
|
while( p->mpAPIName )
|
|
{
|
|
if( IsXMLToken( aName, p->meXMLToken ) )
|
|
{
|
|
aName = OUString::createFromAscii( p->mpAPIName );
|
|
meAttributeName = p->meXMLToken;
|
|
break;
|
|
}
|
|
|
|
p++;
|
|
}
|
|
|
|
xAnimate->setAttributeName( aName );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_Values:
|
|
{
|
|
aValues = rValue;
|
|
}
|
|
break;
|
|
|
|
case ANA_From:
|
|
{
|
|
aFrom = rValue;
|
|
}
|
|
break;
|
|
|
|
case ANA_By:
|
|
{
|
|
aBy = rValue;
|
|
}
|
|
break;
|
|
|
|
case ANA_To:
|
|
{
|
|
aTo = rValue;
|
|
}
|
|
break;
|
|
|
|
case ANA_KeyTimes:
|
|
{
|
|
if( xAnimate.is() )
|
|
xAnimate->setKeyTimes( AnimationsImportHelperImpl::convertKeyTimes( rValue ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_Formula:
|
|
{
|
|
if( xAnimate.is() )
|
|
xAnimate->setFormula( rValue );
|
|
}
|
|
break;
|
|
|
|
case ANA_ANIMID:
|
|
{
|
|
if (!bHaveXmlId) { sXmlId = rValue; }
|
|
}
|
|
break;
|
|
case ANA_XMLID:
|
|
{
|
|
sXmlId = rValue;
|
|
bHaveXmlId = true;
|
|
}
|
|
break;
|
|
|
|
case ANA_CalcMode:
|
|
{
|
|
if( xAnimate.is() )
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_CalcMode ) )
|
|
xAnimate->setCalcMode( nEnum );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_Accumulate:
|
|
{
|
|
if( xAnimate.is() )
|
|
xAnimate->setAccumulate( IsXMLToken( rValue, XML_SUM ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_AdditiveMode:
|
|
{
|
|
if( xAnimate.is() )
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_AdditiveMode ) )
|
|
xAnimate->setAdditive( nEnum );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_KeySplines:
|
|
{
|
|
if( xAnimate.is() )
|
|
xAnimate->setTimeFilter( AnimationsImportHelperImpl::convertTimeFilter( rValue ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_Path:
|
|
{
|
|
Reference< XAnimateMotion > xAnimateMotion( mxNode, UNO_QUERY );
|
|
if( xAnimateMotion.is() )
|
|
xAnimateMotion->setPath( AnimationsImportHelperImpl::convertPath( rValue ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_ColorSpace:
|
|
{
|
|
Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY );
|
|
if( xAnimateColor.is() )
|
|
xAnimateColor->setColorInterpolation( IsXMLToken( rValue, XML_HSL ) ? AnimationColorSpace::HSL : AnimationColorSpace::RGB );
|
|
}
|
|
break;
|
|
|
|
case ANA_ColorDirection:
|
|
{
|
|
Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY );
|
|
if( xAnimateColor.is() )
|
|
xAnimateColor->setDirection( IsXMLToken( rValue, XML_CLOCKWISE ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_TransformType:
|
|
{
|
|
Reference< XAnimateTransform > xTransform( mxNode, UNO_QUERY );
|
|
if( xTransform.is() )
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_TransformType ) )
|
|
{
|
|
xTransform->setTransformType( nEnum );
|
|
switch( nEnum )
|
|
{
|
|
case AnimationTransformType::SCALE: meAttributeName = XML_SCALE; break;
|
|
case AnimationTransformType::ROTATE: meAttributeName = XML_ROTATE; break;
|
|
case AnimationTransformType::SKEWX: meAttributeName = XML_SKEWX; break;
|
|
case AnimationTransformType::SKEWY: meAttributeName = XML_SKEWY; break;
|
|
//case AnimationTransformType::TRANSLATE:
|
|
default:
|
|
meAttributeName = XML_TRANSLATE; break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_TransitionType:
|
|
{
|
|
if( xTransitionFilter.is() )
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_TransitionType ) )
|
|
xTransitionFilter->setTransition( nEnum );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_TransitionSubType:
|
|
{
|
|
if( xTransitionFilter.is() )
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_TransitionSubType ) )
|
|
xTransitionFilter->setSubtype( nEnum );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_Mode:
|
|
{
|
|
if( xTransitionFilter.is() )
|
|
xTransitionFilter->setMode( IsXMLToken( rValue, XML_IN ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_Direction:
|
|
{
|
|
if( xTransitionFilter.is() )
|
|
xTransitionFilter->setDirection( IsXMLToken( rValue, XML_FORWARD ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_FadeColor:
|
|
{
|
|
if( xTransitionFilter.is() )
|
|
{
|
|
sal_Int32 nColor(0);
|
|
::sax::Converter::convertColor(nColor, rValue);
|
|
xTransitionFilter->setFadeColor(nColor);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_IterateType:
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_IterateType ) )
|
|
{
|
|
if( xIter.is() )
|
|
xIter->setIterateType( nEnum );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_IterateInterval:
|
|
{
|
|
if( xIter.is() )
|
|
{
|
|
double fInterval = 0.0;
|
|
if( rValue.match("P") )
|
|
{
|
|
css::util::Duration aDuration;
|
|
if (::sax::Converter::convertDuration(aDuration, rValue))
|
|
{
|
|
fInterval = ((((aDuration.Hours * 60)
|
|
+ aDuration.Minutes) * 60) + aDuration.Seconds)
|
|
+ (aDuration.NanoSeconds / 1000000000.0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fInterval = rValue.toDouble();
|
|
}
|
|
|
|
xIter->setIterateInterval( fInterval );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ANA_Group_Id:
|
|
{
|
|
aUserData.emplace_back( aLocalName, makeAny( rValue.toInt32() ) );
|
|
}
|
|
break;
|
|
|
|
case ANA_Command:
|
|
{
|
|
if( xCommand.is() && nNodeType == AnimationNodeType::COMMAND )
|
|
{
|
|
if( SvXMLUnitConverter::convertEnum( nEnum, rValue, aAnimations_EnumMap_Command ) )
|
|
{
|
|
xCommand->setCommand( nEnum );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// push all unknown attributes within the presentation namespace as user data
|
|
if( nPrefix == XML_NAMESPACE_PRESENTATION )
|
|
{
|
|
aUserData.emplace_back( aLocalName, makeAny( rValue ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!sXmlId.isEmpty())
|
|
{
|
|
Reference< XInterface > const xRef( mxNode, UNO_QUERY );
|
|
GetImport().getInterfaceToIdentifierMapper().registerReference(
|
|
sXmlId, xRef );
|
|
}
|
|
|
|
sal_Int32 nUserDataCount = aUserData.size();
|
|
if( nUserDataCount )
|
|
{
|
|
Sequence< NamedValue > aUnoUserData( nUserDataCount );
|
|
NamedValue* pData = aUnoUserData.getArray();
|
|
for (auto const& item : aUserData)
|
|
*pData++ = item;
|
|
|
|
mxNode->setUserData( aUnoUserData );
|
|
}
|
|
|
|
// convert values
|
|
if( xAnimate.is() )
|
|
{
|
|
if( !aFrom.isEmpty() )
|
|
xAnimate->setFrom( mpHelper->convertValue( meAttributeName, aFrom ) );
|
|
|
|
if( !aBy.isEmpty() )
|
|
xAnimate->setBy( mpHelper->convertValue( meAttributeName, aBy ) );
|
|
|
|
if( !aTo.isEmpty() )
|
|
xAnimate->setTo( mpHelper->convertValue( meAttributeName, aTo ) );
|
|
|
|
if( !aValues.isEmpty() )
|
|
xAnimate->setValues( mpHelper->convertValueSequence( meAttributeName, aValues ) );
|
|
}
|
|
}
|
|
catch (const RuntimeException&)
|
|
{
|
|
OSL_FAIL( "xmloff::AnimationNodeContext::StartElement(), RuntimeException caught!" );
|
|
}
|
|
}
|
|
|
|
SvXMLImportContextRef AnimationNodeContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName,
|
|
const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList )
|
|
{
|
|
if( mxNode.is())
|
|
return new AnimationNodeContext( mxNode, GetImport(), nPrefix, rLocalName, xAttrList, mpHelper );
|
|
else
|
|
return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
|
|
}
|
|
|
|
class AnimationsImport: public SvXMLImport, public XAnimationNodeSupplier
|
|
{
|
|
public:
|
|
explicit AnimationsImport( const Reference< XComponentContext > & rxContext );
|
|
|
|
SvXMLImportContext* CreateDocumentContext(sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList) override;
|
|
|
|
// XInterface
|
|
virtual Any SAL_CALL queryInterface( const Type& aType ) override;
|
|
virtual void SAL_CALL acquire() throw () override;
|
|
virtual void SAL_CALL release() throw () override;
|
|
|
|
// XAnimationNodeSupplier
|
|
Reference< XAnimationNode > SAL_CALL getAnimationNode() override;
|
|
|
|
private:
|
|
Reference< XAnimationNode > mxRootNode;
|
|
};
|
|
|
|
AnimationsImport::AnimationsImport( const Reference< XComponentContext > & rxContext )
|
|
: SvXMLImport( rxContext, AnimationsImport_getImplementationName(), SvXMLImportFlags::META )
|
|
//FIXME: the above "IMPORT_META" used to be a nonsensical "true", question
|
|
// remains whether this should be IMPORT_META (same numerical value as
|
|
// true) or default IMPORT_ALL
|
|
{
|
|
// add namespaces
|
|
GetNamespaceMap().Add(
|
|
GetXMLToken(XML_NP_PRESENTATION),
|
|
GetXMLToken(XML_N_PRESENTATION),
|
|
XML_NAMESPACE_PRESENTATION);
|
|
|
|
GetNamespaceMap().Add(
|
|
GetXMLToken(XML_NP_SMIL),
|
|
GetXMLToken(XML_N_SMIL),
|
|
XML_NAMESPACE_SMIL);
|
|
|
|
GetNamespaceMap().Add(
|
|
GetXMLToken(XML_NP_ANIMATION),
|
|
GetXMLToken(XML_N_ANIMATION),
|
|
XML_NAMESPACE_ANIMATION);
|
|
|
|
mxRootNode.set( SequenceTimeContainer::create(rxContext), UNO_QUERY_THROW );
|
|
}
|
|
|
|
// XInterface
|
|
Any SAL_CALL AnimationsImport::queryInterface( const Type& aType )
|
|
{
|
|
if ( aType == cppu::UnoType<XAnimationNodeSupplier>::get())
|
|
{
|
|
return makeAny( Reference<XAnimationNodeSupplier>( this ) );
|
|
}
|
|
else
|
|
{
|
|
return SvXMLImport::queryInterface( aType );
|
|
}
|
|
}
|
|
|
|
void SAL_CALL AnimationsImport::acquire() throw ()
|
|
{
|
|
SvXMLImport::acquire();
|
|
}
|
|
|
|
void SAL_CALL AnimationsImport::release() throw ()
|
|
{
|
|
SvXMLImport::release();
|
|
}
|
|
|
|
SvXMLImportContext *AnimationsImport::CreateDocumentContext(
|
|
sal_uInt16 const nPrefix, const OUString& rLocalName,
|
|
const Reference<XAttributeList>& xAttrList)
|
|
{
|
|
SvXMLImportContext* pContext = nullptr;
|
|
|
|
if( (XML_NAMESPACE_ANIMATION == nPrefix) && IsXMLToken( rLocalName, XML_SEQ ) )
|
|
{
|
|
pContext = new AnimationNodeContext( mxRootNode, *this, nPrefix, rLocalName, xAttrList );
|
|
}
|
|
else
|
|
{
|
|
pContext = SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList);
|
|
}
|
|
|
|
return pContext;
|
|
}
|
|
|
|
// XAnimationNodeSupplier
|
|
Reference< XAnimationNode > SAL_CALL AnimationsImport::getAnimationNode()
|
|
{
|
|
return mxRootNode;
|
|
}
|
|
|
|
void AnimationNodeContext::postProcessRootNode( const Reference< XAnimationNode >& xRootNode, Reference< XPropertySet > const & xPageProps )
|
|
{
|
|
if( xRootNode.is() && xPageProps.is() ) try
|
|
{
|
|
Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
if( xEnumeration->hasMoreElements() )
|
|
{
|
|
Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
if( xNode->getType() == AnimationNodeType::PAR )
|
|
{
|
|
Event aEvent;
|
|
if( (xNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::BEGIN_EVENT) )
|
|
{
|
|
// found transition node
|
|
Reference< XEnumerationAccess > xChildEnumerationAccess( xNode, UNO_QUERY_THROW );
|
|
Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
while( xChildEnumeration->hasMoreElements() )
|
|
{
|
|
Reference< XAnimationNode > xChildNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
switch( xChildNode->getType() )
|
|
{
|
|
case AnimationNodeType::TRANSITIONFILTER:
|
|
{
|
|
Reference< XTransitionFilter > xTransFilter( xChildNode, UNO_QUERY_THROW );
|
|
|
|
xPageProps->setPropertyValue("TransitionType", Any( xTransFilter->getTransition() ) );
|
|
xPageProps->setPropertyValue("TransitionSubtype", Any( xTransFilter->getSubtype() ) );
|
|
xPageProps->setPropertyValue("TransitionDirection", Any( xTransFilter->getDirection() ) );
|
|
xPageProps->setPropertyValue("TransitionFadeColor", Any( xTransFilter->getFadeColor() ) );
|
|
|
|
double fDuration;
|
|
if( xTransFilter->getDuration() >>= fDuration )
|
|
xPageProps->setPropertyValue("TransitionDuration", Any( fDuration ) );
|
|
|
|
}
|
|
break;
|
|
|
|
case AnimationNodeType::COMMAND:
|
|
{
|
|
Reference< XCommand > xCommand( xChildNode, UNO_QUERY_THROW );
|
|
if( xCommand->getCommand() == EffectCommands::STOPAUDIO )
|
|
{
|
|
xPageProps->setPropertyValue("Sound", Any(true) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case AnimationNodeType::AUDIO:
|
|
{
|
|
Reference< XAudio > xAudio( xChildNode, UNO_QUERY_THROW );
|
|
OUString sSoundURL;
|
|
if( (xAudio->getSource() >>= sSoundURL) && !sSoundURL.isEmpty() )
|
|
{
|
|
xPageProps->setPropertyValue("Sound", Any(sSoundURL) );
|
|
|
|
Timing eTiming;
|
|
if( (xAudio->getRepeatCount() >>= eTiming) && (eTiming == Timing_INDEFINITE) )
|
|
xPageProps->setPropertyValue("LoopSound", Any( true ) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
Reference< XTimeContainer > xRootContainer( xRootNode, UNO_QUERY_THROW );
|
|
xRootContainer->removeChild( xNode );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (const Exception&)
|
|
{
|
|
OSL_FAIL("xmloff::AnimationsImport::postProcessRootNode(), exception caught!");
|
|
}
|
|
}
|
|
|
|
} // namespace xmloff
|
|
|
|
Reference< XInterface > AnimationsImport_createInstance(const Reference< XMultiServiceFactory > & rSMgr)
|
|
{
|
|
return static_cast<cppu::OWeakObject*>(new xmloff::AnimationsImport( comphelper::getComponentContext(rSMgr) ));
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|