2010-10-12 15:51:52 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-11-27 16:10:40 +00:00
|
|
|
/*
|
|
|
|
* 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 .
|
|
|
|
*/
|
2006-09-16 17:12:31 +00:00
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
#include <tools/debug.hxx>
|
2018-07-28 16:47:47 +02:00
|
|
|
#include <sal/log.hxx>
|
2013-04-25 14:18:47 +02:00
|
|
|
#include <com/sun/star/animations/AnimationNodeType.hpp>
|
2013-04-25 13:23:37 +02:00
|
|
|
#include <com/sun/star/animations/AnimateColor.hpp>
|
2013-04-25 14:18:47 +02:00
|
|
|
#include <com/sun/star/animations/AnimateMotion.hpp>
|
2013-04-25 13:23:37 +02:00
|
|
|
#include <com/sun/star/animations/AnimateSet.hpp>
|
2004-11-26 18:45:55 +00:00
|
|
|
#include <com/sun/star/animations/AnimationFill.hpp>
|
2013-04-25 13:30:44 +02:00
|
|
|
#include <com/sun/star/animations/Audio.hpp>
|
2013-04-25 14:12:19 +02:00
|
|
|
#include <com/sun/star/animations/Command.hpp>
|
2013-04-25 14:18:47 +02:00
|
|
|
#include <com/sun/star/animations/Event.hpp>
|
|
|
|
#include <com/sun/star/animations/EventTrigger.hpp>
|
2013-04-25 13:30:44 +02:00
|
|
|
#include <com/sun/star/animations/IterateContainer.hpp>
|
2013-04-23 16:04:30 +02:00
|
|
|
#include <com/sun/star/animations/ParallelTimeContainer.hpp>
|
2013-02-04 10:20:53 +02:00
|
|
|
#include <com/sun/star/animations/SequenceTimeContainer.hpp>
|
2013-04-25 14:18:47 +02:00
|
|
|
#include <com/sun/star/animations/Timing.hpp>
|
|
|
|
#include <com/sun/star/animations/XCommand.hpp>
|
|
|
|
#include <com/sun/star/animations/XIterateContainer.hpp>
|
|
|
|
#include <com/sun/star/animations/XAnimateTransform.hpp>
|
|
|
|
#include <com/sun/star/animations/XAnimateMotion.hpp>
|
|
|
|
#include <com/sun/star/animations/XAnimate.hpp>
|
|
|
|
#include <com/sun/star/beans/NamedValue.hpp>
|
|
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
2004-11-26 18:45:55 +00:00
|
|
|
#include <com/sun/star/container/XEnumerationAccess.hpp>
|
2013-04-25 14:18:47 +02:00
|
|
|
#include <com/sun/star/lang/XInitialization.hpp>
|
2004-11-26 18:45:55 +00:00
|
|
|
#include <com/sun/star/presentation/EffectNodeType.hpp>
|
|
|
|
#include <com/sun/star/presentation/EffectCommands.hpp>
|
|
|
|
#include <com/sun/star/presentation/EffectPresetClass.hpp>
|
|
|
|
#include <com/sun/star/presentation/ParagraphTarget.hpp>
|
|
|
|
#include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
|
|
|
|
#include <com/sun/star/text/XText.hpp>
|
2013-04-25 14:18:47 +02:00
|
|
|
#include <com/sun/star/util/XCloneable.hpp>
|
2005-03-01 16:29:57 +00:00
|
|
|
#include <com/sun/star/util/XChangesNotifier.hpp>
|
2004-11-26 18:45:55 +00:00
|
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
#include <comphelper/sequence.hxx>
|
2005-01-25 14:13:53 +00:00
|
|
|
#include <com/sun/star/lang/Locale.hpp>
|
2012-10-15 15:20:48 +02:00
|
|
|
#include <com/sun/star/i18n/BreakIterator.hpp>
|
2005-01-25 14:13:53 +00:00
|
|
|
#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
|
|
|
|
#include <com/sun/star/i18n/WordType.hpp>
|
|
|
|
#include <com/sun/star/presentation/TextAnimationType.hpp>
|
|
|
|
|
2007-07-06 12:10:13 +00:00
|
|
|
#include <basegfx/polygon/b2dpolypolygon.hxx>
|
|
|
|
#include <basegfx/polygon/b2dpolypolygontools.hxx>
|
|
|
|
#include <basegfx/matrix/b2dhommatrix.hxx>
|
|
|
|
#include <basegfx/range/b2drange.hxx>
|
2009-09-22 18:14:05 +02:00
|
|
|
#include <basegfx/matrix/b2dhommatrixtools.hxx>
|
2007-07-06 12:10:13 +00:00
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
#include <algorithm>
|
2016-09-01 09:28:58 +02:00
|
|
|
#include <deque>
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2015-08-30 21:24:35 +09:00
|
|
|
#include <cppuhelper/implbase.hxx>
|
2005-03-01 16:29:57 +00:00
|
|
|
|
2011-12-06 03:43:48 +01:00
|
|
|
#include <drawinglayer/geometry/viewinformation2d.hxx>
|
|
|
|
#include <svx/sdr/contact/viewcontact.hxx>
|
2007-07-06 12:10:13 +00:00
|
|
|
#include <svx/svdopath.hxx>
|
|
|
|
#include <svx/svdpage.hxx>
|
|
|
|
#include <svx/unoapi.hxx>
|
2017-10-23 22:32:55 +02:00
|
|
|
#include <CustomAnimationEffect.hxx>
|
2004-11-26 18:45:55 +00:00
|
|
|
#include <CustomAnimationPreset.hxx>
|
2017-10-23 22:32:55 +02:00
|
|
|
#include <animations.hxx>
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
using namespace ::com::sun::star;
|
2013-04-25 13:23:37 +02:00
|
|
|
using namespace ::com::sun::star::uno;
|
2004-11-26 18:45:55 +00:00
|
|
|
using namespace ::com::sun::star::presentation;
|
|
|
|
using namespace ::com::sun::star::animations;
|
|
|
|
|
|
|
|
using ::com::sun::star::container::XEnumerationAccess;
|
|
|
|
using ::com::sun::star::container::XEnumeration;
|
|
|
|
using ::com::sun::star::beans::NamedValue;
|
|
|
|
using ::com::sun::star::container::XChild;
|
|
|
|
using ::com::sun::star::drawing::XShape;
|
|
|
|
using ::com::sun::star::lang::XInitialization;
|
|
|
|
using ::com::sun::star::text::XText;
|
2005-01-25 14:13:53 +00:00
|
|
|
using ::com::sun::star::text::XTextRange;
|
2004-11-26 18:45:55 +00:00
|
|
|
using ::com::sun::star::beans::XPropertySet;
|
|
|
|
using ::com::sun::star::util::XCloneable;
|
2005-01-25 14:13:53 +00:00
|
|
|
using ::com::sun::star::lang::Locale;
|
2005-03-01 16:29:57 +00:00
|
|
|
using ::com::sun::star::util::XChangesNotifier;
|
|
|
|
using ::com::sun::star::util::XChangesListener;
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
namespace sd
|
|
|
|
{
|
2007-07-06 12:10:13 +00:00
|
|
|
class MainSequenceChangeGuard
|
|
|
|
{
|
|
|
|
public:
|
2015-10-25 17:33:13 +02:00
|
|
|
explicit MainSequenceChangeGuard( EffectSequenceHelper* pSequence )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
mpMainSequence = dynamic_cast< MainSequence* >( pSequence );
|
2015-11-10 10:23:02 +01:00
|
|
|
if( mpMainSequence == nullptr )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
InteractiveSequence* pI = dynamic_cast< InteractiveSequence* >( pSequence );
|
|
|
|
if( pI )
|
|
|
|
mpMainSequence = pI->mpMainSequence;
|
|
|
|
}
|
|
|
|
DBG_ASSERT( mpMainSequence, "sd::MainSequenceChangeGuard::MainSequenceChangeGuard(), no main sequence to guard!" );
|
|
|
|
|
|
|
|
if( mpMainSequence )
|
|
|
|
mpMainSequence->mbIgnoreChanges++;
|
|
|
|
}
|
|
|
|
|
|
|
|
~MainSequenceChangeGuard()
|
|
|
|
{
|
|
|
|
if( mpMainSequence )
|
|
|
|
mpMainSequence->mbIgnoreChanges++;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
MainSequence* mpMainSequence;
|
|
|
|
};
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
CustomAnimationEffect::CustomAnimationEffect( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
|
2004-11-26 18:45:55 +00:00
|
|
|
: mnNodeType(-1),
|
|
|
|
mnPresetClass(-1),
|
|
|
|
mfBegin(-1.0),
|
|
|
|
mfDuration(-1.0),
|
2005-01-25 14:13:53 +00:00
|
|
|
mfAbsoluteDuration(-1.0),
|
2006-12-12 15:29:01 +00:00
|
|
|
mnGroupId(-1),
|
2004-11-26 18:45:55 +00:00
|
|
|
mnIterateType(0),
|
2006-12-12 15:29:01 +00:00
|
|
|
mfIterateInterval(0.0),
|
2004-11-26 18:45:55 +00:00
|
|
|
mnParaDepth( -1 ),
|
2014-04-24 10:52:02 +02:00
|
|
|
mbHasText(false),
|
2006-12-12 15:29:01 +00:00
|
|
|
mfAcceleration( 1.0 ),
|
|
|
|
mfDecelerate( 1.0 ),
|
|
|
|
mbAutoReverse(false),
|
2004-11-26 18:45:55 +00:00
|
|
|
mnTargetSubItem(0),
|
2006-12-12 15:29:01 +00:00
|
|
|
mnCommand(0),
|
2015-11-10 10:23:02 +01:00
|
|
|
mpEffectSequence( nullptr ),
|
2006-12-12 15:29:01 +00:00
|
|
|
mbHasAfterEffect(false),
|
|
|
|
mbAfterEffectOnNextEffect(false)
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
setNode( xNode );
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void CustomAnimationEffect::setNode( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
mxNode = xNode;
|
|
|
|
mxAudio.clear();
|
|
|
|
|
|
|
|
Sequence< NamedValue > aUserData( mxNode->getUserData() );
|
|
|
|
sal_Int32 nLength = aUserData.getLength();
|
|
|
|
const NamedValue* p = aUserData.getConstArray();
|
|
|
|
|
|
|
|
while( nLength-- )
|
|
|
|
{
|
2012-04-06 14:28:18 +02:00
|
|
|
if ( p->Name == "node-type" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value >>= mnNodeType;
|
|
|
|
}
|
2012-04-06 14:28:18 +02:00
|
|
|
else if ( p->Name == "preset-id" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value >>= maPresetId;
|
|
|
|
}
|
2012-04-06 14:28:18 +02:00
|
|
|
else if ( p->Name == "preset-sub-type" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value >>= maPresetSubType;
|
|
|
|
}
|
2012-04-06 14:28:18 +02:00
|
|
|
else if ( p->Name == "preset-class" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value >>= mnPresetClass;
|
|
|
|
}
|
2012-04-06 14:28:18 +02:00
|
|
|
else if ( p->Name == "preset-property" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value >>= maProperty;
|
|
|
|
}
|
2012-04-06 14:28:18 +02:00
|
|
|
else if ( p->Name == "group-id" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value >>= mnGroupId;
|
|
|
|
}
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get effect start time
|
|
|
|
mxNode->getBegin() >>= mfBegin;
|
|
|
|
|
|
|
|
mfAcceleration = mxNode->getAcceleration();
|
|
|
|
mfDecelerate = mxNode->getDecelerate();
|
|
|
|
mbAutoReverse = mxNode->getAutoReverse();
|
|
|
|
|
|
|
|
// get iteration data
|
|
|
|
Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
|
|
|
|
if( xIter.is() )
|
|
|
|
{
|
|
|
|
mfIterateInterval = xIter->getIterateInterval();
|
|
|
|
mnIterateType = xIter->getIterateType();
|
|
|
|
maTarget = xIter->getTarget();
|
|
|
|
mnTargetSubItem = xIter->getSubItem();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mfIterateInterval = 0.0f;
|
|
|
|
mnIterateType = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate effect duration and get target shape
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( !xChildNode.is() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( xChildNode->getType() == AnimationNodeType::AUDIO )
|
|
|
|
{
|
|
|
|
mxAudio.set( xChildNode, UNO_QUERY );
|
|
|
|
}
|
|
|
|
else if( xChildNode->getType() == AnimationNodeType::COMMAND )
|
|
|
|
{
|
|
|
|
Reference< XCommand > xCommand( xChildNode, UNO_QUERY );
|
|
|
|
if( xCommand.is() )
|
|
|
|
{
|
|
|
|
mnCommand = xCommand->getCommand();
|
|
|
|
if( !maTarget.hasValue() )
|
|
|
|
maTarget = xCommand->getTarget();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double fBegin = 0.0;
|
|
|
|
double fDuration = 0.0;
|
|
|
|
xChildNode->getBegin() >>= fBegin;
|
|
|
|
xChildNode->getDuration() >>= fDuration;
|
|
|
|
|
|
|
|
fDuration += fBegin;
|
|
|
|
if( fDuration > mfDuration )
|
|
|
|
mfDuration = fDuration;
|
|
|
|
|
|
|
|
// no target shape yet?
|
|
|
|
if( !maTarget.hasValue() )
|
|
|
|
{
|
|
|
|
// go get it boys!
|
|
|
|
Reference< XAnimate > xAnimate( xChildNode, UNO_QUERY );
|
|
|
|
if( xAnimate.is() )
|
|
|
|
{
|
|
|
|
maTarget = xAnimate->getTarget();
|
|
|
|
mnTargetSubItem = xAnimate->getSubItem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-01-25 14:13:53 +00:00
|
|
|
|
|
|
|
mfAbsoluteDuration = mfDuration;
|
2012-07-05 16:35:02 +02:00
|
|
|
double fRepeatCount = 1.0;
|
|
|
|
if( (mxNode->getRepeatCount()) >>= fRepeatCount )
|
|
|
|
mfAbsoluteDuration *= fRepeatCount;
|
|
|
|
|
2005-01-25 14:13:53 +00:00
|
|
|
checkForText();
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 CustomAnimationEffect::getNumberOfSubitems( const Any& aTarget, sal_Int16 nIterateType )
|
|
|
|
{
|
|
|
|
sal_Int32 nSubItems = 0;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// first get target text
|
|
|
|
sal_Int32 nOnlyPara = -1;
|
|
|
|
|
|
|
|
Reference< XText > xShape;
|
|
|
|
aTarget >>= xShape;
|
|
|
|
if( !xShape.is() )
|
|
|
|
{
|
|
|
|
ParagraphTarget aParaTarget;
|
|
|
|
if( aTarget >>= aParaTarget )
|
|
|
|
{
|
2005-03-01 16:29:57 +00:00
|
|
|
xShape.set( aParaTarget.Shape, UNO_QUERY );
|
2005-01-25 14:13:53 +00:00
|
|
|
nOnlyPara = aParaTarget.Paragraph;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// now use the break iterator to iterate over the given text
|
|
|
|
// and count the sub items
|
|
|
|
|
|
|
|
if( xShape.is() )
|
|
|
|
{
|
|
|
|
// TODO/LATER: Optimize this, don't create a break iterator each time
|
2012-10-15 15:20:48 +02:00
|
|
|
Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
|
|
|
|
Reference < i18n::XBreakIterator > xBI = i18n::BreakIterator::create(xContext);
|
2005-01-25 14:13:53 +00:00
|
|
|
|
2012-10-15 15:20:48 +02:00
|
|
|
Reference< XEnumerationAccess > xEA( xShape, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEA->createEnumeration(), UNO_QUERY_THROW );
|
2015-11-10 19:20:12 -05:00
|
|
|
css::lang::Locale aLocale;
|
2012-10-15 15:20:48 +02:00
|
|
|
const OUString aStrLocaleName( "CharLocale" );
|
|
|
|
Reference< XTextRange > xParagraph;
|
|
|
|
|
|
|
|
sal_Int32 nPara = 0;
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
2005-01-25 14:13:53 +00:00
|
|
|
{
|
2012-10-15 15:20:48 +02:00
|
|
|
xEnumeration->nextElement() >>= xParagraph;
|
|
|
|
|
2016-10-01 15:45:53 +02:00
|
|
|
// skip this if it's not the only paragraph we want to count
|
2012-10-15 15:20:48 +02:00
|
|
|
if( (nOnlyPara != -1) && (nOnlyPara != nPara ) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( nIterateType == TextAnimationType::BY_PARAGRAPH )
|
2005-01-25 14:13:53 +00:00
|
|
|
{
|
2012-10-15 15:20:48 +02:00
|
|
|
nSubItems++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const OUString aText( xParagraph->getString() );
|
|
|
|
Reference< XPropertySet > xSet( xParagraph, UNO_QUERY_THROW );
|
|
|
|
xSet->getPropertyValue( aStrLocaleName ) >>= aLocale;
|
2005-01-25 14:13:53 +00:00
|
|
|
|
2012-10-15 15:20:48 +02:00
|
|
|
sal_Int32 nPos;
|
|
|
|
const sal_Int32 nEndPos = aText.getLength();
|
2005-01-25 14:13:53 +00:00
|
|
|
|
2012-10-15 15:20:48 +02:00
|
|
|
if( nIterateType == TextAnimationType::BY_WORD )
|
2005-01-25 14:13:53 +00:00
|
|
|
{
|
2012-10-15 15:20:48 +02:00
|
|
|
for( nPos = 0; nPos < nEndPos; nPos++ )
|
|
|
|
{
|
2016-04-20 17:19:18 +02:00
|
|
|
nPos = xBI->getWordBoundary(aText, nPos, aLocale, i18n::WordType::ANY_WORD, true).endPos;
|
2012-10-15 15:20:48 +02:00
|
|
|
nSubItems++;
|
|
|
|
}
|
|
|
|
break;
|
2005-01-25 14:13:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-10-15 15:20:48 +02:00
|
|
|
sal_Int32 nDone;
|
|
|
|
for( nPos = 0; nPos < nEndPos; nPos++ )
|
2005-01-25 14:13:53 +00:00
|
|
|
{
|
2012-10-15 15:20:48 +02:00
|
|
|
nPos = xBI->nextCharacters(aText, nPos, aLocale, i18n::CharacterIteratorMode::SKIPCELL, 0, nDone);
|
|
|
|
nSubItems++;
|
2005-01-25 14:13:53 +00:00
|
|
|
}
|
|
|
|
}
|
2012-10-15 15:20:48 +02:00
|
|
|
}
|
2005-01-25 14:13:53 +00:00
|
|
|
|
2012-10-15 15:20:48 +02:00
|
|
|
if( nPara == nOnlyPara )
|
|
|
|
break;
|
2005-01-25 14:13:53 +00:00
|
|
|
|
2012-10-15 15:20:48 +02:00
|
|
|
nPara++;
|
2005-01-25 14:13:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2005-01-25 14:13:53 +00:00
|
|
|
{
|
|
|
|
nSubItems = 0;
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::getNumberOfSubitems(), exception caught!" );
|
2005-01-25 14:13:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nSubItems;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CustomAnimationEffect::~CustomAnimationEffect()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
CustomAnimationEffectPtr CustomAnimationEffect::clone() const
|
|
|
|
{
|
|
|
|
Reference< XCloneable > xCloneable( mxNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XAnimationNode > xNode( xCloneable->createClone(), UNO_QUERY_THROW );
|
2005-12-14 14:51:29 +00:00
|
|
|
CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xNode ) );
|
|
|
|
pEffect->setEffectSequence( getEffectSequence() );
|
|
|
|
return pEffect;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 CustomAnimationEffect::get_node_type( const Reference< XAnimationNode >& xNode )
|
|
|
|
{
|
|
|
|
sal_Int16 nNodeType = -1;
|
|
|
|
|
|
|
|
if( xNode.is() )
|
|
|
|
{
|
|
|
|
Sequence< NamedValue > aUserData( xNode->getUserData() );
|
|
|
|
sal_Int32 nLength = aUserData.getLength();
|
|
|
|
if( nLength )
|
|
|
|
{
|
|
|
|
const NamedValue* p = aUserData.getConstArray();
|
|
|
|
while( nLength-- )
|
|
|
|
{
|
2012-04-06 14:28:18 +02:00
|
|
|
if ( p->Name == "node-type" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value >>= nNodeType;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nNodeType;
|
|
|
|
}
|
|
|
|
|
2007-07-06 12:10:13 +00:00
|
|
|
void CustomAnimationEffect::setPresetClass( sal_Int16 nPresetClass )
|
|
|
|
{
|
|
|
|
if( mnPresetClass != nPresetClass )
|
|
|
|
{
|
|
|
|
mnPresetClass = nPresetClass;
|
|
|
|
if( mxNode.is() )
|
|
|
|
{
|
|
|
|
// first try to find a "preset-class" entry in the user data
|
|
|
|
// and change it
|
|
|
|
Sequence< NamedValue > aUserData( mxNode->getUserData() );
|
|
|
|
sal_Int32 nLength = aUserData.getLength();
|
|
|
|
bool bFound = false;
|
|
|
|
if( nLength )
|
|
|
|
{
|
|
|
|
NamedValue* p = aUserData.getArray();
|
|
|
|
while( nLength-- )
|
|
|
|
{
|
2012-04-06 14:28:18 +02:00
|
|
|
if ( p->Name == "preset-class" )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
p->Value <<= mnPresetClass;
|
|
|
|
bFound = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// no "node-type" entry inside user data, so add it
|
|
|
|
if( !bFound )
|
|
|
|
{
|
|
|
|
nLength = aUserData.getLength();
|
|
|
|
aUserData.realloc( nLength + 1);
|
2012-04-15 23:14:28 -03:00
|
|
|
aUserData[nLength].Name = "preset-class";
|
2007-07-06 12:10:13 +00:00
|
|
|
aUserData[nLength].Value <<= mnPresetClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
mxNode->setUserData( aUserData );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
void CustomAnimationEffect::setNodeType( sal_Int16 nNodeType )
|
|
|
|
{
|
|
|
|
if( mnNodeType != nNodeType )
|
|
|
|
{
|
|
|
|
mnNodeType = nNodeType;
|
|
|
|
if( mxNode.is() )
|
|
|
|
{
|
|
|
|
// first try to find a "node-type" entry in the user data
|
|
|
|
// and change it
|
|
|
|
Sequence< NamedValue > aUserData( mxNode->getUserData() );
|
|
|
|
sal_Int32 nLength = aUserData.getLength();
|
|
|
|
bool bFound = false;
|
|
|
|
if( nLength )
|
|
|
|
{
|
|
|
|
NamedValue* p = aUserData.getArray();
|
|
|
|
while( nLength-- )
|
|
|
|
{
|
2012-04-06 14:28:18 +02:00
|
|
|
if ( p->Name == "node-type" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value <<= mnNodeType;
|
|
|
|
bFound = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// no "node-type" entry inside user data, so add it
|
|
|
|
if( !bFound )
|
|
|
|
{
|
|
|
|
nLength = aUserData.getLength();
|
|
|
|
aUserData.realloc( nLength + 1);
|
2012-04-15 23:14:28 -03:00
|
|
|
aUserData[nLength].Name = "node-type";
|
2004-11-26 18:45:55 +00:00
|
|
|
aUserData[nLength].Value <<= mnNodeType;
|
|
|
|
}
|
|
|
|
|
|
|
|
mxNode->setUserData( aUserData );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setGroupId( sal_Int32 nGroupId )
|
|
|
|
{
|
|
|
|
mnGroupId = nGroupId;
|
|
|
|
if( mxNode.is() )
|
|
|
|
{
|
|
|
|
// first try to find a "group-id" entry in the user data
|
|
|
|
// and change it
|
|
|
|
Sequence< NamedValue > aUserData( mxNode->getUserData() );
|
|
|
|
sal_Int32 nLength = aUserData.getLength();
|
|
|
|
bool bFound = false;
|
|
|
|
if( nLength )
|
|
|
|
{
|
|
|
|
NamedValue* p = aUserData.getArray();
|
|
|
|
while( nLength-- )
|
|
|
|
{
|
2012-04-06 14:28:18 +02:00
|
|
|
if ( p->Name == "group-id" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value <<= mnGroupId;
|
|
|
|
bFound = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// no "node-type" entry inside user data, so add it
|
|
|
|
if( !bFound )
|
|
|
|
{
|
|
|
|
nLength = aUserData.getLength();
|
|
|
|
aUserData.realloc( nLength + 1);
|
2012-04-15 23:14:28 -03:00
|
|
|
aUserData[nLength].Name = "group-id";
|
2004-11-26 18:45:55 +00:00
|
|
|
aUserData[nLength].Value <<= mnGroupId;
|
|
|
|
}
|
|
|
|
|
|
|
|
mxNode->setUserData( aUserData );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-25 14:13:53 +00:00
|
|
|
/** checks if the text for this effect has changed and updates internal flags.
|
|
|
|
returns true if something changed.
|
|
|
|
*/
|
|
|
|
bool CustomAnimationEffect::checkForText()
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-01-25 14:13:53 +00:00
|
|
|
bool bChange = false;
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
Reference< XText > xText;
|
|
|
|
|
2014-05-10 00:14:44 +02:00
|
|
|
if( maTarget.getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
// calc para depth
|
|
|
|
ParagraphTarget aParaTarget;
|
|
|
|
maTarget >>= aParaTarget;
|
|
|
|
|
2015-11-04 15:36:26 +02:00
|
|
|
xText.set( aParaTarget.Shape, UNO_QUERY );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
// get paragraph
|
|
|
|
if( xText.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEA( xText, UNO_QUERY );
|
|
|
|
if( xEA.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEA->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
2014-04-24 10:52:02 +02:00
|
|
|
bool bHasText = xEnumeration->hasMoreElements();
|
2005-01-25 14:13:53 +00:00
|
|
|
bChange |= bHasText != mbHasText;
|
|
|
|
mbHasText = bHasText;
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
sal_Int32 nPara = aParaTarget.Paragraph;
|
|
|
|
|
|
|
|
while( xEnumeration->hasMoreElements() && nPara-- )
|
|
|
|
xEnumeration->nextElement();
|
|
|
|
|
|
|
|
if( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XPropertySet > xParaSet;
|
|
|
|
xEnumeration->nextElement() >>= xParaSet;
|
|
|
|
if( xParaSet.is() )
|
|
|
|
{
|
2007-01-09 10:20:51 +00:00
|
|
|
sal_Int32 nParaDepth = 0;
|
2012-04-15 23:14:28 -03:00
|
|
|
const OUString strNumberingLevel( "NumberingLevel" );
|
2005-01-25 14:13:53 +00:00
|
|
|
xParaSet->getPropertyValue( strNumberingLevel ) >>= nParaDepth;
|
|
|
|
bChange |= nParaDepth != mnParaDepth;
|
|
|
|
mnParaDepth = nParaDepth;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
maTarget >>= xText;
|
2014-04-24 10:52:02 +02:00
|
|
|
bool bHasText = xText.is() && !xText->getString().isEmpty();
|
2005-01-25 14:13:53 +00:00
|
|
|
bChange |= bHasText != mbHasText;
|
|
|
|
mbHasText = bHasText;
|
|
|
|
}
|
|
|
|
|
|
|
|
bChange |= calculateIterateDuration();
|
|
|
|
return bChange;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CustomAnimationEffect::calculateIterateDuration()
|
|
|
|
{
|
|
|
|
bool bChange = false;
|
|
|
|
|
|
|
|
// if we have an iteration, we must also calculate the
|
|
|
|
// 'true' container duration, that is
|
|
|
|
// ( ( is form animated ) ? [contained effects duration] : 0 ) +
|
|
|
|
// ( [number of animated children] - 1 ) * [interval-delay] + [contained effects duration]
|
|
|
|
Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
|
|
|
|
if( xIter.is() )
|
|
|
|
{
|
|
|
|
double fDuration = mfDuration;
|
|
|
|
const double fSubEffectDuration = mfDuration;
|
|
|
|
|
|
|
|
if( mnTargetSubItem != ShapeAnimationSubType::ONLY_BACKGROUND ) // does not make sense for iterate container but better check
|
|
|
|
{
|
|
|
|
const sal_Int32 nSubItems = getNumberOfSubitems( maTarget, mnIterateType );
|
|
|
|
if( nSubItems )
|
|
|
|
{
|
|
|
|
const double f = (nSubItems-1) * mfIterateInterval;
|
|
|
|
fDuration += f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if we also animate the form first, we have to add the
|
|
|
|
// sub effect duration to the whole effect duration
|
|
|
|
if( mnTargetSubItem == ShapeAnimationSubType::AS_WHOLE )
|
|
|
|
fDuration += fSubEffectDuration;
|
|
|
|
|
|
|
|
bChange |= fDuration != mfAbsoluteDuration;
|
|
|
|
mfAbsoluteDuration = fDuration;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2005-01-25 14:13:53 +00:00
|
|
|
return bChange;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void CustomAnimationEffect::setTarget( const css::uno::Any& rTarget )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
maTarget = rTarget;
|
|
|
|
|
|
|
|
// first, check special case for random node
|
|
|
|
Reference< XInitialization > xInit( mxNode, UNO_QUERY );
|
|
|
|
if( xInit.is() )
|
|
|
|
{
|
|
|
|
const Sequence< Any > aArgs( &maTarget, 1 );
|
|
|
|
xInit->initialize( aArgs );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
|
|
|
|
if( xIter.is() )
|
|
|
|
{
|
|
|
|
xIter->setTarget(maTarget);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
2009-01-06 08:40:41 +00:00
|
|
|
const Any aElem( xEnumeration->nextElement() );
|
|
|
|
Reference< XAnimate > xAnimate( aElem, UNO_QUERY );
|
2004-11-26 18:45:55 +00:00
|
|
|
if( xAnimate.is() )
|
|
|
|
xAnimate->setTarget( rTarget );
|
2009-01-06 08:40:41 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Reference< XCommand > xCommand( aElem, UNO_QUERY );
|
|
|
|
if( xCommand.is() )
|
|
|
|
xCommand->setTarget( rTarget );
|
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
checkForText();
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::setTarget(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setTargetSubItem( sal_Int16 nSubItem )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
mnTargetSubItem = nSubItem;
|
|
|
|
|
|
|
|
Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
|
|
|
|
if( xIter.is() )
|
|
|
|
{
|
|
|
|
xIter->setSubItem(mnTargetSubItem);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( xAnimate.is() )
|
|
|
|
xAnimate->setSubItem( mnTargetSubItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::setTargetSubItem(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setDuration( double fDuration )
|
|
|
|
{
|
|
|
|
if( (mfDuration != -1.0) && (mfDuration != fDuration) ) try
|
|
|
|
{
|
|
|
|
double fScale = fDuration / mfDuration;
|
|
|
|
mfDuration = fDuration;
|
2012-07-05 16:35:02 +02:00
|
|
|
double fRepeatCount = 1.0;
|
|
|
|
getRepeatCount() >>= fRepeatCount;
|
|
|
|
mfAbsoluteDuration = mfDuration * fRepeatCount;
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
// calculate effect duration and get target shape
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( !xChildNode.is() )
|
|
|
|
continue;
|
|
|
|
|
2006-12-12 15:29:01 +00:00
|
|
|
double fChildBegin = 0.0;
|
|
|
|
xChildNode->getBegin() >>= fChildBegin;
|
|
|
|
if( fChildBegin != 0.0 )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2006-12-12 15:29:01 +00:00
|
|
|
fChildBegin *= fScale;
|
|
|
|
xChildNode->setBegin( makeAny( fChildBegin ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2006-12-12 15:29:01 +00:00
|
|
|
double fChildDuration = 0.0;
|
|
|
|
xChildNode->getDuration() >>= fChildDuration;
|
|
|
|
if( fChildDuration != 0.0 )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2006-12-12 15:29:01 +00:00
|
|
|
fChildDuration *= fScale;
|
|
|
|
xChildNode->setDuration( makeAny( fChildDuration ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-01-25 14:13:53 +00:00
|
|
|
calculateIterateDuration();
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::setDuration(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setBegin( double fBegin )
|
|
|
|
{
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
mfBegin = fBegin;
|
|
|
|
mxNode->setBegin( makeAny( fBegin ) );
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::setBegin(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setAcceleration( double fAcceleration )
|
|
|
|
{
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
mfAcceleration = fAcceleration;
|
|
|
|
mxNode->setAcceleration( fAcceleration );
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::setAcceleration(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
void CustomAnimationEffect::setDecelerate( double fDecelerate )
|
|
|
|
{
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
mfDecelerate = fDecelerate;
|
|
|
|
mxNode->setDecelerate( fDecelerate );
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::setDecelerate(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-24 10:52:02 +02:00
|
|
|
void CustomAnimationEffect::setAutoReverse( bool bAutoReverse )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
mbAutoReverse = bAutoReverse;
|
|
|
|
mxNode->setAutoReverse( bAutoReverse );
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::setAutoReverse(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void CustomAnimationEffect::replaceNode( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
sal_Int16 nNodeType = mnNodeType;
|
|
|
|
Any aTarget = maTarget;
|
|
|
|
|
|
|
|
double fBegin = mfBegin;
|
|
|
|
double fDuration = mfDuration;
|
|
|
|
double fAcceleration = mfAcceleration;
|
|
|
|
double fDecelerate = mfDecelerate ;
|
2014-04-24 10:52:02 +02:00
|
|
|
bool bAutoReverse = mbAutoReverse;
|
2004-11-26 18:45:55 +00:00
|
|
|
Reference< XAudio > xAudio( mxAudio );
|
|
|
|
sal_Int16 nIterateType = mnIterateType;
|
|
|
|
double fIterateInterval = mfIterateInterval;
|
2005-03-01 16:29:57 +00:00
|
|
|
sal_Int16 nSubItem = mnTargetSubItem;
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
setNode( xNode );
|
|
|
|
|
2005-02-24 14:04:33 +00:00
|
|
|
setAudio( xAudio );
|
2004-11-26 18:45:55 +00:00
|
|
|
setNodeType( nNodeType );
|
|
|
|
setTarget( aTarget );
|
2005-03-01 16:29:57 +00:00
|
|
|
setTargetSubItem( nSubItem );
|
2004-11-26 18:45:55 +00:00
|
|
|
setDuration( fDuration );
|
|
|
|
setBegin( fBegin );
|
|
|
|
|
|
|
|
setAcceleration( fAcceleration );
|
|
|
|
setDecelerate( fDecelerate );
|
|
|
|
setAutoReverse( bAutoReverse );
|
|
|
|
|
|
|
|
if( nIterateType != mnIterateType )
|
|
|
|
setIterateType( nIterateType );
|
|
|
|
|
|
|
|
if( mnIterateType && ( fIterateInterval != mfIterateInterval ) )
|
|
|
|
setIterateInterval( fIterateInterval );
|
|
|
|
}
|
|
|
|
|
|
|
|
Reference< XShape > CustomAnimationEffect::getTargetShape() const
|
|
|
|
{
|
|
|
|
Reference< XShape > xShape;
|
|
|
|
maTarget >>= xShape;
|
|
|
|
if( !xShape.is() )
|
|
|
|
{
|
|
|
|
ParagraphTarget aParaTarget;
|
|
|
|
if( maTarget >>= aParaTarget )
|
|
|
|
xShape = aParaTarget.Shape;
|
|
|
|
}
|
|
|
|
|
|
|
|
return xShape;
|
|
|
|
}
|
|
|
|
|
|
|
|
Any CustomAnimationEffect::getRepeatCount() const
|
|
|
|
{
|
|
|
|
if( mxNode.is() )
|
|
|
|
{
|
|
|
|
return mxNode->getRepeatCount();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Any aAny;
|
|
|
|
return aAny;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Any CustomAnimationEffect::getEnd() const
|
|
|
|
{
|
|
|
|
if( mxNode.is() )
|
|
|
|
{
|
|
|
|
return mxNode->getEnd();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Any aAny;
|
|
|
|
return aAny;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int16 CustomAnimationEffect::getFill() const
|
|
|
|
{
|
|
|
|
if( mxNode.is() )
|
|
|
|
return mxNode->getFill();
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setRepeatCount( const Any& rRepeatCount )
|
|
|
|
{
|
|
|
|
if( mxNode.is() )
|
2012-07-05 16:35:02 +02:00
|
|
|
{
|
2004-11-26 18:45:55 +00:00
|
|
|
mxNode->setRepeatCount( rRepeatCount );
|
2012-07-05 16:35:02 +02:00
|
|
|
double fRepeatCount = 1.0;
|
|
|
|
rRepeatCount >>= fRepeatCount;
|
|
|
|
mfAbsoluteDuration = mfDuration * fRepeatCount;
|
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setEnd( const Any& rEnd )
|
|
|
|
{
|
|
|
|
if( mxNode.is() )
|
|
|
|
mxNode->setEnd( rEnd );
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setFill( sal_Int16 nFill )
|
|
|
|
{
|
|
|
|
if( mxNode.is() )
|
|
|
|
mxNode->setFill( nFill );
|
|
|
|
}
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
Reference< XAnimationNode > CustomAnimationEffect::createAfterEffectNode() const
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT( mbHasAfterEffect, "sd::CustomAnimationEffect::createAfterEffectNode(), this node has no after effect!" );
|
|
|
|
|
2013-04-25 13:23:37 +02:00
|
|
|
Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2013-04-25 13:23:37 +02:00
|
|
|
Reference< XAnimate > xAnimate;
|
|
|
|
if( maDimColor.hasValue() )
|
|
|
|
xAnimate = AnimateColor::create( xContext );
|
|
|
|
else
|
|
|
|
xAnimate = AnimateSet::create( xContext );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
Any aTo;
|
|
|
|
OUString aAttributeName;
|
|
|
|
|
|
|
|
if( maDimColor.hasValue() )
|
|
|
|
{
|
|
|
|
aTo = maDimColor;
|
2012-04-15 23:14:28 -03:00
|
|
|
aAttributeName = "DimColor";
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-02-24 11:22:18 +02:00
|
|
|
aTo <<= false;
|
2012-04-15 23:14:28 -03:00
|
|
|
aAttributeName = "Visibility";
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Any aBegin;
|
2005-09-23 09:41:40 +00:00
|
|
|
if( !mbAfterEffectOnNextEffect ) // sameClick
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
Event aEvent;
|
|
|
|
|
|
|
|
aEvent.Source <<= getNode();
|
|
|
|
aEvent.Trigger = EventTrigger::END_EVENT;
|
|
|
|
aEvent.Repeat = 0;
|
|
|
|
|
|
|
|
aBegin <<= aEvent;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-06 08:59:07 +02:00
|
|
|
aBegin <<= 0.0;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
xAnimate->setBegin( aBegin );
|
|
|
|
xAnimate->setTo( aTo );
|
|
|
|
xAnimate->setAttributeName( aAttributeName );
|
|
|
|
|
2017-04-06 08:59:07 +02:00
|
|
|
xAnimate->setDuration( makeAny( 0.001 ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
xAnimate->setFill( AnimationFill::HOLD );
|
|
|
|
xAnimate->setTarget( maTarget );
|
|
|
|
|
2013-04-30 18:25:35 +02:00
|
|
|
return xAnimate;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setIterateType( sal_Int16 nIterateType )
|
|
|
|
{
|
|
|
|
if( mnIterateType != nIterateType ) try
|
|
|
|
{
|
|
|
|
// do we need to exchange the container node?
|
|
|
|
if( (mnIterateType == 0) || (nIterateType == 0) )
|
|
|
|
{
|
|
|
|
sal_Int16 nTargetSubItem = mnTargetSubItem;
|
|
|
|
|
2013-04-25 13:30:44 +02:00
|
|
|
Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
|
2013-04-23 16:04:30 +02:00
|
|
|
Reference< XTimeContainer > xNewContainer;
|
|
|
|
if(nIterateType)
|
|
|
|
{
|
2013-04-25 13:30:44 +02:00
|
|
|
xNewContainer.set( IterateContainer::create( xContext ) );
|
2013-04-23 16:04:30 +02:00
|
|
|
}
|
|
|
|
else
|
2013-04-25 13:30:44 +02:00
|
|
|
xNewContainer.set( ParallelTimeContainer::create( xContext ), UNO_QUERY_THROW );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
Reference< XTimeContainer > xOldContainer( mxNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
|
|
xOldContainer->removeChild( xChildNode );
|
|
|
|
xNewContainer->appendChild( xChildNode );
|
|
|
|
}
|
|
|
|
|
2013-05-02 10:36:43 +02:00
|
|
|
xNewContainer->setBegin( mxNode->getBegin() );
|
|
|
|
xNewContainer->setDuration( mxNode->getDuration() );
|
|
|
|
xNewContainer->setEnd( mxNode->getEnd() );
|
|
|
|
xNewContainer->setEndSync( mxNode->getEndSync() );
|
|
|
|
xNewContainer->setRepeatCount( mxNode->getRepeatCount() );
|
|
|
|
xNewContainer->setFill( mxNode->getFill() );
|
|
|
|
xNewContainer->setFillDefault( mxNode->getFillDefault() );
|
|
|
|
xNewContainer->setRestart( mxNode->getRestart() );
|
|
|
|
xNewContainer->setRestartDefault( mxNode->getRestartDefault() );
|
|
|
|
xNewContainer->setAcceleration( mxNode->getAcceleration() );
|
|
|
|
xNewContainer->setDecelerate( mxNode->getDecelerate() );
|
|
|
|
xNewContainer->setAutoReverse( mxNode->getAutoReverse() );
|
|
|
|
xNewContainer->setRepeatDuration( mxNode->getRepeatDuration() );
|
|
|
|
xNewContainer->setEndSync( mxNode->getEndSync() );
|
|
|
|
xNewContainer->setRepeatCount( mxNode->getRepeatCount() );
|
|
|
|
xNewContainer->setUserData( mxNode->getUserData() );
|
|
|
|
|
|
|
|
mxNode = xNewContainer;
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
Any aTarget;
|
|
|
|
if( nIterateType )
|
|
|
|
{
|
|
|
|
Reference< XIterateContainer > xIter( mxNode, UNO_QUERY_THROW );
|
|
|
|
xIter->setTarget(maTarget);
|
|
|
|
xIter->setSubItem( nTargetSubItem );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aTarget = maTarget;
|
|
|
|
}
|
|
|
|
|
|
|
|
Reference< XEnumerationAccess > xEA( mxNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xE->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimate > xAnimate( xE->nextElement(), UNO_QUERY );
|
|
|
|
if( xAnimate.is() )
|
|
|
|
{
|
|
|
|
xAnimate->setTarget( aTarget );
|
|
|
|
xAnimate->setSubItem( nTargetSubItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mnIterateType = nIterateType;
|
|
|
|
|
|
|
|
// if we have an iteration container, we must set its type
|
|
|
|
if( mnIterateType )
|
|
|
|
{
|
|
|
|
Reference< XIterateContainer > xIter( mxNode, UNO_QUERY_THROW );
|
|
|
|
xIter->setIterateType( nIterateType );
|
|
|
|
}
|
2005-01-25 14:13:53 +00:00
|
|
|
|
|
|
|
checkForText();
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::CustomAnimationEffect::setIterateType(), Exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setIterateInterval( double fIterateInterval )
|
|
|
|
{
|
|
|
|
if( mfIterateInterval != fIterateInterval )
|
|
|
|
{
|
|
|
|
Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
|
|
|
|
|
|
|
|
DBG_ASSERT( xIter.is(), "sd::CustomAnimationEffect::setIterateInterval(), not an iteration node" );
|
|
|
|
if( xIter.is() )
|
|
|
|
{
|
|
|
|
mfIterateInterval = fIterateInterval;
|
|
|
|
xIter->setIterateInterval( fIterateInterval );
|
|
|
|
}
|
2005-01-25 14:13:53 +00:00
|
|
|
|
|
|
|
calculateIterateDuration();
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString CustomAnimationEffect::getPath() const
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aPath;
|
2007-07-06 12:10:13 +00:00
|
|
|
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimateMotion > xMotion( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( xMotion.is() )
|
|
|
|
{
|
|
|
|
xMotion->getPath() >>= aPath;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::getPath(), exception caught!" );
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return aPath;
|
|
|
|
}
|
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
void CustomAnimationEffect::setPath( const OUString& rPath )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimateMotion > xMotion( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( xMotion.is() )
|
|
|
|
{
|
|
|
|
|
|
|
|
MainSequenceChangeGuard aGuard( mpEffectSequence );
|
|
|
|
xMotion->setPath( Any( rPath ) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::setPath(), exception caught!" );
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
Any CustomAnimationEffect::getProperty( sal_Int32 nNodeType, const OUString& rAttributeName, EValue eValue )
|
|
|
|
{
|
|
|
|
Any aProperty;
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() && !aProperty.hasValue() )
|
|
|
|
{
|
|
|
|
Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( !xAnimate.is() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( xAnimate->getType() == nNodeType )
|
|
|
|
{
|
|
|
|
if( xAnimate->getAttributeName() == rAttributeName )
|
|
|
|
{
|
|
|
|
switch( eValue )
|
|
|
|
{
|
2017-02-15 09:45:57 +02:00
|
|
|
case EValue::To: aProperty = xAnimate->getTo(); break;
|
|
|
|
case EValue::By: aProperty = xAnimate->getBy(); break;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::getProperty(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return aProperty;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CustomAnimationEffect::setProperty( sal_Int32 nNodeType, const OUString& rAttributeName, EValue eValue, const Any& rValue )
|
|
|
|
{
|
|
|
|
bool bChanged = false;
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( !xAnimate.is() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( xAnimate->getType() == nNodeType )
|
|
|
|
{
|
|
|
|
if( xAnimate->getAttributeName() == rAttributeName )
|
|
|
|
{
|
|
|
|
switch( eValue )
|
|
|
|
{
|
2017-02-15 09:45:57 +02:00
|
|
|
case EValue::To:
|
2004-11-26 18:45:55 +00:00
|
|
|
if( xAnimate->getTo() != rValue )
|
|
|
|
{
|
|
|
|
xAnimate->setTo( rValue );
|
|
|
|
bChanged = true;
|
|
|
|
}
|
|
|
|
break;
|
2017-02-15 09:45:57 +02:00
|
|
|
case EValue::By:
|
2004-11-26 18:45:55 +00:00
|
|
|
if( xAnimate->getTo() != rValue )
|
|
|
|
{
|
|
|
|
xAnimate->setBy( rValue );
|
|
|
|
bChanged = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::setProperty(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return bChanged;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool implIsColorAttribute( const OUString& rAttributeName )
|
|
|
|
{
|
2012-04-06 19:49:53 +02:00
|
|
|
return rAttributeName == "FillColor" || rAttributeName == "LineColor" || rAttributeName == "CharColor";
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Any CustomAnimationEffect::getColor( sal_Int32 nIndex )
|
|
|
|
{
|
|
|
|
Any aColor;
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() && !aColor.hasValue() )
|
|
|
|
{
|
|
|
|
Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( !xAnimate.is() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
switch( xAnimate->getType() )
|
|
|
|
{
|
|
|
|
case AnimationNodeType::SET:
|
|
|
|
case AnimationNodeType::ANIMATE:
|
|
|
|
if( !implIsColorAttribute( xAnimate->getAttributeName() ) )
|
|
|
|
break;
|
2016-05-10 17:10:32 +02:00
|
|
|
SAL_FALLTHROUGH;
|
2004-11-26 18:45:55 +00:00
|
|
|
case AnimationNodeType::ANIMATECOLOR:
|
|
|
|
Sequence<Any> aValues( xAnimate->getValues() );
|
|
|
|
if( aValues.hasElements() )
|
|
|
|
{
|
|
|
|
if( aValues.getLength() > nIndex )
|
|
|
|
aColor = aValues[nIndex];
|
|
|
|
}
|
|
|
|
else if( nIndex == 0 )
|
|
|
|
aColor = xAnimate->getFrom();
|
|
|
|
else
|
|
|
|
aColor = xAnimate->getTo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::getColor(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return aColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setColor( sal_Int32 nIndex, const Any& rColor )
|
|
|
|
{
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( !xAnimate.is() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
switch( xAnimate->getType() )
|
|
|
|
{
|
|
|
|
case AnimationNodeType::SET:
|
|
|
|
case AnimationNodeType::ANIMATE:
|
|
|
|
if( !implIsColorAttribute( xAnimate->getAttributeName() ) )
|
|
|
|
break;
|
2016-05-10 17:10:32 +02:00
|
|
|
SAL_FALLTHROUGH;
|
2004-11-26 18:45:55 +00:00
|
|
|
case AnimationNodeType::ANIMATECOLOR:
|
|
|
|
{
|
|
|
|
Sequence<Any> aValues( xAnimate->getValues() );
|
|
|
|
if( aValues.hasElements() )
|
|
|
|
{
|
|
|
|
if( aValues.getLength() > nIndex )
|
|
|
|
{
|
|
|
|
aValues[nIndex] = rColor;
|
|
|
|
xAnimate->setValues( aValues );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( (nIndex == 0) && xAnimate->getFrom().hasValue() )
|
|
|
|
xAnimate->setFrom(rColor);
|
|
|
|
else if( (nIndex == 1) && xAnimate->getTo().hasValue() )
|
|
|
|
xAnimate->setTo(rColor);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::setColor(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Any CustomAnimationEffect::getTransformationProperty( sal_Int32 nTransformType, EValue eValue )
|
|
|
|
{
|
|
|
|
Any aProperty;
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() && !aProperty.hasValue() )
|
|
|
|
{
|
|
|
|
Reference< XAnimateTransform > xTransform( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( !xTransform.is() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( xTransform->getTransformType() == nTransformType )
|
|
|
|
{
|
|
|
|
switch( eValue )
|
|
|
|
{
|
2017-02-15 09:45:57 +02:00
|
|
|
case EValue::To: aProperty = xTransform->getTo(); break;
|
|
|
|
case EValue::By: aProperty = xTransform->getBy(); break;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::getTransformationProperty(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return aProperty;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CustomAnimationEffect::setTransformationProperty( sal_Int32 nTransformType, EValue eValue, const Any& rValue )
|
|
|
|
{
|
|
|
|
bool bChanged = false;
|
|
|
|
if( mxNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
|
|
|
|
if( xEnumerationAccess.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimateTransform > xTransform( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( !xTransform.is() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( xTransform->getTransformType() == nTransformType )
|
|
|
|
{
|
|
|
|
switch( eValue )
|
|
|
|
{
|
2017-02-15 09:45:57 +02:00
|
|
|
case EValue::To:
|
2004-11-26 18:45:55 +00:00
|
|
|
if( xTransform->getTo() != rValue )
|
|
|
|
{
|
|
|
|
xTransform->setTo( rValue );
|
|
|
|
bChanged = true;
|
|
|
|
}
|
|
|
|
break;
|
2017-02-15 09:45:57 +02:00
|
|
|
case EValue::By:
|
2004-11-26 18:45:55 +00:00
|
|
|
if( xTransform->getBy() != rValue )
|
|
|
|
{
|
|
|
|
xTransform->setBy( rValue );
|
|
|
|
bChanged = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::setTransformationProperty(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return bChanged;
|
|
|
|
}
|
|
|
|
|
2016-03-01 15:13:33 +02:00
|
|
|
void CustomAnimationEffect::createAudio( const css::uno::Any& rSource )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT( !mxAudio.is(), "sd::CustomAnimationEffect::createAudio(), node already has an audio!" );
|
|
|
|
|
|
|
|
if( !mxAudio.is() ) try
|
|
|
|
{
|
2013-04-25 13:30:44 +02:00
|
|
|
Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
|
|
|
|
Reference< XAudio > xAudio( Audio::create( xContext ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
xAudio->setSource( rSource );
|
2016-03-01 15:13:33 +02:00
|
|
|
xAudio->setVolume( 1.0 );
|
2004-11-26 18:45:55 +00:00
|
|
|
setAudio( xAudio );
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::createAudio(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Reference< XCommand > findCommandNode( const Reference< XAnimationNode >& xRootNode )
|
|
|
|
{
|
|
|
|
Reference< XCommand > xCommand;
|
|
|
|
|
|
|
|
if( xRootNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( !xCommand.is() && xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY );
|
|
|
|
if( xNode.is() && (xNode->getType() == AnimationNodeType::COMMAND) )
|
|
|
|
xCommand.set( xNode, UNO_QUERY_THROW );
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2011-03-01 19:06:55 +01:00
|
|
|
OSL_FAIL("sd::findCommandNode(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return xCommand;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::removeAudio()
|
|
|
|
{
|
2005-02-24 14:04:33 +00:00
|
|
|
try
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-02-24 14:04:33 +00:00
|
|
|
Reference< XAnimationNode > xChild;
|
|
|
|
|
|
|
|
if( mxAudio.is() )
|
|
|
|
{
|
|
|
|
xChild.set( mxAudio, UNO_QUERY );
|
|
|
|
mxAudio.clear();
|
|
|
|
}
|
|
|
|
else if( mnCommand == EffectCommands::STOPAUDIO )
|
|
|
|
{
|
|
|
|
xChild.set( findCommandNode( mxNode ), UNO_QUERY );
|
|
|
|
mnCommand = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( xChild.is() )
|
|
|
|
{
|
|
|
|
Reference< XTimeContainer > xContainer( mxNode, UNO_QUERY );
|
|
|
|
if( xContainer.is() )
|
|
|
|
xContainer->removeChild( xChild );
|
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2011-03-01 19:06:55 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::removeAudio(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void CustomAnimationEffect::setAudio( const Reference< css::animations::XAudio >& xAudio )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-02-24 14:04:33 +00:00
|
|
|
if( mxAudio != xAudio ) try
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
removeAudio();
|
|
|
|
mxAudio = xAudio;
|
|
|
|
Reference< XTimeContainer > xContainer( mxNode, UNO_QUERY );
|
|
|
|
Reference< XAnimationNode > xChild( mxAudio, UNO_QUERY );
|
|
|
|
if( xContainer.is() && xChild.is() )
|
|
|
|
xContainer->appendChild( xChild );
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2005-02-24 14:04:33 +00:00
|
|
|
{
|
2011-03-01 19:06:55 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::setAudio(), exception caught!" );
|
2005-02-24 14:04:33 +00:00
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::setStopAudio()
|
|
|
|
{
|
|
|
|
if( mnCommand != EffectCommands::STOPAUDIO ) try
|
|
|
|
{
|
|
|
|
if( mxAudio.is() )
|
|
|
|
removeAudio();
|
|
|
|
|
2013-04-25 14:12:19 +02:00
|
|
|
Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
|
|
|
|
Reference< XCommand > xCommand( Command::create( xContext ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
xCommand->setCommand( EffectCommands::STOPAUDIO );
|
|
|
|
|
|
|
|
Reference< XTimeContainer > xContainer( mxNode, UNO_QUERY_THROW );
|
2013-05-02 10:36:43 +02:00
|
|
|
xContainer->appendChild( xCommand );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
mnCommand = EffectCommands::STOPAUDIO;
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2011-03-01 19:06:55 +01:00
|
|
|
OSL_FAIL("sd::CustomAnimationEffect::setStopAudio(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-18 15:44:51 +00:00
|
|
|
bool CustomAnimationEffect::getStopAudio() const
|
|
|
|
{
|
|
|
|
return mnCommand == EffectCommands::STOPAUDIO;
|
|
|
|
}
|
|
|
|
|
SOSAW080: Added first bunch of basic changes to helpers
SOSAW080: Make SdrModel& prerequisite to SdrObjects
Added need for SdrModel& in constructors of SdrModel,
SdrPage, SdrView and SdrObjList. Builds, not finished.
SOSAW080: removed and replaced old SdrModel
Removed and replaced GetModel()/SetModel() in all using
classes (SdrObject, SdrPage, SdrView), added accessors
to new referenced SdrModel, adapted all accessing places.
Refactored/Extended ::Clone and ::operator== for these
classes to allow cloning objects to a target SdrModel.
Adapted places where this is done AFAP. Added quite some
comments (tagged with 'TTTT') where possible further work
is needed. Builds completely, thus checking in. This does
not mean that this change is done yet.
SOSAW080: Adapted SdrPage/SdrModel relationship
Also needed to work on copy-construction of SdrPage and hierarchy,
quite some stuff removed, no copy-constructor anymore, no
MigrateItemPool stuff. Builds well, test stuck, will need
some cleanup/finetunung
SOSAW080: Smaller corrections/includes adapted
SOSAW080: Smaller corrections/includes adapted
SOSAW080: Debugging/Stabilizing/MakeUnitTestWork
SOSAW080: Stabilized for UnitTests, cleanups
SOSAW080: Adapted GetObjGraphic to just take a const SdrObject&
SOSAW080: Removed ChangeModel from classes
Classes SvxTextEditSource and SvxDrawPage (including
TextEditSource stuff) do not need change of SdrModel
anymore.
SOSAW080: Adapted some comments to make more readable
SOSAW080: Corrected constructor
SOSAW080: getSdrModelFromUnoModel added override marks
SOSAW080: Added missing includes
SOSAW080: Corrected SdrPage constructor
SOSAW080: Corrected some SdrObject::Clone scenarios
Especially when cloning to another SdrModel and taking
the sdr::properties into account.
SOSAW080: Added include for Mac-Build
SOSAW080: Added Scale to DefaultProperties
If a SdrModel change happens in DefaultProperties copy
constructor (used from Clone()), potentially a Scale
for the SfxItems has to be done.
SOSAW080: Added missing include for MacBuild
SOSAW080: Corrected CppunitTest_sc_anchor_test
An adaption of a SdrPathObj instantiation was missing,
added that. Seems as if that test is no tpart of the
usual 'make' scenario, but used/executed in gerrit builds
SOSAW080: Reworked SvxShape to use SdrObject's SdrModel
SOSAW080: Reworked SvxShape to use SdrObject's SdrModel
SOSAW080: Free SdrObjects when SdrModel goes down
In an UNO API test problem is that SvxShapes reference
SdrShapes, but these are not added to a SdrPage and not
'owned' by the SvxShape. Thus these do not get deleted
at all (same in master, memory leak). I extended
SvxShape::Notify the case for ModelCleared to also
Free the SdrObject when not owner and it's not added to
a SdrPage (in that case it gets deleted with deleting
the SdrModel)
SOSAW080: Solve UNO API calls that move SvxShapes to other Model
Due to UNO API tests I got a call to insert an xShape to a
xDrawPage which was constructed in another Model, this has now to
be done by Cloning the SdrObject to the new SdrModel, getting
rid of the old one and getting all the UNO implementation
stuff right (referemces SdrObject <-> xShape).
1cb7d573d323e98a89761fe662c10c4a654fdec0
24617494a0ef79f6e33dfcb02782a833a81c6434
763f39094b6a48b529a6952d01468f8776c97679
242b9e228a9a042c3a5bdd38b1ea6600144276d5
242b9e228a9a042c3a5bdd38b1ea6600144276d5
33a6f3f306b70c223171aef796dd5ee041ad14df
6878b33f8b05738a44c0910e40a60a0f0d1d58ed
0a636caf3cb36c2f9c6cd11aa22cb9bc435dc8f2
8c4626274a5cc531dad27f27c0c45d4c528fb2fb
446685a49a6d67aedd01cfbbd5e87b07f97a4d7b
c1b5ed3c99bc7219a0061e4ece24ea42afd2889a
22de9a1c8af7c25be5c108671ddc548ba323ed47
4caf6b6fbbe6e8130741d793dffb560fd01d4ed5
488b9601735ec1822433f82f633990063951fe08
c366d60299f239e3df856ddffedb19e743e4be0c
c5137ba8c597c7b5f90318df50e87b93a39a28dc
f9e646242cf89f6fde1315046952252a2c429779
f830fbc5fadd89d04be5edd2a5abf9b0d4bf0410
1694b54903df784385abaa8452e1201e12344238
17bcb44d2e29920c0c74430c2d9c703b36cfa0ad
17bcb44d2e29920c0c74430c2d9c703b36cfa0ad
7b5c241faec7488924e5935ae8b19f785846b5e4
bf097ee7467895823fbd158a2a9543da3b5a5078
Change-Id: Iaf53535de0502a481466be74a1768bbb39f0e78c
Reviewed-on: https://gerrit.libreoffice.org/52526
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-03-01 15:54:32 +01:00
|
|
|
SdrPathObj* CustomAnimationEffect::createSdrPathObjFromPath(SdrModel& rTargetModel)
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
SOSAW080: Added first bunch of basic changes to helpers
SOSAW080: Make SdrModel& prerequisite to SdrObjects
Added need for SdrModel& in constructors of SdrModel,
SdrPage, SdrView and SdrObjList. Builds, not finished.
SOSAW080: removed and replaced old SdrModel
Removed and replaced GetModel()/SetModel() in all using
classes (SdrObject, SdrPage, SdrView), added accessors
to new referenced SdrModel, adapted all accessing places.
Refactored/Extended ::Clone and ::operator== for these
classes to allow cloning objects to a target SdrModel.
Adapted places where this is done AFAP. Added quite some
comments (tagged with 'TTTT') where possible further work
is needed. Builds completely, thus checking in. This does
not mean that this change is done yet.
SOSAW080: Adapted SdrPage/SdrModel relationship
Also needed to work on copy-construction of SdrPage and hierarchy,
quite some stuff removed, no copy-constructor anymore, no
MigrateItemPool stuff. Builds well, test stuck, will need
some cleanup/finetunung
SOSAW080: Smaller corrections/includes adapted
SOSAW080: Smaller corrections/includes adapted
SOSAW080: Debugging/Stabilizing/MakeUnitTestWork
SOSAW080: Stabilized for UnitTests, cleanups
SOSAW080: Adapted GetObjGraphic to just take a const SdrObject&
SOSAW080: Removed ChangeModel from classes
Classes SvxTextEditSource and SvxDrawPage (including
TextEditSource stuff) do not need change of SdrModel
anymore.
SOSAW080: Adapted some comments to make more readable
SOSAW080: Corrected constructor
SOSAW080: getSdrModelFromUnoModel added override marks
SOSAW080: Added missing includes
SOSAW080: Corrected SdrPage constructor
SOSAW080: Corrected some SdrObject::Clone scenarios
Especially when cloning to another SdrModel and taking
the sdr::properties into account.
SOSAW080: Added include for Mac-Build
SOSAW080: Added Scale to DefaultProperties
If a SdrModel change happens in DefaultProperties copy
constructor (used from Clone()), potentially a Scale
for the SfxItems has to be done.
SOSAW080: Added missing include for MacBuild
SOSAW080: Corrected CppunitTest_sc_anchor_test
An adaption of a SdrPathObj instantiation was missing,
added that. Seems as if that test is no tpart of the
usual 'make' scenario, but used/executed in gerrit builds
SOSAW080: Reworked SvxShape to use SdrObject's SdrModel
SOSAW080: Reworked SvxShape to use SdrObject's SdrModel
SOSAW080: Free SdrObjects when SdrModel goes down
In an UNO API test problem is that SvxShapes reference
SdrShapes, but these are not added to a SdrPage and not
'owned' by the SvxShape. Thus these do not get deleted
at all (same in master, memory leak). I extended
SvxShape::Notify the case for ModelCleared to also
Free the SdrObject when not owner and it's not added to
a SdrPage (in that case it gets deleted with deleting
the SdrModel)
SOSAW080: Solve UNO API calls that move SvxShapes to other Model
Due to UNO API tests I got a call to insert an xShape to a
xDrawPage which was constructed in another Model, this has now to
be done by Cloning the SdrObject to the new SdrModel, getting
rid of the old one and getting all the UNO implementation
stuff right (referemces SdrObject <-> xShape).
1cb7d573d323e98a89761fe662c10c4a654fdec0
24617494a0ef79f6e33dfcb02782a833a81c6434
763f39094b6a48b529a6952d01468f8776c97679
242b9e228a9a042c3a5bdd38b1ea6600144276d5
242b9e228a9a042c3a5bdd38b1ea6600144276d5
33a6f3f306b70c223171aef796dd5ee041ad14df
6878b33f8b05738a44c0910e40a60a0f0d1d58ed
0a636caf3cb36c2f9c6cd11aa22cb9bc435dc8f2
8c4626274a5cc531dad27f27c0c45d4c528fb2fb
446685a49a6d67aedd01cfbbd5e87b07f97a4d7b
c1b5ed3c99bc7219a0061e4ece24ea42afd2889a
22de9a1c8af7c25be5c108671ddc548ba323ed47
4caf6b6fbbe6e8130741d793dffb560fd01d4ed5
488b9601735ec1822433f82f633990063951fe08
c366d60299f239e3df856ddffedb19e743e4be0c
c5137ba8c597c7b5f90318df50e87b93a39a28dc
f9e646242cf89f6fde1315046952252a2c429779
f830fbc5fadd89d04be5edd2a5abf9b0d4bf0410
1694b54903df784385abaa8452e1201e12344238
17bcb44d2e29920c0c74430c2d9c703b36cfa0ad
17bcb44d2e29920c0c74430c2d9c703b36cfa0ad
7b5c241faec7488924e5935ae8b19f785846b5e4
bf097ee7467895823fbd158a2a9543da3b5a5078
Change-Id: Iaf53535de0502a481466be74a1768bbb39f0e78c
Reviewed-on: https://gerrit.libreoffice.org/52526
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-03-01 15:54:32 +01:00
|
|
|
SdrPathObj * pPathObj = new SdrPathObj(rTargetModel, OBJ_PATHLINE);
|
2007-07-06 12:10:13 +00:00
|
|
|
updateSdrPathObjFromPath( *pPathObj );
|
|
|
|
return pPathObj;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::updateSdrPathObjFromPath( SdrPathObj& rPathObj )
|
|
|
|
{
|
2016-04-27 09:22:13 +02:00
|
|
|
::basegfx::B2DPolyPolygon aPolyPoly;
|
2017-09-22 14:12:07 +03:00
|
|
|
if( ::basegfx::utils::importFromSvgD( aPolyPoly, getPath(), true, nullptr ) )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
SdrObject* pObj = GetSdrObjectFromXShape( getTargetShape() );
|
|
|
|
if( pObj )
|
|
|
|
{
|
SOSAW080: Derive SdrObjGroup from SdrObjList
Also simplify parent/child relationships, get rid
of double data (SdrPage/Parent infos in SdrObjects,
also in SdrObjList). This is all not needed - when a
SdrObject is inserted to a SdrPage, get SdrPage by
traveling over parents (no double info, member as soon
as inserted, ...).
More cleanups/reworks included, will need some more
cleanups, too.
Stabilizing: SetRectsDirty/DefaultStyleSheet
Had to correct the SetRectsDirty stuff for 3D due to
going down the hierarchy while the 2D implementation
goes the other direction -> endless loops. Added special
handling for 3D stuff for now (will be chnaged again when
SnapRect is no longer needed at SdrObject level).
Also had to adapt how the DefaultStyleSheet is set at
incarnated SdrObjects - better: their properties. Since
we now always have a SdrModel, it is possible to correctly
initialize with the correct default StyleSheet from that
SdrModel.
This needs to be done after ForceDefaultAttributes and in a
way that again deletes Items that are set in the StyleSheet.
This leads to an error in CppunitTest_sd_import_tests where
I checked tdf100491 - it is okay and thus I change the control
instance of the imported, XML-dumped file.
The less hard attributes, the better for Styles in general.
Cleanup of comments for last two commits
Corrected SvxShape::getParent()
Needed to get the direct parent, so test for SdrObject
first (to get SdrObjGroup/E3DScene), for SdrPage second
Fixed CppunitTest_sc_subsequent_export_test
Several problems arose. The used SdrCaptionObj was
Cloned, but the clone not inserted to a SdrPage. This
leads to not being able to access a UNO API imlementation
of the SdrPage (SvxPage) on lower levels.
It worked before due to SdrObject having a SdrPage*
additionally to being added to a SdrPage - this is exactly
the main cleanup this change does.
Looked for why it is cloned, could see no reasons. The
SdrCaptionObj exists during all im/export, not difference
to other SdrObjects (that do not get cloned). It is not
changed in any way. It *might* be to suppress a crash that
happened due to UNO API Service emfio/emfio not being
available in the UnitTest scenario. Interestingly it
did not crash with the cloned SdrCaptionObj, but the
Graphic exported was probably wrong.
Fixed by no longer Cloning the SdrCaptionObj and adding
emfio/emfio UNO API Service.
d139f821a5b39535a3e7b9c6261df7e18f8ae8ac
910e7f4bc628a715fda7545dffaf3369d5e76ea0
ca1de01b723051e09ac37d7ec7bba978beea41c5
3a76da1471dfe75e69847f64a6a3519ad21c8c9c
Change-Id: I986586e326b563acebf00d931a7084c6eb09e5f8
Reviewed-on: https://gerrit.libreoffice.org/54689
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-04-16 22:34:50 +02:00
|
|
|
SdrPage* pPage = pObj->getSdrPageFromSdrObject();
|
2007-07-06 12:10:13 +00:00
|
|
|
if( pPage )
|
|
|
|
{
|
|
|
|
const Size aPageSize( pPage->GetSize() );
|
2018-01-12 20:16:43 +01:00
|
|
|
aPolyPoly.transform(basegfx::utils::createScaleB2DHomMatrix(static_cast<double>(aPageSize.Width()), static_cast<double>(aPageSize.Height())));
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
|
2017-03-30 20:27:55 +02:00
|
|
|
const ::tools::Rectangle aBoundRect( pObj->GetCurrentBoundRect() );
|
2007-07-06 12:10:13 +00:00
|
|
|
const Point aCenter( aBoundRect.Center() );
|
2017-09-22 14:12:07 +03:00
|
|
|
aPolyPoly.transform(basegfx::utils::createTranslateB2DHomMatrix(aCenter.X(), aCenter.Y()));
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 09:22:13 +02:00
|
|
|
rPathObj.SetPathPoly( aPolyPoly );
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationEffect::updatePathFromSdrPathObj( const SdrPathObj& rPathObj )
|
|
|
|
{
|
2016-04-27 09:22:13 +02:00
|
|
|
::basegfx::B2DPolyPolygon aPolyPoly( rPathObj.GetPathPoly() );
|
2007-07-06 12:10:13 +00:00
|
|
|
|
|
|
|
SdrObject* pObj = GetSdrObjectFromXShape( getTargetShape() );
|
|
|
|
if( pObj )
|
|
|
|
{
|
2017-03-30 20:27:55 +02:00
|
|
|
::tools::Rectangle aBoundRect(0,0,0,0);
|
2011-12-06 03:43:48 +01:00
|
|
|
|
2016-11-30 11:12:39 +02:00
|
|
|
const drawinglayer::primitive2d::Primitive2DContainer xPrimitives(pObj->GetViewContact().getViewIndependentPrimitive2DContainer());
|
2011-12-06 03:43:48 +01:00
|
|
|
const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
|
2015-12-10 12:27:50 +02:00
|
|
|
const basegfx::B2DRange aRange(xPrimitives.getB2DRange(aViewInformation2D));
|
2011-12-06 03:43:48 +01:00
|
|
|
|
|
|
|
if(!aRange.isEmpty())
|
|
|
|
{
|
2017-03-30 20:27:55 +02:00
|
|
|
aBoundRect = ::tools::Rectangle(
|
2018-01-12 20:16:43 +01:00
|
|
|
static_cast<sal_Int32>(floor(aRange.getMinX())), static_cast<sal_Int32>(floor(aRange.getMinY())),
|
|
|
|
static_cast<sal_Int32>(ceil(aRange.getMaxX())), static_cast<sal_Int32>(ceil(aRange.getMaxY())));
|
2011-12-06 03:43:48 +01:00
|
|
|
}
|
|
|
|
|
2007-07-06 12:10:13 +00:00
|
|
|
const Point aCenter( aBoundRect.Center() );
|
|
|
|
|
2017-09-22 14:12:07 +03:00
|
|
|
aPolyPoly.transform(basegfx::utils::createTranslateB2DHomMatrix(-aCenter.X(), -aCenter.Y()));
|
2007-07-06 12:10:13 +00:00
|
|
|
|
SOSAW080: Derive SdrObjGroup from SdrObjList
Also simplify parent/child relationships, get rid
of double data (SdrPage/Parent infos in SdrObjects,
also in SdrObjList). This is all not needed - when a
SdrObject is inserted to a SdrPage, get SdrPage by
traveling over parents (no double info, member as soon
as inserted, ...).
More cleanups/reworks included, will need some more
cleanups, too.
Stabilizing: SetRectsDirty/DefaultStyleSheet
Had to correct the SetRectsDirty stuff for 3D due to
going down the hierarchy while the 2D implementation
goes the other direction -> endless loops. Added special
handling for 3D stuff for now (will be chnaged again when
SnapRect is no longer needed at SdrObject level).
Also had to adapt how the DefaultStyleSheet is set at
incarnated SdrObjects - better: their properties. Since
we now always have a SdrModel, it is possible to correctly
initialize with the correct default StyleSheet from that
SdrModel.
This needs to be done after ForceDefaultAttributes and in a
way that again deletes Items that are set in the StyleSheet.
This leads to an error in CppunitTest_sd_import_tests where
I checked tdf100491 - it is okay and thus I change the control
instance of the imported, XML-dumped file.
The less hard attributes, the better for Styles in general.
Cleanup of comments for last two commits
Corrected SvxShape::getParent()
Needed to get the direct parent, so test for SdrObject
first (to get SdrObjGroup/E3DScene), for SdrPage second
Fixed CppunitTest_sc_subsequent_export_test
Several problems arose. The used SdrCaptionObj was
Cloned, but the clone not inserted to a SdrPage. This
leads to not being able to access a UNO API imlementation
of the SdrPage (SvxPage) on lower levels.
It worked before due to SdrObject having a SdrPage*
additionally to being added to a SdrPage - this is exactly
the main cleanup this change does.
Looked for why it is cloned, could see no reasons. The
SdrCaptionObj exists during all im/export, not difference
to other SdrObjects (that do not get cloned). It is not
changed in any way. It *might* be to suppress a crash that
happened due to UNO API Service emfio/emfio not being
available in the UnitTest scenario. Interestingly it
did not crash with the cloned SdrCaptionObj, but the
Graphic exported was probably wrong.
Fixed by no longer Cloning the SdrCaptionObj and adding
emfio/emfio UNO API Service.
d139f821a5b39535a3e7b9c6261df7e18f8ae8ac
910e7f4bc628a715fda7545dffaf3369d5e76ea0
ca1de01b723051e09ac37d7ec7bba978beea41c5
3a76da1471dfe75e69847f64a6a3519ad21c8c9c
Change-Id: I986586e326b563acebf00d931a7084c6eb09e5f8
Reviewed-on: https://gerrit.libreoffice.org/54689
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
2018-04-16 22:34:50 +02:00
|
|
|
SdrPage* pPage = pObj->getSdrPageFromSdrObject();
|
2007-07-06 12:10:13 +00:00
|
|
|
if( pPage )
|
|
|
|
{
|
|
|
|
const Size aPageSize( pPage->GetSize() );
|
2017-09-22 14:12:07 +03:00
|
|
|
aPolyPoly.transform(basegfx::utils::createScaleB2DHomMatrix(
|
2018-01-12 20:16:43 +01:00
|
|
|
1.0 / static_cast<double>(aPageSize.Width()), 1.0 / static_cast<double>(aPageSize.Height())));
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-22 14:12:07 +03:00
|
|
|
setPath( ::basegfx::utils::exportToSvgD( aPolyPoly, true, true, true) );
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
EffectSequenceHelper::EffectSequenceHelper()
|
|
|
|
: mnSequenceType( EffectNodeType::DEFAULT )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
EffectSequenceHelper::EffectSequenceHelper( const css::uno::Reference< css::animations::XTimeContainer >& xSequenceRoot )
|
2004-11-26 18:45:55 +00:00
|
|
|
: mxSequenceRoot( xSequenceRoot ), mnSequenceType( EffectNodeType::DEFAULT )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xNode( mxSequenceRoot, UNO_QUERY_THROW );
|
|
|
|
create( xNode );
|
|
|
|
}
|
|
|
|
|
|
|
|
EffectSequenceHelper::~EffectSequenceHelper()
|
|
|
|
{
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::reset()
|
|
|
|
{
|
|
|
|
EffectSequence::iterator aIter( maEffects.begin() );
|
|
|
|
EffectSequence::iterator aEnd( maEffects.end() );
|
|
|
|
if( aIter != aEnd )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect = (*aIter++);
|
2015-11-10 10:23:02 +01:00
|
|
|
pEffect->setEffectSequence(nullptr);
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
maEffects.clear();
|
|
|
|
}
|
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
Reference< XAnimationNode > EffectSequenceHelper::getRootNode()
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xRoot( mxSequenceRoot, UNO_QUERY );
|
|
|
|
return xRoot;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::append( const CustomAnimationEffectPtr& pEffect )
|
|
|
|
{
|
|
|
|
pEffect->setEffectSequence( this );
|
|
|
|
maEffects.push_back(pEffect);
|
|
|
|
rebuild();
|
|
|
|
}
|
|
|
|
|
|
|
|
CustomAnimationEffectPtr EffectSequenceHelper::append( const CustomAnimationPresetPtr& pPreset, const Any& rTarget, double fDuration /* = -1.0 */ )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect;
|
|
|
|
|
|
|
|
if( pPreset.get() )
|
|
|
|
{
|
2017-05-08 16:12:01 +02:00
|
|
|
Reference< XAnimationNode > xNode( pPreset->create( "" ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
if( xNode.is() )
|
|
|
|
{
|
|
|
|
// first, filter all only ui relevant user data
|
|
|
|
std::vector< NamedValue > aNewUserData;
|
|
|
|
Sequence< NamedValue > aUserData( xNode->getUserData() );
|
|
|
|
sal_Int32 nLength = aUserData.getLength();
|
|
|
|
const NamedValue* p = aUserData.getConstArray();
|
|
|
|
bool bFilter = false;
|
|
|
|
|
|
|
|
while( nLength-- )
|
|
|
|
{
|
2012-04-06 19:49:53 +02:00
|
|
|
if( p->Name != "text-only" && p->Name != "preset-property" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
aNewUserData.push_back( *p );
|
|
|
|
bFilter = true;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bFilter )
|
|
|
|
{
|
2016-11-08 15:53:21 +02:00
|
|
|
aUserData = ::comphelper::containerToSequence( aNewUserData );
|
2004-11-26 18:45:55 +00:00
|
|
|
xNode->setUserData( aUserData );
|
|
|
|
}
|
|
|
|
|
|
|
|
// check target, maybe we need to force it to text
|
2005-03-18 15:44:51 +00:00
|
|
|
sal_Int16 nSubItem = ShapeAnimationSubType::AS_WHOLE;
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2016-04-12 16:39:03 +02:00
|
|
|
if( rTarget.getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
nSubItem = ShapeAnimationSubType::ONLY_TEXT;
|
|
|
|
}
|
2005-03-18 15:44:51 +00:00
|
|
|
else if( pPreset->isTextOnly() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
Reference< XShape > xShape;
|
2016-04-12 16:39:03 +02:00
|
|
|
rTarget >>= xShape;
|
2004-11-26 18:45:55 +00:00
|
|
|
if( xShape.is() )
|
|
|
|
{
|
2017-11-13 00:20:20 +01:00
|
|
|
// that's bad, we target a shape here but the effect is only for text
|
2004-11-26 18:45:55 +00:00
|
|
|
// so change subitem
|
|
|
|
nSubItem = ShapeAnimationSubType::ONLY_TEXT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// now create effect from preset
|
|
|
|
pEffect.reset( new CustomAnimationEffect( xNode ) );
|
|
|
|
pEffect->setEffectSequence( this );
|
2016-04-12 16:39:03 +02:00
|
|
|
pEffect->setTarget( rTarget );
|
2004-11-26 18:45:55 +00:00
|
|
|
pEffect->setTargetSubItem( nSubItem );
|
|
|
|
if( fDuration != -1.0 )
|
|
|
|
pEffect->setDuration( fDuration );
|
|
|
|
|
|
|
|
maEffects.push_back(pEffect);
|
|
|
|
|
|
|
|
rebuild();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DBG_ASSERT( pEffect.get(), "sd::EffectSequenceHelper::append(), failed!" );
|
|
|
|
return pEffect;
|
|
|
|
}
|
|
|
|
|
2007-07-06 12:10:13 +00:00
|
|
|
CustomAnimationEffectPtr EffectSequenceHelper::append( const SdrPathObj& rPathObj, const Any& rTarget, double fDuration /* = -1.0 */ )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect;
|
|
|
|
|
|
|
|
if( fDuration <= 0.0 )
|
|
|
|
fDuration = 2.0;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2013-04-25 14:43:24 +02:00
|
|
|
Reference< XTimeContainer > xEffectContainer( ParallelTimeContainer::create( ::comphelper::getProcessComponentContext() ), UNO_QUERY_THROW );
|
2013-04-25 14:18:47 +02:00
|
|
|
Reference< XAnimationNode > xAnimateMotion( AnimateMotion::create( ::comphelper::getProcessComponentContext() ) );
|
2007-07-06 12:10:13 +00:00
|
|
|
|
|
|
|
xAnimateMotion->setDuration( Any( fDuration ) );
|
|
|
|
xAnimateMotion->setFill( AnimationFill::HOLD );
|
|
|
|
xEffectContainer->appendChild( xAnimateMotion );
|
|
|
|
|
|
|
|
sal_Int16 nSubItem = ShapeAnimationSubType::AS_WHOLE;
|
|
|
|
|
2014-05-10 00:14:44 +02:00
|
|
|
if( rTarget.getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2007-07-06 12:10:13 +00:00
|
|
|
nSubItem = ShapeAnimationSubType::ONLY_TEXT;
|
|
|
|
|
2013-05-02 10:36:43 +02:00
|
|
|
pEffect.reset( new CustomAnimationEffect( xEffectContainer ) );
|
2007-07-06 12:10:13 +00:00
|
|
|
pEffect->setEffectSequence( this );
|
|
|
|
pEffect->setTarget( rTarget );
|
|
|
|
pEffect->setTargetSubItem( nSubItem );
|
2015-10-28 12:01:32 +02:00
|
|
|
pEffect->setNodeType( css::presentation::EffectNodeType::ON_CLICK );
|
|
|
|
pEffect->setPresetClass( css::presentation::EffectPresetClass::MOTIONPATH );
|
2007-07-06 12:10:13 +00:00
|
|
|
pEffect->setAcceleration( 0.5 );
|
|
|
|
pEffect->setDecelerate( 0.5 );
|
|
|
|
pEffect->setFill( AnimationFill::HOLD );
|
|
|
|
pEffect->setBegin( 0.0 );
|
|
|
|
pEffect->updatePathFromSdrPathObj( rPathObj );
|
|
|
|
if( fDuration != -1.0 )
|
|
|
|
pEffect->setDuration( fDuration );
|
|
|
|
|
|
|
|
maEffects.push_back(pEffect);
|
|
|
|
|
|
|
|
rebuild();
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::EffectSequenceHelper::append(), exception caught!" );
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return pEffect;
|
|
|
|
}
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
void EffectSequenceHelper::replace( const CustomAnimationEffectPtr& pEffect, const CustomAnimationPresetPtr& pPreset, const OUString& rPresetSubType, double fDuration /* = -1.0 */ )
|
|
|
|
{
|
|
|
|
if( pEffect.get() && pPreset.get() ) try
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xNewNode( pPreset->create( rPresetSubType ) );
|
|
|
|
if( xNewNode.is() )
|
|
|
|
{
|
|
|
|
pEffect->replaceNode( xNewNode );
|
|
|
|
if( fDuration != -1.0 )
|
|
|
|
pEffect->setDuration( fDuration );
|
|
|
|
}
|
|
|
|
|
|
|
|
rebuild();
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::EffectSequenceHelper::replace(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::replace( const CustomAnimationEffectPtr& pEffect, const CustomAnimationPresetPtr& pPreset, double fDuration /* = -1.0 */ )
|
|
|
|
{
|
2017-05-08 16:12:01 +02:00
|
|
|
replace( pEffect, pPreset, "", fDuration );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::remove( const CustomAnimationEffectPtr& pEffect )
|
|
|
|
{
|
|
|
|
if( pEffect.get() )
|
|
|
|
{
|
2015-11-10 10:23:02 +01:00
|
|
|
pEffect->setEffectSequence( nullptr );
|
2004-11-26 18:45:55 +00:00
|
|
|
maEffects.remove( pEffect );
|
|
|
|
}
|
|
|
|
|
|
|
|
rebuild();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::rebuild()
|
|
|
|
{
|
|
|
|
implRebuild();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::implRebuild()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// first we delete all time containers on the first two levels
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxSequenceRoot, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
|
|
Reference< XTimeContainer > xChildContainer( xChildNode, UNO_QUERY_THROW );
|
|
|
|
|
|
|
|
Reference< XEnumerationAccess > xChildEnumerationAccess( xChildNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xChildEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
|
|
xChildContainer->removeChild( xNode );
|
|
|
|
}
|
|
|
|
|
|
|
|
mxSequenceRoot->removeChild( xChildNode );
|
|
|
|
}
|
|
|
|
|
|
|
|
// second, rebuild main sequence
|
|
|
|
EffectSequence::iterator aIter( maEffects.begin() );
|
|
|
|
EffectSequence::iterator aEnd( maEffects.end() );
|
|
|
|
if( aIter != aEnd )
|
|
|
|
{
|
2017-11-04 14:45:32 +01:00
|
|
|
std::vector< sd::AfterEffectNode > aAfterEffects;
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
CustomAnimationEffectPtr pEffect = (*aIter++);
|
|
|
|
|
|
|
|
bool bFirst = true;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
// create a par container for the next click node and all following with and after effects
|
2013-04-25 14:43:24 +02:00
|
|
|
Reference< XTimeContainer > xOnClickContainer( ParallelTimeContainer::create( ::comphelper::getProcessComponentContext() ), UNO_QUERY_THROW );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
Event aEvent;
|
|
|
|
if( mxEventSource.is() )
|
|
|
|
{
|
|
|
|
aEvent.Source <<= mxEventSource;
|
|
|
|
aEvent.Trigger = EventTrigger::ON_CLICK;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aEvent.Trigger = EventTrigger::ON_NEXT;
|
|
|
|
}
|
|
|
|
aEvent.Repeat = 0;
|
|
|
|
|
|
|
|
Any aBegin( makeAny( aEvent ) );
|
|
|
|
if( bFirst )
|
|
|
|
{
|
|
|
|
// if the first node is not a click action, this click container
|
|
|
|
// must not have INDEFINITE begin but start at 0s
|
|
|
|
bFirst = false;
|
|
|
|
if( pEffect->getNodeType() != EffectNodeType::ON_CLICK )
|
2017-04-06 08:59:07 +02:00
|
|
|
aBegin <<= 0.0;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
xOnClickContainer->setBegin( aBegin );
|
|
|
|
|
2013-05-02 10:36:43 +02:00
|
|
|
mxSequenceRoot->appendChild( xOnClickContainer );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
double fBegin = 0.0;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
// create a par container for the current click or after effect node and all following with effects
|
2013-04-25 14:43:24 +02:00
|
|
|
Reference< XTimeContainer > xWithContainer( ParallelTimeContainer::create( ::comphelper::getProcessComponentContext() ), UNO_QUERY_THROW );
|
2004-11-26 18:45:55 +00:00
|
|
|
xWithContainer->setBegin( makeAny( fBegin ) );
|
2013-05-02 10:36:43 +02:00
|
|
|
xOnClickContainer->appendChild( xWithContainer );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
double fDuration = 0.0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xEffectNode( pEffect->getNode() );
|
|
|
|
xWithContainer->appendChild( xEffectNode );
|
|
|
|
|
|
|
|
if( pEffect->hasAfterEffect() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xAfterEffect( pEffect->createAfterEffectNode() );
|
2005-09-23 09:41:40 +00:00
|
|
|
AfterEffectNode a( xAfterEffect, xEffectNode, pEffect->IsAfterEffectOnNext() );
|
2004-11-26 18:45:55 +00:00
|
|
|
aAfterEffects.push_back( a );
|
|
|
|
}
|
|
|
|
|
2005-01-25 14:13:53 +00:00
|
|
|
double fTemp = pEffect->getBegin() + pEffect->getAbsoluteDuration();
|
2004-11-26 18:45:55 +00:00
|
|
|
if( fTemp > fDuration )
|
|
|
|
fDuration = fTemp;
|
|
|
|
|
|
|
|
if( aIter != aEnd )
|
|
|
|
pEffect = (*aIter++);
|
|
|
|
else
|
|
|
|
pEffect.reset();
|
|
|
|
}
|
|
|
|
while( pEffect.get() && (pEffect->getNodeType() == EffectNodeType::WITH_PREVIOUS) );
|
|
|
|
|
|
|
|
fBegin += fDuration;
|
|
|
|
}
|
|
|
|
while( pEffect.get() && (pEffect->getNodeType() != EffectNodeType::ON_CLICK) );
|
|
|
|
}
|
|
|
|
while( pEffect.get() );
|
|
|
|
|
|
|
|
// process after effect nodes
|
|
|
|
std::for_each( aAfterEffects.begin(), aAfterEffects.end(), stl_process_after_effect_node_func );
|
|
|
|
|
|
|
|
updateTextGroups();
|
|
|
|
|
|
|
|
// reset duration, might have been altered (see below)
|
|
|
|
mxSequenceRoot->setDuration( Any() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-12-01 23:41:42 +02:00
|
|
|
// empty sequence, set duration to 0.0 explicitly
|
2004-11-26 18:45:55 +00:00
|
|
|
// (otherwise, this sequence will never end)
|
2017-04-06 08:59:07 +02:00
|
|
|
mxSequenceRoot->setDuration( makeAny(0.0) );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::EffectSequenceHelper::rebuild(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
stl_CustomAnimationEffect_search_node_predict::stl_CustomAnimationEffect_search_node_predict( const css::uno::Reference< css::animations::XAnimationNode >& xSearchNode )
|
2004-11-26 18:45:55 +00:00
|
|
|
: mxSearchNode( xSearchNode )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-04-12 11:54:45 +02:00
|
|
|
bool stl_CustomAnimationEffect_search_node_predict::operator()( const CustomAnimationEffectPtr& pEffect ) const
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
return pEffect->getNode() == mxSearchNode;
|
|
|
|
}
|
|
|
|
|
2017-01-19 17:53:18 +01:00
|
|
|
/// @throws Exception
|
2017-08-03 10:23:01 +02:00
|
|
|
static bool implFindNextContainer( Reference< XTimeContainer > const & xParent, Reference< XTimeContainer > const & xCurrent, Reference< XTimeContainer >& xNext )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( xParent, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration() );
|
|
|
|
if( xEnumeration.is() )
|
|
|
|
{
|
|
|
|
Reference< XInterface > x;
|
|
|
|
while( xEnumeration->hasMoreElements() && !xNext.is() )
|
|
|
|
{
|
|
|
|
if( (xEnumeration->nextElement() >>= x) && (x == xCurrent) )
|
|
|
|
{
|
|
|
|
if( xEnumeration->hasMoreElements() )
|
|
|
|
xEnumeration->nextElement() >>= xNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return xNext.is();
|
|
|
|
}
|
|
|
|
|
2017-08-03 10:23:01 +02:00
|
|
|
void stl_process_after_effect_node_func(AfterEffectNode const & rNode)
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if( rNode.mxNode.is() && rNode.mxMaster.is() )
|
|
|
|
{
|
|
|
|
// set master node
|
|
|
|
Reference< XAnimationNode > xMasterNode( rNode.mxMaster, UNO_QUERY_THROW );
|
|
|
|
Sequence< NamedValue > aUserData( rNode.mxNode->getUserData() );
|
|
|
|
sal_Int32 nSize = aUserData.getLength();
|
|
|
|
aUserData.realloc(nSize+1);
|
2012-04-15 23:14:28 -03:00
|
|
|
aUserData[nSize].Name = "master-element";
|
2004-11-26 18:45:55 +00:00
|
|
|
aUserData[nSize].Value <<= xMasterNode;
|
|
|
|
rNode.mxNode->setUserData( aUserData );
|
|
|
|
|
|
|
|
// insert after effect node into timeline
|
|
|
|
Reference< XTimeContainer > xContainer( rNode.mxMaster->getParent(), UNO_QUERY_THROW );
|
|
|
|
|
2005-09-23 09:41:40 +00:00
|
|
|
if( !rNode.mbOnNextEffect ) // sameClick
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
// insert the aftereffect after its effect is animated
|
|
|
|
xContainer->insertAfter( rNode.mxNode, rNode.mxMaster );
|
|
|
|
}
|
|
|
|
else // nextClick
|
|
|
|
{
|
2013-04-25 14:43:24 +02:00
|
|
|
Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
|
2004-11-26 18:45:55 +00:00
|
|
|
// insert the aftereffect in the next group
|
|
|
|
|
|
|
|
Reference< XTimeContainer > xClickContainer( xContainer->getParent(), UNO_QUERY_THROW );
|
|
|
|
Reference< XTimeContainer > xSequenceContainer( xClickContainer->getParent(), UNO_QUERY_THROW );
|
|
|
|
|
|
|
|
Reference< XTimeContainer > xNextContainer;
|
|
|
|
|
|
|
|
// first try if we have an after effect container
|
|
|
|
if( !implFindNextContainer( xClickContainer, xContainer, xNextContainer ) )
|
|
|
|
{
|
|
|
|
Reference< XTimeContainer > xNextClickContainer;
|
|
|
|
// if not, try to find the next click effect container
|
|
|
|
if( implFindNextContainer( xSequenceContainer, xClickContainer, xNextClickContainer ) )
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( xNextClickContainer, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
if( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
// the next container is the first child container
|
|
|
|
xEnumeration->nextElement() >>= xNextContainer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// this does not yet have a child container, create one
|
2013-04-25 14:43:24 +02:00
|
|
|
xNextContainer.set( ParallelTimeContainer::create(xContext), UNO_QUERY_THROW );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2017-04-06 08:59:07 +02:00
|
|
|
xNextContainer->setBegin( makeAny( 0.0 ) );
|
2013-05-02 10:36:43 +02:00
|
|
|
xNextClickContainer->appendChild( xNextContainer );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
DBG_ASSERT( xNextContainer.is(), "ppt::stl_process_after_effect_node_func::operator(), could not find/create container!" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if we don't have a next container, we add one to the sequence container
|
|
|
|
if( !xNextContainer.is() )
|
|
|
|
{
|
2013-04-25 14:43:24 +02:00
|
|
|
Reference< XTimeContainer > xNewClickContainer( ParallelTimeContainer::create( xContext ), UNO_QUERY_THROW );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
Event aEvent;
|
|
|
|
aEvent.Trigger = EventTrigger::ON_NEXT;
|
|
|
|
aEvent.Repeat = 0;
|
2013-05-02 10:36:43 +02:00
|
|
|
xNewClickContainer->setBegin( makeAny( aEvent ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2013-05-02 10:36:43 +02:00
|
|
|
xSequenceContainer->insertAfter( xNewClickContainer, xClickContainer );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2013-04-25 14:43:24 +02:00
|
|
|
xNextContainer.set( ParallelTimeContainer::create( xContext ), UNO_QUERY_THROW );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2018-06-07 13:03:58 +02:00
|
|
|
xNextContainer->setBegin( makeAny( 0.0 ) );
|
|
|
|
xNewClickContainer->appendChild( xNextContainer );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( xNextContainer.is() )
|
|
|
|
{
|
2005-09-23 09:41:40 +00:00
|
|
|
// find begin time of first element
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( xNextContainer, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
if( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChild;
|
|
|
|
// the next container is the first child container
|
|
|
|
xEnumeration->nextElement() >>= xChild;
|
|
|
|
if( xChild.is() )
|
|
|
|
{
|
|
|
|
Any aBegin( xChild->getBegin() );
|
2007-01-09 10:20:51 +00:00
|
|
|
double fBegin = 0.0;
|
2005-09-23 09:41:40 +00:00
|
|
|
if( (aBegin >>= fBegin) && (fBegin >= 0.0))
|
|
|
|
rNode.mxNode->setBegin( aBegin );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
xNextContainer->appendChild( rNode.mxNode );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "ppt::stl_process_after_effect_node_func::operator(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EffectSequence::iterator EffectSequenceHelper::find( const CustomAnimationEffectPtr& pEffect )
|
|
|
|
{
|
|
|
|
return std::find( maEffects.begin(), maEffects.end(), pEffect );
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
CustomAnimationEffectPtr EffectSequenceHelper::findEffect( const css::uno::Reference< css::animations::XAnimationNode >& xNode ) const
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect;
|
|
|
|
|
|
|
|
EffectSequence::const_iterator aIter( maEffects.begin() );
|
2012-05-19 15:09:08 +02:00
|
|
|
for( ; aIter != maEffects.end(); ++aIter )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
if( (*aIter)->getNode() == xNode )
|
|
|
|
{
|
|
|
|
pEffect = (*aIter);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pEffect;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 EffectSequenceHelper::getOffsetFromEffect( const CustomAnimationEffectPtr& xEffect ) const
|
|
|
|
{
|
|
|
|
sal_Int32 nOffset = 0;
|
|
|
|
|
|
|
|
EffectSequence::const_iterator aIter( maEffects.begin() );
|
2012-05-19 15:09:08 +02:00
|
|
|
for( ; aIter != maEffects.end(); ++aIter, nOffset++ )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
if( (*aIter) == xEffect )
|
|
|
|
return nOffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
CustomAnimationEffectPtr EffectSequenceHelper::getEffectFromOffset( sal_Int32 nOffset ) const
|
|
|
|
{
|
|
|
|
EffectSequence::const_iterator aIter( maEffects.begin() );
|
|
|
|
while( nOffset-- && aIter != maEffects.end() )
|
2012-05-19 15:09:08 +02:00
|
|
|
++aIter;
|
2007-07-06 12:10:13 +00:00
|
|
|
|
|
|
|
CustomAnimationEffectPtr pEffect;
|
|
|
|
if( aIter != maEffects.end() )
|
|
|
|
pEffect = (*aIter);
|
|
|
|
|
|
|
|
return pEffect;
|
|
|
|
}
|
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
bool EffectSequenceHelper::disposeShape( const Reference< XShape >& xShape )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
bool bChanges = false;
|
|
|
|
|
|
|
|
EffectSequence::iterator aIter( maEffects.begin() );
|
|
|
|
while( aIter != maEffects.end() )
|
|
|
|
{
|
|
|
|
if( (*aIter)->getTargetShape() == xShape )
|
|
|
|
{
|
2015-11-10 10:23:02 +01:00
|
|
|
(*aIter)->setEffectSequence( nullptr );
|
2004-11-26 18:45:55 +00:00
|
|
|
bChanges = true;
|
|
|
|
aIter = maEffects.erase( aIter );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-05-19 15:09:08 +02:00
|
|
|
++aIter;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
return bChanges;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
bool EffectSequenceHelper::hasEffect( const css::uno::Reference< css::drawing::XShape >& xShape )
|
2005-01-21 17:17:16 +00:00
|
|
|
{
|
|
|
|
EffectSequence::iterator aIter( maEffects.begin() );
|
|
|
|
while( aIter != maEffects.end() )
|
|
|
|
{
|
|
|
|
if( (*aIter)->getTargetShape() == xShape )
|
|
|
|
return true;
|
2012-05-19 15:09:08 +02:00
|
|
|
++aIter;
|
2005-01-21 17:17:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void EffectSequenceHelper::insertTextRange( const css::uno::Any& aTarget )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-01-25 14:13:53 +00:00
|
|
|
bool bChanges = false;
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
ParagraphTarget aParaTarget;
|
|
|
|
if( !(aTarget >>= aParaTarget ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
EffectSequence::iterator aIter( maEffects.begin() );
|
|
|
|
while( aIter != maEffects.end() )
|
|
|
|
{
|
|
|
|
if( (*aIter)->getTargetShape() == aParaTarget.Shape )
|
2005-01-25 14:13:53 +00:00
|
|
|
bChanges |= (*aIter)->checkForText();
|
2012-05-19 15:09:08 +02:00
|
|
|
++aIter;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
2005-01-25 14:13:53 +00:00
|
|
|
|
|
|
|
if( bChanges )
|
|
|
|
rebuild();
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void EffectSequenceHelper::disposeTextRange( const css::uno::Any& aTarget )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
ParagraphTarget aParaTarget;
|
|
|
|
if( !(aTarget >>= aParaTarget ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
bool bChanges = false;
|
|
|
|
bool bErased = false;
|
|
|
|
|
|
|
|
EffectSequence::iterator aIter( maEffects.begin() );
|
|
|
|
while( aIter != maEffects.end() )
|
|
|
|
{
|
|
|
|
Any aIterTarget( (*aIter)->getTarget() );
|
2014-05-10 00:14:44 +02:00
|
|
|
if( aIterTarget.getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
ParagraphTarget aIterParaTarget;
|
|
|
|
if( (aIterTarget >>= aIterParaTarget) && (aIterParaTarget.Shape == aParaTarget.Shape) )
|
|
|
|
{
|
|
|
|
if( aIterParaTarget.Paragraph == aParaTarget.Paragraph )
|
|
|
|
{
|
|
|
|
// delete this effect if it targets the disposed paragraph directly
|
2015-11-10 10:23:02 +01:00
|
|
|
(*aIter)->setEffectSequence( nullptr );
|
2004-11-26 18:45:55 +00:00
|
|
|
aIter = maEffects.erase( aIter );
|
|
|
|
bChanges = true;
|
|
|
|
bErased = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( aIterParaTarget.Paragraph > aParaTarget.Paragraph )
|
|
|
|
{
|
|
|
|
// shift all paragraphs after disposed paragraph
|
|
|
|
aIterParaTarget.Paragraph--;
|
|
|
|
(*aIter)->setTarget( makeAny( aIterParaTarget ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( (*aIter)->getTargetShape() == aParaTarget.Shape )
|
|
|
|
{
|
2005-01-25 14:13:53 +00:00
|
|
|
bChanges |= (*aIter)->checkForText();
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( bErased )
|
|
|
|
bErased = false;
|
|
|
|
else
|
2012-05-19 15:09:08 +02:00
|
|
|
++aIter;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( bChanges )
|
|
|
|
rebuild();
|
|
|
|
}
|
|
|
|
|
|
|
|
CustomAnimationTextGroup::CustomAnimationTextGroup( const Reference< XShape >& rTarget, sal_Int32 nGroupId )
|
|
|
|
: maTarget( rTarget ),
|
|
|
|
mnGroupId( nGroupId )
|
|
|
|
{
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CustomAnimationTextGroup::reset()
|
|
|
|
{
|
|
|
|
mnTextGrouping = -1;
|
|
|
|
mbAnimateForm = false;
|
|
|
|
mbTextReverse = false;
|
|
|
|
mfGroupingAuto = -1.0;
|
|
|
|
mnLastPara = -1; // used to check for TextReverse
|
|
|
|
|
2016-05-09 13:22:38 +02:00
|
|
|
for (sal_Int8 & rn : mnDepthFlags)
|
2012-05-09 00:14:32 +02:00
|
|
|
{
|
2016-05-09 13:22:38 +02:00
|
|
|
rn = 0;
|
2012-05-09 00:14:32 +02:00
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
maEffects.clear();
|
|
|
|
}
|
|
|
|
|
2017-08-03 10:23:01 +02:00
|
|
|
void CustomAnimationTextGroup::addEffect( CustomAnimationEffectPtr const & pEffect )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
maEffects.push_back( pEffect );
|
|
|
|
|
|
|
|
Any aTarget( pEffect->getTarget() );
|
2014-05-10 00:14:44 +02:00
|
|
|
if( aTarget.getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
// now look at the paragraph
|
|
|
|
ParagraphTarget aParaTarget;
|
|
|
|
aTarget >>= aParaTarget;
|
|
|
|
|
|
|
|
if( mnLastPara != -1 )
|
|
|
|
mbTextReverse = mnLastPara > aParaTarget.Paragraph;
|
|
|
|
|
|
|
|
mnLastPara = aParaTarget.Paragraph;
|
|
|
|
|
|
|
|
const sal_Int32 nParaDepth = pEffect->getParaDepth();
|
|
|
|
|
2012-05-09 00:14:32 +02:00
|
|
|
// only look at the first PARA_LEVELS levels
|
|
|
|
if( nParaDepth < PARA_LEVELS )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
// our first paragraph with this level?
|
|
|
|
if( mnDepthFlags[nParaDepth] == 0 )
|
|
|
|
{
|
|
|
|
// so set it to the first found
|
2018-01-12 20:16:43 +01:00
|
|
|
mnDepthFlags[nParaDepth] = static_cast<sal_Int8>(pEffect->getNodeType());
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
else if( mnDepthFlags[nParaDepth] != pEffect->getNodeType() )
|
|
|
|
{
|
|
|
|
mnDepthFlags[nParaDepth] = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pEffect->getNodeType() == EffectNodeType::AFTER_PREVIOUS )
|
|
|
|
mfGroupingAuto = pEffect->getBegin();
|
|
|
|
|
2012-05-09 00:14:32 +02:00
|
|
|
mnTextGrouping = PARA_LEVELS;
|
|
|
|
while( (mnTextGrouping > 0)
|
|
|
|
&& (mnDepthFlags[mnTextGrouping - 1] <= 0) )
|
|
|
|
--mnTextGrouping;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// if we have an effect with the shape as a target, we animate the background
|
|
|
|
mbAnimateForm = pEffect->getTargetSubItem() != ShapeAnimationSubType::ONLY_TEXT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CustomAnimationTextGroupPtr EffectSequenceHelper::findGroup( sal_Int32 nGroupId )
|
|
|
|
{
|
|
|
|
CustomAnimationTextGroupPtr aPtr;
|
|
|
|
|
|
|
|
CustomAnimationTextGroupMap::iterator aIter( maGroupMap.find( nGroupId ) );
|
|
|
|
if( aIter != maGroupMap.end() )
|
|
|
|
aPtr = (*aIter).second;
|
|
|
|
|
|
|
|
return aPtr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::updateTextGroups()
|
|
|
|
{
|
|
|
|
maGroupMap.clear();
|
|
|
|
|
|
|
|
// first create all the groups
|
|
|
|
EffectSequence::iterator aIter( maEffects.begin() );
|
|
|
|
const EffectSequence::iterator aEnd( maEffects.end() );
|
|
|
|
while( aIter != aEnd )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect( (*aIter++) );
|
|
|
|
|
|
|
|
const sal_Int32 nGroupId = pEffect->getGroupId();
|
|
|
|
|
|
|
|
if( nGroupId == -1 )
|
|
|
|
continue; // trivial case, no group
|
|
|
|
|
|
|
|
CustomAnimationTextGroupPtr pGroup = findGroup( nGroupId );
|
|
|
|
if( !pGroup.get() )
|
|
|
|
{
|
|
|
|
pGroup.reset( new CustomAnimationTextGroup( pEffect->getTargetShape(), nGroupId ) );
|
|
|
|
maGroupMap[nGroupId] = pGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
pGroup->addEffect( pEffect );
|
|
|
|
}
|
2018-06-18 14:27:31 +08:00
|
|
|
|
|
|
|
// Now that all the text groups have been cleared up and rebuilt, we need to update its
|
|
|
|
// text grouping. addEffect() already make mnTextGrouping the last possible level,
|
|
|
|
// so just continue to find the last level that is not EffectNodeType::WITH_PREVIOUS.
|
|
|
|
for(const auto &rGroupMapItem: maGroupMap)
|
|
|
|
{
|
|
|
|
const CustomAnimationTextGroupPtr &pGroup = rGroupMapItem.second;
|
|
|
|
while(pGroup->mnTextGrouping > 0 && pGroup->mnDepthFlags[pGroup->mnTextGrouping - 1] == EffectNodeType::WITH_PREVIOUS)
|
|
|
|
--pGroup->mnTextGrouping;
|
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2018-09-06 08:50:58 +02:00
|
|
|
CustomAnimationTextGroupPtr
|
|
|
|
EffectSequenceHelper::createTextGroup(const CustomAnimationEffectPtr& pEffect,
|
|
|
|
sal_Int32 nTextGrouping, double fTextGroupingAuto,
|
|
|
|
bool bAnimateForm, bool bTextReverse)
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
// first finde a free group-id
|
|
|
|
sal_Int32 nGroupId = 0;
|
|
|
|
|
|
|
|
CustomAnimationTextGroupMap::iterator aIter( maGroupMap.begin() );
|
|
|
|
const CustomAnimationTextGroupMap::iterator aEnd( maGroupMap.end() );
|
|
|
|
while( aIter != aEnd )
|
|
|
|
{
|
|
|
|
if( (*aIter).first == nGroupId )
|
|
|
|
{
|
|
|
|
nGroupId++;
|
|
|
|
aIter = maGroupMap.begin();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-05-19 15:09:08 +02:00
|
|
|
++aIter;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Reference< XShape > xTarget( pEffect->getTargetShape() );
|
|
|
|
|
|
|
|
CustomAnimationTextGroupPtr pTextGroup( new CustomAnimationTextGroup( xTarget, nGroupId ) );
|
|
|
|
maGroupMap[nGroupId] = pTextGroup;
|
|
|
|
|
|
|
|
bool bUsed = false;
|
|
|
|
|
|
|
|
// do we need to target the shape?
|
|
|
|
if( (nTextGrouping == 0) || bAnimateForm )
|
|
|
|
{
|
|
|
|
sal_Int16 nSubItem;
|
|
|
|
if( nTextGrouping == 0)
|
|
|
|
nSubItem = bAnimateForm ? ShapeAnimationSubType::AS_WHOLE : ShapeAnimationSubType::ONLY_TEXT;
|
|
|
|
else
|
|
|
|
nSubItem = ShapeAnimationSubType::ONLY_BACKGROUND;
|
|
|
|
|
|
|
|
pEffect->setTarget( makeAny( xTarget ) );
|
|
|
|
pEffect->setTargetSubItem( nSubItem );
|
|
|
|
pEffect->setEffectSequence( this );
|
|
|
|
pEffect->setGroupId( nGroupId );
|
|
|
|
|
|
|
|
pTextGroup->addEffect( pEffect );
|
|
|
|
bUsed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
pTextGroup->mnTextGrouping = nTextGrouping;
|
|
|
|
pTextGroup->mfGroupingAuto = fTextGroupingAuto;
|
|
|
|
pTextGroup->mbTextReverse = bTextReverse;
|
|
|
|
|
|
|
|
// now add an effect for each paragraph
|
|
|
|
createTextGroupParagraphEffects( pTextGroup, pEffect, bUsed );
|
|
|
|
|
|
|
|
notify_listeners();
|
|
|
|
|
|
|
|
return pTextGroup;
|
|
|
|
}
|
|
|
|
|
2016-04-12 11:54:45 +02:00
|
|
|
void EffectSequenceHelper::createTextGroupParagraphEffects( const CustomAnimationTextGroupPtr& pTextGroup, const CustomAnimationEffectPtr& pEffect, bool bUsed )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
Reference< XShape > xTarget( pTextGroup->maTarget );
|
|
|
|
|
|
|
|
sal_Int32 nTextGrouping = pTextGroup->mnTextGrouping;
|
|
|
|
double fTextGroupingAuto = pTextGroup->mfGroupingAuto;
|
2014-04-24 10:52:02 +02:00
|
|
|
bool bTextReverse = pTextGroup->mbTextReverse;
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
// now add an effect for each paragraph
|
|
|
|
if( nTextGrouping >= 0 ) try
|
|
|
|
{
|
|
|
|
EffectSequence::iterator aInsertIter( find( pEffect ) );
|
|
|
|
|
|
|
|
Reference< XEnumerationAccess > xText( xTarget, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xText->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
|
2016-09-01 09:28:58 +02:00
|
|
|
std::deque< sal_Int16 > aParaList;
|
2005-03-30 09:29:19 +00:00
|
|
|
sal_Int16 nPara;
|
|
|
|
|
|
|
|
// fill the list with all valid paragraphs
|
|
|
|
for( nPara = 0; xEnumeration->hasMoreElements(); nPara++ )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-03-30 09:29:19 +00:00
|
|
|
Reference< XTextRange > xRange( xEnumeration->nextElement(), UNO_QUERY );
|
2012-01-08 09:52:25 -02:00
|
|
|
if( xRange.is() && !xRange->getString().isEmpty() )
|
2005-03-30 09:29:19 +00:00
|
|
|
{
|
|
|
|
if( bTextReverse ) // sort them
|
|
|
|
aParaList.push_front( nPara );
|
|
|
|
else
|
|
|
|
aParaList.push_back( nPara );
|
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ParagraphTarget aTarget;
|
|
|
|
aTarget.Shape = xTarget;
|
|
|
|
|
2016-09-01 09:28:58 +02:00
|
|
|
for( const auto i : aParaList )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2016-09-01 09:28:58 +02:00
|
|
|
aTarget.Paragraph = i;
|
2005-03-30 09:29:19 +00:00
|
|
|
|
|
|
|
CustomAnimationEffectPtr pNewEffect;
|
|
|
|
if( bUsed )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-03-30 09:29:19 +00:00
|
|
|
// clone a new effect from first effect
|
|
|
|
pNewEffect = pEffect->clone();
|
|
|
|
++aInsertIter;
|
|
|
|
aInsertIter = maEffects.insert( aInsertIter, pNewEffect );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-10-01 15:45:53 +02:00
|
|
|
// reuse first effect if it's not yet used
|
2005-03-30 09:29:19 +00:00
|
|
|
pNewEffect = pEffect;
|
|
|
|
bUsed = true;
|
|
|
|
aInsertIter = find( pNewEffect );
|
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2005-03-30 09:29:19 +00:00
|
|
|
// set target and group-id
|
|
|
|
pNewEffect->setTarget( makeAny( aTarget ) );
|
|
|
|
pNewEffect->setTargetSubItem( ShapeAnimationSubType::ONLY_TEXT );
|
|
|
|
pNewEffect->setGroupId( pTextGroup->mnGroupId );
|
|
|
|
pNewEffect->setEffectSequence( this );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2005-03-30 09:29:19 +00:00
|
|
|
// set correct node type
|
|
|
|
if( pNewEffect->getParaDepth() < nTextGrouping )
|
|
|
|
{
|
|
|
|
if( fTextGroupingAuto == -1.0 )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-03-30 09:29:19 +00:00
|
|
|
pNewEffect->setNodeType( EffectNodeType::ON_CLICK );
|
2004-11-26 18:45:55 +00:00
|
|
|
pNewEffect->setBegin( 0.0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-03-30 09:29:19 +00:00
|
|
|
pNewEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
|
|
|
|
pNewEffect->setBegin( fTextGroupingAuto );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-30 09:29:19 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
pNewEffect->setNodeType( EffectNodeType::WITH_PREVIOUS );
|
|
|
|
pNewEffect->setBegin( 0.0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
pTextGroup->addEffect( pNewEffect );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
notify_listeners();
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL("sd::EffectSequenceHelper::createTextGroup(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-12 11:54:45 +02:00
|
|
|
void EffectSequenceHelper::setTextGrouping( const CustomAnimationTextGroupPtr& pTextGroup, sal_Int32 nTextGrouping )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
if( pTextGroup->mnTextGrouping == nTextGrouping )
|
|
|
|
{
|
|
|
|
// first case, trivial case, do nothing
|
|
|
|
}
|
|
|
|
else if( (pTextGroup->mnTextGrouping == -1) && (nTextGrouping >= 0) )
|
|
|
|
{
|
|
|
|
// second case, we need to add new effects for each paragraph
|
|
|
|
|
|
|
|
CustomAnimationEffectPtr pEffect( pTextGroup->maEffects.front() );
|
|
|
|
|
|
|
|
pTextGroup->mnTextGrouping = nTextGrouping;
|
|
|
|
createTextGroupParagraphEffects( pTextGroup, pEffect, true );
|
|
|
|
notify_listeners();
|
|
|
|
}
|
|
|
|
else if( (pTextGroup->mnTextGrouping >= 0) && (nTextGrouping == -1 ) )
|
|
|
|
{
|
|
|
|
// third case, we need to remove effects for each paragraph
|
|
|
|
|
|
|
|
EffectSequence aEffects( pTextGroup->maEffects );
|
|
|
|
pTextGroup->reset();
|
|
|
|
|
|
|
|
EffectSequence::iterator aIter( aEffects.begin() );
|
|
|
|
const EffectSequence::iterator aEnd( aEffects.end() );
|
|
|
|
while( aIter != aEnd )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect( (*aIter++) );
|
|
|
|
|
2014-05-10 00:14:44 +02:00
|
|
|
if( pEffect->getTarget().getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
remove( pEffect );
|
|
|
|
else
|
|
|
|
pTextGroup->addEffect( pEffect );
|
|
|
|
}
|
|
|
|
notify_listeners();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// fourth case, we need to change the node types for the text nodes
|
|
|
|
double fTextGroupingAuto = pTextGroup->mfGroupingAuto;
|
|
|
|
|
|
|
|
EffectSequence aEffects( pTextGroup->maEffects );
|
|
|
|
pTextGroup->reset();
|
|
|
|
|
|
|
|
EffectSequence::iterator aIter( aEffects.begin() );
|
|
|
|
const EffectSequence::iterator aEnd( aEffects.end() );
|
|
|
|
while( aIter != aEnd )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect( (*aIter++) );
|
|
|
|
|
2014-05-10 00:14:44 +02:00
|
|
|
if( pEffect->getTarget().getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
// set correct node type
|
|
|
|
if( pEffect->getParaDepth() < nTextGrouping )
|
|
|
|
{
|
|
|
|
if( fTextGroupingAuto == -1.0 )
|
|
|
|
{
|
|
|
|
pEffect->setNodeType( EffectNodeType::ON_CLICK );
|
|
|
|
pEffect->setBegin( 0.0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
|
|
|
|
pEffect->setBegin( fTextGroupingAuto );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pEffect->setNodeType( EffectNodeType::WITH_PREVIOUS );
|
|
|
|
pEffect->setBegin( 0.0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pTextGroup->addEffect( pEffect );
|
|
|
|
|
|
|
|
}
|
|
|
|
notify_listeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-12 11:54:45 +02:00
|
|
|
void EffectSequenceHelper::setAnimateForm( const CustomAnimationTextGroupPtr& pTextGroup, bool bAnimateForm )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
if( pTextGroup->mbAnimateForm == bAnimateForm )
|
|
|
|
{
|
|
|
|
// trivial case, do nothing
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
EffectSequence aEffects( pTextGroup->maEffects );
|
|
|
|
pTextGroup->reset();
|
|
|
|
|
2012-07-05 21:08:09 +01:00
|
|
|
SAL_WARN_IF(aEffects.empty(), "sd", "EffectSequenceHelper::setAnimateForm effects empty" );
|
|
|
|
|
|
|
|
if (aEffects.empty())
|
|
|
|
return;
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
EffectSequence::iterator aIter( aEffects.begin() );
|
|
|
|
const EffectSequence::iterator aEnd( aEffects.end() );
|
|
|
|
|
|
|
|
// first insert if we have to
|
|
|
|
if( bAnimateForm )
|
|
|
|
{
|
2017-07-07 08:42:54 +02:00
|
|
|
EffectSequence::iterator aInsertIter( find( *aIter ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
CustomAnimationEffectPtr pEffect;
|
2014-05-10 00:14:44 +02:00
|
|
|
if( (aEffects.size() == 1) && ((*aIter)->getTarget().getValueType() != ::cppu::UnoType<ParagraphTarget>::get() ) )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
// special case, only one effect and that targets whole text,
|
|
|
|
// convert this to target whole shape
|
|
|
|
pEffect = (*aIter++);
|
|
|
|
pEffect->setTargetSubItem( ShapeAnimationSubType::AS_WHOLE );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pEffect = (*aIter)->clone();
|
|
|
|
pEffect->setTarget( makeAny( (*aIter)->getTargetShape() ) );
|
|
|
|
pEffect->setTargetSubItem( ShapeAnimationSubType::ONLY_BACKGROUND );
|
|
|
|
maEffects.insert( aInsertIter, pEffect );
|
|
|
|
}
|
|
|
|
|
|
|
|
pTextGroup->addEffect( pEffect );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !bAnimateForm && (aEffects.size() == 1) )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect( (*aIter) );
|
|
|
|
pEffect->setTarget( makeAny( (*aIter)->getTargetShape() ) );
|
|
|
|
pEffect->setTargetSubItem( ShapeAnimationSubType::ONLY_TEXT );
|
|
|
|
pTextGroup->addEffect( pEffect );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-09-29 17:58:05 +02:00
|
|
|
// read the rest to the group again
|
2004-11-26 18:45:55 +00:00
|
|
|
while( aIter != aEnd )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect( (*aIter++) );
|
|
|
|
|
2014-05-10 00:14:44 +02:00
|
|
|
if( pEffect->getTarget().getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
pTextGroup->addEffect( pEffect );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DBG_ASSERT( !bAnimateForm, "sd::EffectSequenceHelper::setAnimateForm(), something is wrong here!" );
|
|
|
|
remove( pEffect );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
notify_listeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-12 11:54:45 +02:00
|
|
|
void EffectSequenceHelper::setTextGroupingAuto( const CustomAnimationTextGroupPtr& pTextGroup, double fTextGroupingAuto )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
sal_Int32 nTextGrouping = pTextGroup->mnTextGrouping;
|
|
|
|
|
|
|
|
EffectSequence aEffects( pTextGroup->maEffects );
|
|
|
|
pTextGroup->reset();
|
|
|
|
|
|
|
|
EffectSequence::iterator aIter( aEffects.begin() );
|
|
|
|
const EffectSequence::iterator aEnd( aEffects.end() );
|
|
|
|
while( aIter != aEnd )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect( (*aIter++) );
|
|
|
|
|
2014-05-10 00:14:44 +02:00
|
|
|
if( pEffect->getTarget().getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
// set correct node type
|
|
|
|
if( pEffect->getParaDepth() < nTextGrouping )
|
|
|
|
{
|
|
|
|
if( fTextGroupingAuto == -1.0 )
|
|
|
|
{
|
|
|
|
pEffect->setNodeType( EffectNodeType::ON_CLICK );
|
|
|
|
pEffect->setBegin( 0.0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
|
|
|
|
pEffect->setBegin( fTextGroupingAuto );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pEffect->setNodeType( EffectNodeType::WITH_PREVIOUS );
|
|
|
|
pEffect->setBegin( 0.0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pTextGroup->addEffect( pEffect );
|
|
|
|
|
|
|
|
}
|
|
|
|
notify_listeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ImplStlTextGroupSortHelper
|
|
|
|
{
|
2015-10-25 17:33:13 +02:00
|
|
|
explicit ImplStlTextGroupSortHelper( bool bReverse ) : mbReverse( bReverse ) {};
|
2004-11-26 18:45:55 +00:00
|
|
|
bool operator()( const CustomAnimationEffectPtr& p1, const CustomAnimationEffectPtr& p2 );
|
2018-10-08 16:12:06 +02:00
|
|
|
bool const mbReverse;
|
2004-11-26 18:45:55 +00:00
|
|
|
sal_Int32 getTargetParagraph( const CustomAnimationEffectPtr& p1 );
|
|
|
|
};
|
|
|
|
|
|
|
|
sal_Int32 ImplStlTextGroupSortHelper::getTargetParagraph( const CustomAnimationEffectPtr& p1 )
|
|
|
|
{
|
|
|
|
const Any aTarget(p1->getTarget());
|
2014-05-10 00:14:44 +02:00
|
|
|
if( aTarget.hasValue() && aTarget.getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
ParagraphTarget aParaTarget;
|
|
|
|
aTarget >>= aParaTarget;
|
|
|
|
return aParaTarget.Paragraph;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return mbReverse ? 0x7fffffff : -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ImplStlTextGroupSortHelper::operator()( const CustomAnimationEffectPtr& p1, const CustomAnimationEffectPtr& p2 )
|
|
|
|
{
|
|
|
|
if( mbReverse )
|
|
|
|
{
|
|
|
|
return getTargetParagraph( p2 ) < getTargetParagraph( p1 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return getTargetParagraph( p1 ) < getTargetParagraph( p2 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-12 11:54:45 +02:00
|
|
|
void EffectSequenceHelper::setTextReverse( const CustomAnimationTextGroupPtr& pTextGroup, bool bTextReverse )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
if( pTextGroup->mbTextReverse == bTextReverse )
|
|
|
|
{
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::vector< CustomAnimationEffectPtr > aSortedVector(pTextGroup->maEffects.size());
|
|
|
|
std::copy( pTextGroup->maEffects.begin(), pTextGroup->maEffects.end(), aSortedVector.begin() );
|
|
|
|
ImplStlTextGroupSortHelper aSortHelper( bTextReverse );
|
|
|
|
std::sort( aSortedVector.begin(), aSortedVector.end(), aSortHelper );
|
|
|
|
|
|
|
|
pTextGroup->reset();
|
|
|
|
|
|
|
|
std::vector< CustomAnimationEffectPtr >::iterator aIter( aSortedVector.begin() );
|
|
|
|
const std::vector< CustomAnimationEffectPtr >::iterator aEnd( aSortedVector.end() );
|
|
|
|
|
|
|
|
if( aIter != aEnd )
|
|
|
|
{
|
2017-07-07 08:42:54 +02:00
|
|
|
pTextGroup->addEffect( *aIter );
|
|
|
|
EffectSequence::iterator aInsertIter( find( *aIter++ ) );
|
2004-11-26 18:45:55 +00:00
|
|
|
while( aIter != aEnd )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect( (*aIter++) );
|
|
|
|
maEffects.erase( find( pEffect ) );
|
|
|
|
aInsertIter = maEffects.insert( ++aInsertIter, pEffect );
|
|
|
|
pTextGroup->addEffect( pEffect );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
notify_listeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::addListener( ISequenceListener* pListener )
|
|
|
|
{
|
|
|
|
if( std::find( maListeners.begin(), maListeners.end(), pListener ) == maListeners.end() )
|
|
|
|
maListeners.push_back( pListener );
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::removeListener( ISequenceListener* pListener )
|
|
|
|
{
|
|
|
|
maListeners.remove( pListener );
|
|
|
|
}
|
|
|
|
|
2017-06-28 21:48:22 +02:00
|
|
|
struct stl_notify_listeners_func
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2006-12-12 15:29:01 +00:00
|
|
|
stl_notify_listeners_func() {}
|
2004-11-26 18:45:55 +00:00
|
|
|
void operator()(ISequenceListener* pListener) { pListener->notify_change(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
void EffectSequenceHelper::notify_listeners()
|
|
|
|
{
|
|
|
|
stl_notify_listeners_func aFunc;
|
|
|
|
std::for_each( maListeners.begin(), maListeners.end(), aFunc );
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void EffectSequenceHelper::create( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT( xNode.is(), "sd::EffectSequenceHelper::create(), illegal argument" );
|
|
|
|
|
|
|
|
if( xNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
|
|
createEffectsequence( xChildNode );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::EffectSequenceHelper::create(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::createEffectsequence( const Reference< XAnimationNode >& xNode )
|
|
|
|
{
|
|
|
|
DBG_ASSERT( xNode.is(), "sd::EffectSequenceHelper::createEffectsequence(), illegal argument" );
|
|
|
|
|
|
|
|
if( xNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
|
|
|
|
|
|
createEffects( xChildNode );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::EffectSequenceHelper::createEffectsequence(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::createEffects( const Reference< XAnimationNode >& xNode )
|
|
|
|
{
|
|
|
|
DBG_ASSERT( xNode.is(), "sd::EffectSequenceHelper::createEffects(), illegal argument" );
|
|
|
|
|
|
|
|
if( xNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
|
|
|
|
|
|
switch( xChildNode->getType() )
|
|
|
|
{
|
|
|
|
// found an effect
|
|
|
|
case AnimationNodeType::PAR:
|
|
|
|
case AnimationNodeType::ITERATE:
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xChildNode ) );
|
|
|
|
|
|
|
|
if( pEffect->mnNodeType != -1 )
|
|
|
|
{
|
|
|
|
pEffect->setEffectSequence( this );
|
|
|
|
maEffects.push_back(pEffect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
// found an after effect
|
|
|
|
case AnimationNodeType::SET:
|
|
|
|
case AnimationNodeType::ANIMATECOLOR:
|
|
|
|
{
|
|
|
|
processAfterEffect( xChildNode );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::EffectSequenceHelper::createEffects(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::processAfterEffect( const Reference< XAnimationNode >& xNode )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xMaster;
|
|
|
|
|
|
|
|
Sequence< NamedValue > aUserData( xNode->getUserData() );
|
|
|
|
sal_Int32 nLength = aUserData.getLength();
|
|
|
|
const NamedValue* p = aUserData.getConstArray();
|
|
|
|
|
|
|
|
while( nLength-- )
|
|
|
|
{
|
2012-04-06 14:28:18 +02:00
|
|
|
if ( p->Name == "master-element" )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
p->Value >>= xMaster;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// only process if this is a valid after effect
|
|
|
|
if( xMaster.is() )
|
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pMasterEffect;
|
|
|
|
|
|
|
|
// find the master effect
|
|
|
|
stl_CustomAnimationEffect_search_node_predict aSearchPredict( xMaster );
|
|
|
|
EffectSequence::iterator aIter( std::find_if( maEffects.begin(), maEffects.end(), aSearchPredict ) );
|
|
|
|
if( aIter != maEffects.end() )
|
|
|
|
pMasterEffect = (*aIter );
|
|
|
|
|
|
|
|
if( pMasterEffect.get() )
|
|
|
|
{
|
|
|
|
pMasterEffect->setHasAfterEffect( true );
|
|
|
|
|
|
|
|
// find out what kind of after effect this is
|
|
|
|
if( xNode->getType() == AnimationNodeType::ANIMATECOLOR )
|
|
|
|
{
|
2013-09-26 11:44:54 +02:00
|
|
|
// it's a dim
|
2004-11-26 18:45:55 +00:00
|
|
|
Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW );
|
|
|
|
pMasterEffect->setDimColor( xAnimate->getTo() );
|
2005-09-23 09:41:40 +00:00
|
|
|
pMasterEffect->setAfterEffectOnNext( true );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-09-26 11:44:54 +02:00
|
|
|
// it's a hide
|
2013-05-02 10:36:43 +02:00
|
|
|
pMasterEffect->setAfterEffectOnNext( xNode->getParent() != xMaster->getParent() );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::EffectSequenceHelper::processAfterEffect(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-30 21:24:35 +09:00
|
|
|
class AnimationChangeListener : public cppu::WeakImplHelper< XChangesListener >
|
2005-03-01 16:29:57 +00:00
|
|
|
{
|
|
|
|
public:
|
2015-10-25 17:33:13 +02:00
|
|
|
explicit AnimationChangeListener( MainSequence* pMainSequence ) : mpMainSequence( pMainSequence ) {}
|
2005-03-01 16:29:57 +00:00
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
virtual void SAL_CALL changesOccurred( const css::util::ChangesEvent& Event ) override;
|
|
|
|
virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
|
2005-03-01 16:29:57 +00:00
|
|
|
private:
|
|
|
|
MainSequence* mpMainSequence;
|
|
|
|
};
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL AnimationChangeListener::changesOccurred( const css::util::ChangesEvent& )
|
2005-03-01 16:29:57 +00:00
|
|
|
{
|
|
|
|
if( mpMainSequence )
|
|
|
|
mpMainSequence->startRecreateTimer();
|
|
|
|
}
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL AnimationChangeListener::disposing( const css::lang::EventObject& )
|
2005-03-01 16:29:57 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
MainSequence::MainSequence()
|
2014-04-15 20:24:45 +01:00
|
|
|
: mxTimingRootNode(SequenceTimeContainer::create(::comphelper::getProcessComponentContext()))
|
|
|
|
, mbTimerMode(false)
|
|
|
|
, mbRebuilding( false )
|
|
|
|
, mnRebuildLockGuard( 0 )
|
|
|
|
, mbPendingRebuildRequest( false )
|
|
|
|
, mbIgnoreChanges( 0 )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-03-01 16:29:57 +00:00
|
|
|
if( mxTimingRootNode.is() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2015-10-28 12:01:32 +02:00
|
|
|
Sequence< css::beans::NamedValue > aUserData
|
2015-10-28 13:55:01 +02:00
|
|
|
{ { "node-type", css::uno::makeAny(css::presentation::EffectNodeType::MAIN_SEQUENCE) } };
|
2005-03-01 16:29:57 +00:00
|
|
|
mxTimingRootNode->setUserData( aUserData );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
2005-03-01 16:29:57 +00:00
|
|
|
init();
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
MainSequence::MainSequence( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
|
2014-04-15 20:25:29 +01:00
|
|
|
: mxTimingRootNode( xNode, UNO_QUERY )
|
|
|
|
, mbTimerMode( false )
|
|
|
|
, mbRebuilding( false )
|
|
|
|
, mnRebuildLockGuard( 0 )
|
|
|
|
, mbPendingRebuildRequest( false )
|
|
|
|
, mbIgnoreChanges( 0 )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-03-01 16:29:57 +00:00
|
|
|
init();
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
MainSequence::~MainSequence()
|
|
|
|
{
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainSequence::init()
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
mnSequenceType = EffectNodeType::MAIN_SEQUENCE;
|
|
|
|
|
2017-01-23 19:37:51 +01:00
|
|
|
maTimer.SetInvokeHandler( LINK(this, MainSequence, onTimerHdl) );
|
2018-09-26 10:19:11 -07:00
|
|
|
maTimer.SetTimeout(50);
|
2005-03-01 16:29:57 +00:00
|
|
|
|
|
|
|
mxChangesListener.set( new AnimationChangeListener( this ) );
|
|
|
|
|
2006-12-12 15:29:01 +00:00
|
|
|
createMainSequence();
|
2005-03-01 16:29:57 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void MainSequence::reset( const css::uno::Reference< css::animations::XAnimationNode >& xTimingRootNode )
|
2005-03-01 16:29:57 +00:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
|
|
|
|
mxTimingRootNode.set( xTimingRootNode, UNO_QUERY );
|
|
|
|
|
2006-12-12 15:29:01 +00:00
|
|
|
createMainSequence();
|
2005-03-01 16:29:57 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
Reference< css::animations::XAnimationNode > MainSequence::getRootNode()
|
2005-03-01 16:29:57 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
DBG_ASSERT( mnRebuildLockGuard == 0, "MainSequence::getRootNode(), rebuild is locked, is this really what you want?" );
|
2005-03-01 16:29:57 +00:00
|
|
|
|
|
|
|
if( maTimer.IsActive() && mbTimerMode )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-03-01 16:29:57 +00:00
|
|
|
// force a rebuild NOW if one is pending
|
|
|
|
maTimer.Stop();
|
|
|
|
implRebuild();
|
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
return EffectSequenceHelper::getRootNode();
|
|
|
|
}
|
|
|
|
|
2006-12-12 15:29:01 +00:00
|
|
|
void MainSequence::createMainSequence()
|
2005-03-01 16:29:57 +00:00
|
|
|
{
|
|
|
|
if( mxTimingRootNode.is() ) try
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxTimingRootNode, UNO_QUERY_THROW );
|
2004-11-26 18:45:55 +00:00
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
|
|
sal_Int32 nNodeType = CustomAnimationEffect::get_node_type( xChildNode );
|
|
|
|
if( nNodeType == EffectNodeType::MAIN_SEQUENCE )
|
|
|
|
{
|
|
|
|
mxSequenceRoot.set( xChildNode, UNO_QUERY );
|
2005-03-01 16:29:57 +00:00
|
|
|
EffectSequenceHelper::create( xChildNode );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
else if( nNodeType == EffectNodeType::INTERACTIVE_SEQUENCE )
|
|
|
|
{
|
|
|
|
Reference< XTimeContainer > xInteractiveRoot( xChildNode, UNO_QUERY_THROW );
|
|
|
|
InteractiveSequencePtr pIS( new InteractiveSequence( xInteractiveRoot, this ) );
|
|
|
|
pIS->addListener( this );
|
2017-11-11 21:07:56 +01:00
|
|
|
maInteractiveSequenceVector.push_back( pIS );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// see if we have a mainsequence at all. if not, create one...
|
|
|
|
if( !mxSequenceRoot.is() )
|
|
|
|
{
|
2013-02-04 10:20:53 +02:00
|
|
|
mxSequenceRoot = SequenceTimeContainer::create( ::comphelper::getProcessComponentContext() );
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
uno::Sequence< css::beans::NamedValue > aUserData
|
2015-10-28 13:55:01 +02:00
|
|
|
{ { "node-type", css::uno::makeAny(css::presentation::EffectNodeType::MAIN_SEQUENCE) } };
|
2013-02-04 10:20:53 +02:00
|
|
|
mxSequenceRoot->setUserData( aUserData );
|
|
|
|
|
|
|
|
// empty sequence until now, set duration to 0.0
|
|
|
|
// explicitly (otherwise, this sequence will never
|
|
|
|
// end)
|
2017-04-06 08:59:07 +02:00
|
|
|
mxSequenceRoot->setDuration( makeAny(0.0) );
|
2013-02-04 10:20:53 +02:00
|
|
|
|
|
|
|
Reference< XAnimationNode > xMainSequenceNode( mxSequenceRoot, UNO_QUERY_THROW );
|
|
|
|
mxTimingRootNode->appendChild( xMainSequenceNode );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
updateTextGroups();
|
|
|
|
|
|
|
|
notify_listeners();
|
2005-03-01 16:29:57 +00:00
|
|
|
|
|
|
|
Reference< XChangesNotifier > xNotifier( mxTimingRootNode, UNO_QUERY );
|
|
|
|
if( xNotifier.is() )
|
|
|
|
xNotifier->addChangesListener( mxChangesListener );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::MainSequence::create(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
DBG_ASSERT( mxSequenceRoot.is(), "sd::MainSequence::create(), found no main sequence!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainSequence::reset()
|
|
|
|
{
|
|
|
|
EffectSequenceHelper::reset();
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& interactiveSequence : maInteractiveSequenceVector)
|
|
|
|
interactiveSequence->reset();
|
|
|
|
maInteractiveSequenceVector.clear();
|
2005-03-01 16:29:57 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Reference< XChangesNotifier > xNotifier( mxTimingRootNode, UNO_QUERY );
|
|
|
|
if( xNotifier.is() )
|
|
|
|
xNotifier->removeChangesListener( mxChangesListener );
|
|
|
|
}
|
|
|
|
catch( Exception& )
|
|
|
|
{
|
2014-02-25 23:45:44 +01:00
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
InteractiveSequencePtr MainSequence::createInteractiveSequence( const css::uno::Reference< css::drawing::XShape >& xShape )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
InteractiveSequencePtr pIS;
|
|
|
|
|
|
|
|
// create a new interactive sequence container
|
2013-02-04 10:20:53 +02:00
|
|
|
Reference< XTimeContainer > xISRoot = SequenceTimeContainer::create( ::comphelper::getProcessComponentContext() );
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
uno::Sequence< css::beans::NamedValue > aUserData
|
2015-10-28 13:55:01 +02:00
|
|
|
{ { "node-type", css::uno::makeAny(css::presentation::EffectNodeType::INTERACTIVE_SEQUENCE) } };
|
2013-02-04 10:20:53 +02:00
|
|
|
xISRoot->setUserData( aUserData );
|
|
|
|
|
|
|
|
Reference< XChild > xChild( mxSequenceRoot, UNO_QUERY_THROW );
|
|
|
|
Reference< XTimeContainer > xParent( xChild->getParent(), UNO_QUERY_THROW );
|
2013-05-02 10:36:43 +02:00
|
|
|
xParent->appendChild( xISRoot );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
pIS.reset( new InteractiveSequence( xISRoot, this) );
|
|
|
|
pIS->setTriggerShape( xShape );
|
|
|
|
pIS->addListener( this );
|
2017-11-11 21:07:56 +01:00
|
|
|
maInteractiveSequenceVector.push_back( pIS );
|
2004-11-26 18:45:55 +00:00
|
|
|
return pIS;
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
CustomAnimationEffectPtr MainSequence::findEffect( const css::uno::Reference< css::animations::XAnimationNode >& xNode ) const
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
|
|
|
CustomAnimationEffectPtr pEffect = EffectSequenceHelper::findEffect( xNode );
|
|
|
|
|
2015-11-10 10:23:02 +01:00
|
|
|
if( pEffect.get() == nullptr )
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& interactiveSequence : maInteractiveSequenceVector)
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
pEffect = interactiveSequence->findEffect( xNode );
|
|
|
|
if (pEffect.get())
|
|
|
|
break;
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return pEffect;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 MainSequence::getOffsetFromEffect( const CustomAnimationEffectPtr& pEffect ) const
|
|
|
|
{
|
|
|
|
sal_Int32 nOffset = EffectSequenceHelper::getOffsetFromEffect( pEffect );
|
|
|
|
|
|
|
|
if( nOffset != -1 )
|
|
|
|
return nOffset;
|
|
|
|
|
|
|
|
nOffset = EffectSequenceHelper::getCount();
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& interactiveSequence : maInteractiveSequenceVector)
|
2007-07-06 12:10:13 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
sal_Int32 nTemp = interactiveSequence->getOffsetFromEffect( pEffect );
|
2007-07-06 12:10:13 +00:00
|
|
|
if( nTemp != -1 )
|
|
|
|
return nOffset + nTemp;
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
nOffset += interactiveSequence->getCount();
|
2007-07-06 12:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
CustomAnimationEffectPtr MainSequence::getEffectFromOffset( sal_Int32 nOffset ) const
|
|
|
|
{
|
|
|
|
if( nOffset >= 0 )
|
|
|
|
{
|
|
|
|
if( nOffset < getCount() )
|
|
|
|
return EffectSequenceHelper::getEffectFromOffset( nOffset );
|
|
|
|
|
|
|
|
nOffset -= getCount();
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
auto aIter( maInteractiveSequenceVector.begin() );
|
2007-07-06 12:10:13 +00:00
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
while( (aIter != maInteractiveSequenceVector.end()) && (nOffset > (*aIter)->getCount()) )
|
2007-07-06 12:10:13 +00:00
|
|
|
nOffset -= (*aIter++)->getCount();
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
if( (aIter != maInteractiveSequenceVector.end()) && (nOffset >= 0) )
|
2007-07-06 12:10:13 +00:00
|
|
|
return (*aIter)->getEffectFromOffset( nOffset );
|
|
|
|
}
|
|
|
|
|
|
|
|
CustomAnimationEffectPtr pEffect;
|
|
|
|
return pEffect;
|
|
|
|
}
|
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
bool MainSequence::disposeShape( const Reference< XShape >& xShape )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2005-03-01 16:29:57 +00:00
|
|
|
bool bChanges = EffectSequenceHelper::disposeShape( xShape );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& iterativeSequence : maInteractiveSequenceVector)
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
bChanges |= iterativeSequence->disposeShape( xShape );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
2005-03-01 16:29:57 +00:00
|
|
|
|
|
|
|
if( bChanges )
|
|
|
|
startRebuildTimer();
|
|
|
|
|
|
|
|
return bChanges;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
bool MainSequence::hasEffect( const css::uno::Reference< css::drawing::XShape >& xShape )
|
2005-01-21 17:17:16 +00:00
|
|
|
{
|
|
|
|
if( EffectSequenceHelper::hasEffect( xShape ) )
|
|
|
|
return true;
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& iterativeSequence : maInteractiveSequenceVector)
|
2005-01-21 17:17:16 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
if( iterativeSequence->getTriggerShape() == xShape )
|
2005-01-21 17:17:16 +00:00
|
|
|
return true;
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
if( iterativeSequence->hasEffect( xShape ) )
|
2005-01-21 17:17:16 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void MainSequence::insertTextRange( const css::uno::Any& aTarget )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
EffectSequenceHelper::insertTextRange( aTarget );
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& iterativeSequence : maInteractiveSequenceVector)
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
iterativeSequence->insertTextRange( aTarget );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
void MainSequence::disposeTextRange( const css::uno::Any& aTarget )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
EffectSequenceHelper::disposeTextRange( aTarget );
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& iterativeSequence : maInteractiveSequenceVector)
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
iterativeSequence->disposeTextRange( aTarget );
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-25 14:13:53 +00:00
|
|
|
/** callback from the sd::View when an object just left text edit mode */
|
|
|
|
void MainSequence::onTextChanged( const Reference< XShape >& xShape )
|
|
|
|
{
|
|
|
|
EffectSequenceHelper::onTextChanged( xShape );
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& iterativeSequence : maInteractiveSequenceVector)
|
2005-01-25 14:13:53 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
iterativeSequence->onTextChanged( xShape );
|
2005-01-25 14:13:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSequenceHelper::onTextChanged( const Reference< XShape >& xShape )
|
|
|
|
{
|
|
|
|
bool bChanges = false;
|
|
|
|
|
|
|
|
EffectSequence::iterator aIter;
|
2010-11-26 21:44:24 +00:00
|
|
|
for( aIter = maEffects.begin(); aIter != maEffects.end(); ++aIter )
|
2005-01-25 14:13:53 +00:00
|
|
|
{
|
|
|
|
if( (*aIter)->getTargetShape() == xShape )
|
|
|
|
bChanges |= (*aIter)->checkForText();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bChanges )
|
|
|
|
EffectSequenceHelper::implRebuild();
|
|
|
|
}
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
void MainSequence::rebuild()
|
|
|
|
{
|
2005-03-01 16:29:57 +00:00
|
|
|
startRebuildTimer();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainSequence::lockRebuilds()
|
|
|
|
{
|
|
|
|
mnRebuildLockGuard++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainSequence::unlockRebuilds()
|
|
|
|
{
|
|
|
|
DBG_ASSERT( mnRebuildLockGuard, "sd::MainSequence::unlockRebuilds(), no corresponding lockRebuilds() call!" );
|
|
|
|
if( mnRebuildLockGuard )
|
|
|
|
mnRebuildLockGuard--;
|
|
|
|
|
|
|
|
if( (mnRebuildLockGuard == 0) && mbPendingRebuildRequest )
|
|
|
|
{
|
|
|
|
mbPendingRebuildRequest = false;
|
|
|
|
startRebuildTimer();
|
|
|
|
}
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainSequence::implRebuild()
|
|
|
|
{
|
2005-03-01 16:29:57 +00:00
|
|
|
if( mnRebuildLockGuard )
|
|
|
|
{
|
|
|
|
mbPendingRebuildRequest = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mbRebuilding = true;
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
EffectSequenceHelper::implRebuild();
|
|
|
|
|
2017-11-11 21:07:56 +01:00
|
|
|
auto aIter( maInteractiveSequenceVector.begin() );
|
|
|
|
while( aIter != maInteractiveSequenceVector.end() )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
InteractiveSequencePtr pIS( (*aIter) );
|
|
|
|
if( pIS->maEffects.empty() )
|
|
|
|
{
|
|
|
|
// remove empty interactive sequences
|
2017-11-11 21:07:56 +01:00
|
|
|
aIter = maInteractiveSequenceVector.erase( aIter );
|
2004-11-26 18:45:55 +00:00
|
|
|
|
|
|
|
Reference< XChild > xChild( mxSequenceRoot, UNO_QUERY_THROW );
|
|
|
|
Reference< XTimeContainer > xParent( xChild->getParent(), UNO_QUERY_THROW );
|
|
|
|
Reference< XAnimationNode > xISNode( pIS->mxSequenceRoot, UNO_QUERY_THROW );
|
|
|
|
xParent->removeChild( xISNode );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pIS->implRebuild();
|
2012-05-19 15:09:08 +02:00
|
|
|
++aIter;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
notify_listeners();
|
2005-03-01 16:29:57 +00:00
|
|
|
mbRebuilding = false;
|
2004-11-26 18:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainSequence::notify_change()
|
|
|
|
{
|
|
|
|
notify_listeners();
|
|
|
|
}
|
|
|
|
|
2015-10-28 12:01:32 +02:00
|
|
|
bool MainSequence::setTrigger( const CustomAnimationEffectPtr& pEffect, const css::uno::Reference< css::drawing::XShape >& xTriggerShape )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
|
|
|
EffectSequenceHelper* pOldSequence = pEffect->getEffectSequence();
|
|
|
|
|
2015-11-10 10:23:02 +01:00
|
|
|
EffectSequenceHelper* pNewSequence = nullptr;
|
2004-11-26 18:45:55 +00:00
|
|
|
if( xTriggerShape.is() )
|
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
for (auto const& iteractiveSequence : maInteractiveSequenceVector)
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2017-11-11 21:07:56 +01:00
|
|
|
InteractiveSequencePtr pIS(iteractiveSequence);
|
2004-11-26 18:45:55 +00:00
|
|
|
if( pIS->getTriggerShape() == xTriggerShape )
|
|
|
|
{
|
|
|
|
pNewSequence = pIS.get();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !pNewSequence )
|
|
|
|
pNewSequence = createInteractiveSequence( xTriggerShape ).get();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pNewSequence = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pOldSequence != pNewSequence )
|
|
|
|
{
|
2005-12-14 14:51:29 +00:00
|
|
|
if( pOldSequence )
|
|
|
|
pOldSequence->maEffects.remove( pEffect );
|
|
|
|
if( pNewSequence )
|
|
|
|
pNewSequence->maEffects.push_back( pEffect );
|
2004-11-26 18:45:55 +00:00
|
|
|
pEffect->setEffectSequence( pNewSequence );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-10-05 07:56:12 +02:00
|
|
|
IMPL_LINK_NOARG(MainSequence, onTimerHdl, Timer *, void)
|
2005-03-01 16:29:57 +00:00
|
|
|
{
|
|
|
|
if( mbTimerMode )
|
|
|
|
{
|
|
|
|
implRebuild();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reset();
|
2006-12-12 15:29:01 +00:00
|
|
|
createMainSequence();
|
2005-03-01 16:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 10:19:11 -07:00
|
|
|
/** starts a timer that recreates the internal structure from the API core */
|
2005-03-01 16:29:57 +00:00
|
|
|
void MainSequence::startRecreateTimer()
|
|
|
|
{
|
2007-07-06 12:10:13 +00:00
|
|
|
if( !mbRebuilding && (mbIgnoreChanges == 0) )
|
2005-03-01 16:29:57 +00:00
|
|
|
{
|
|
|
|
mbTimerMode = false;
|
|
|
|
maTimer.Start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 10:19:11 -07:00
|
|
|
/**
|
|
|
|
* starts a timer that rebuilds the API core from the internal structure
|
|
|
|
* This is used to reduce the number of screen redraws due to animation changes.
|
|
|
|
*/
|
2005-03-01 16:29:57 +00:00
|
|
|
void MainSequence::startRebuildTimer()
|
|
|
|
{
|
|
|
|
mbTimerMode = true;
|
|
|
|
maTimer.Start();
|
|
|
|
}
|
|
|
|
|
2004-11-26 18:45:55 +00:00
|
|
|
InteractiveSequence::InteractiveSequence( const Reference< XTimeContainer >& xSequenceRoot, MainSequence* pMainSequence )
|
|
|
|
: EffectSequenceHelper( xSequenceRoot ), mpMainSequence( pMainSequence )
|
|
|
|
{
|
|
|
|
mnSequenceType = EffectNodeType::INTERACTIVE_SEQUENCE;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if( mxSequenceRoot.is() )
|
|
|
|
{
|
|
|
|
Reference< XEnumerationAccess > xEnumerationAccess( mxSequenceRoot, UNO_QUERY_THROW );
|
|
|
|
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
|
|
|
|
while( !mxEventSource.is() && xEnumeration->hasMoreElements() )
|
|
|
|
{
|
|
|
|
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
|
|
|
|
|
|
|
|
Event aEvent;
|
|
|
|
if( (xChildNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::ON_CLICK) )
|
|
|
|
aEvent.Source >>= mxEventSource;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-25 15:08:11 +09:00
|
|
|
catch( Exception& )
|
2004-11-26 18:45:55 +00:00
|
|
|
{
|
2013-02-18 23:33:27 +01:00
|
|
|
OSL_FAIL( "sd::InteractiveSequence::InteractiveSequence(), exception caught!" );
|
2004-11-26 18:45:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void InteractiveSequence::rebuild()
|
|
|
|
{
|
|
|
|
mpMainSequence->rebuild();
|
|
|
|
}
|
|
|
|
|
|
|
|
void InteractiveSequence::implRebuild()
|
|
|
|
{
|
|
|
|
EffectSequenceHelper::implRebuild();
|
|
|
|
}
|
|
|
|
|
2005-03-01 16:29:57 +00:00
|
|
|
MainSequenceRebuildGuard::MainSequenceRebuildGuard( const MainSequencePtr& pMainSequence )
|
|
|
|
: mpMainSequence( pMainSequence )
|
|
|
|
{
|
|
|
|
if( mpMainSequence.get() )
|
|
|
|
mpMainSequence->lockRebuilds();
|
|
|
|
}
|
|
|
|
|
|
|
|
MainSequenceRebuildGuard::~MainSequenceRebuildGuard()
|
|
|
|
{
|
|
|
|
if( mpMainSequence.get() )
|
|
|
|
mpMainSequence->unlockRebuilds();
|
|
|
|
}
|
|
|
|
|
2006-12-12 15:29:01 +00:00
|
|
|
}
|
2010-10-12 15:51:52 +02:00
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|