blob: d141bcda1930baf858bae1d791b036880c86b843 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"
#include <com/sun/star/presentation/EffectNodeType.hpp>
#include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
#include <com/sun/star/presentation/TextAnimationType.hpp>
#include <com/sun/star/presentation/ParagraphTarget.hpp>
#include <com/sun/star/animations/Event.hpp>
#include <com/sun/star/animations/EventTrigger.hpp>
#include <com/sun/star/animations/Timing.hpp>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/animations/AnimationFill.hpp>
#include <com/sun/star/animations/XAnimate.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <svx/unoshape.hxx>
#include <svx/svdotext.hxx>
#include <svx/svdopath.hxx>
#include <svx/svdogrp.hxx>
#include <svx/svditer.hxx>
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include <CustomAnimationPreset.hxx>
#include <TransitionPreset.hxx>
#include <EffectMigration.hxx>
#include <anminfo.hxx>
using namespace ::vos;
using namespace ::sd;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::animations;
using namespace ::com::sun::star::presentation;
using ::com::sun::star::drawing::XShape;
using ::rtl::OUString;
using ::com::sun::star::lang::XMultiServiceFactory;
using ::com::sun::star::drawing::XShape;
using ::com::sun::star::beans::NamedValue;
struct deprecated_FadeEffect_conversion_table_entry
{
FadeEffect meFadeEffect;
const sal_Char* mpPresetId;
}
deprecated_FadeEffect_conversion_table[] =
{
// OOo 1.x transitions
{ FadeEffect_FADE_FROM_LEFT, "wipe-right" },
{ FadeEffect_FADE_FROM_TOP, "wipe-down" },
{ FadeEffect_FADE_FROM_RIGHT, "wipe-left" },
{ FadeEffect_FADE_FROM_BOTTOM, "wipe-up" },
{ FadeEffect_CLOCKWISE, "wheel-clockwise-1-spoke" },
{ FadeEffect_UNCOVER_TO_LEFT, "uncover-left" },
{ FadeEffect_UNCOVER_TO_UPPERLEFT, "uncover-left-up" },
{ FadeEffect_UNCOVER_TO_TOP, "uncover-up" },
{ FadeEffect_UNCOVER_TO_UPPERRIGHT, "uncover-right-up" },
{ FadeEffect_UNCOVER_TO_RIGHT, "uncover-right" },
{ FadeEffect_UNCOVER_TO_LOWERRIGHT, "uncover-right-down" },
{ FadeEffect_UNCOVER_TO_BOTTOM, "uncover-down" },
{ FadeEffect_UNCOVER_TO_LOWERLEFT, "uncover-left-down" },
{ FadeEffect_VERTICAL_LINES, "random-bars-vertical" },
{ FadeEffect_HORIZONTAL_LINES, "random-bars-horizontal" },
{ FadeEffect_VERTICAL_CHECKERBOARD, "checkerboard-down" },
{ FadeEffect_HORIZONTAL_CHECKERBOARD, "checkerboard-across" },
{ FadeEffect_FADE_TO_CENTER, "box-in" },
{ FadeEffect_FADE_FROM_CENTER, "box-out" },
{ FadeEffect_VERTICAL_STRIPES, "venetian-blinds-vertical" },
{ FadeEffect_HORIZONTAL_STRIPES, "venetian-blinds-horizontal" },
{ FadeEffect_MOVE_FROM_LEFT, "cover-right" },
{ FadeEffect_MOVE_FROM_TOP, "cover-down" },
{ FadeEffect_MOVE_FROM_RIGHT, "cover-left" },
{ FadeEffect_MOVE_FROM_BOTTOM, "cover-up" },
{ FadeEffect_MOVE_FROM_UPPERLEFT, "cover-right-down" },
{ FadeEffect_MOVE_FROM_UPPERRIGHT, "cover-left-down" },
{ FadeEffect_MOVE_FROM_LOWERRIGHT, "cover-left-up" },
{ FadeEffect_MOVE_FROM_LOWERLEFT, "cover-right-up" },
{ FadeEffect_DISSOLVE, "dissolve" },
{ FadeEffect_RANDOM, "random-transition" },
{ FadeEffect_ROLL_FROM_LEFT, "push-right" },
{ FadeEffect_ROLL_FROM_TOP, "push-down" },
{ FadeEffect_ROLL_FROM_RIGHT, "push-left" },
{ FadeEffect_ROLL_FROM_BOTTOM, "push-up" },
{ FadeEffect_CLOSE_VERTICAL, "split-horizontal-in" },
{ FadeEffect_CLOSE_HORIZONTAL, "split-vertical-in" },
{ FadeEffect_OPEN_VERTICAL, "split-horizontal-out" },
{ FadeEffect_OPEN_HORIZONTAL, "split-vertical-out" },
{ FadeEffect_FADE_FROM_UPPERLEFT, "diagonal-squares-right-down" },
{ FadeEffect_FADE_FROM_UPPERRIGHT, "diagonal-squares-left-down" },
{ FadeEffect_FADE_FROM_LOWERLEFT, "diagonal-squares-right-up" },
{ FadeEffect_FADE_FROM_LOWERRIGHT, "diagonal-squares-left-up" },
// OOo 1.x transitions not in OOo 2.x
{ FadeEffect_CLOCKWISE, "clock-wipe-twelve" },
{ FadeEffect_COUNTERCLOCKWISE, "reverse-clock-wipe-twelve" },
{ FadeEffect_SPIRALIN_LEFT, "spiral-wipe-top-left-clockwise" },
{ FadeEffect_SPIRALIN_RIGHT, "spiral-wipe-top-right-counter-clockwise" },
{ FadeEffect_SPIRALOUT_LEFT, "spiral-wipe-out-to-bottom-right-clockwise" },
{ FadeEffect_SPIRALOUT_RIGHT, "spiral-wipe-out-to-bottom-left-counter-clockwise" },
{ FadeEffect_WAVYLINE_FROM_LEFT, "snake-wipe-top-left-vertical" },
{ FadeEffect_WAVYLINE_FROM_TOP, "snake-wipe-top-left-horizontal" },
{ FadeEffect_WAVYLINE_FROM_RIGHT, "snake-wipe-bottom-right-vertical" },
{ FadeEffect_WAVYLINE_FROM_BOTTOM, "snake-wipe-bottom-right-horizontal" },
{ FadeEffect_STRETCH_FROM_LEFT, "wipe-right" }, // todo
{ FadeEffect_STRETCH_FROM_TOP, "wipe-down" }, // todo
{ FadeEffect_STRETCH_FROM_RIGHT, "wipe-left" }, // todo
{ FadeEffect_STRETCH_FROM_BOTTOM, "wipe-up" }, // todo
// OOo 1.x not available transitions
{ FadeEffect_CLOCKWISE, "wheel-clockwise-2-spokes" },
{ FadeEffect_CLOCKWISE, "wheel-clockwise-3-spokes" },
{ FadeEffect_CLOCKWISE, "wheel-clockwise-4-spokes" },
{ FadeEffect_CLOCKWISE, "wheel-clockwise-8-spokes" },
{ FadeEffect_FADE_FROM_CENTER, "shape-circle" },
{ FadeEffect_FADE_FROM_CENTER, "shape-diamond" },
{ FadeEffect_FADE_FROM_CENTER, "shape-plus" },
{ FadeEffect_CLOCKWISE, "wedge" },
{ FadeEffect_DISSOLVE, "fade-through-black" },
{ FadeEffect_CLOCKWISE, "zoom-rotate-in" },
{ FadeEffect_HORIZONTAL_LINES, "comb-horizontal" },
{ FadeEffect_VERTICAL_LINES, "comb-vertical" },
{ FadeEffect_DISSOLVE, "fade-smoothly" },
{ FadeEffect_NONE, 0 }
};
/* todo
cut cut (same as NONE?)
cut-through-black cut toBlack
wedge wedge
*/
void EffectMigration::SetFadeEffect( SdPage* pPage, ::com::sun::star::presentation::FadeEffect eNewEffect)
{
deprecated_FadeEffect_conversion_table_entry* pEntry = deprecated_FadeEffect_conversion_table;
while( (pEntry->meFadeEffect != FadeEffect_NONE) && (pEntry->meFadeEffect != eNewEffect) )
pEntry++;
if( pEntry->mpPresetId )
{
const OUString aPresetId( OUString::createFromAscii( pEntry->mpPresetId ) );
const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList();
TransitionPresetList::const_iterator aIt( rPresetList.begin());
const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
for( ; aIt != aEndIt; ++aIt )
{
if( (*aIt)->getPresetId() == aPresetId)
{
pPage->setTransitionType( (*aIt)->getTransition() );
pPage->setTransitionSubtype( (*aIt)->getSubtype() );
pPage->setTransitionDirection( (*aIt)->getDirection() );
pPage->setTransitionFadeColor( (*aIt)->getFadeColor() );
break;
}
}
}
else
{
pPage->setTransitionType( 0 );
pPage->setTransitionSubtype( 0 );
pPage->setTransitionDirection( 0 );
pPage->setTransitionFadeColor( 0 );
}
}
FadeEffect EffectMigration::GetFadeEffect( const SdPage* pPage )
{
const TransitionPresetList & rPresetList = TransitionPreset::getTransitionPresetList();
TransitionPresetList::const_iterator aIt( rPresetList.begin());
const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
for( ; aIt != aEndIt; ++aIt )
{
if( ( (*aIt)->getTransition() == pPage->getTransitionType() ) &&
( (*aIt)->getSubtype() == pPage->getTransitionSubtype() ) &&
( (*aIt)->getDirection() == pPage->getTransitionDirection() ) &&
( (*aIt)->getFadeColor() == pPage->getTransitionFadeColor() ) )
{
const OUString& aPresetId = (*aIt)->getPresetId();
deprecated_FadeEffect_conversion_table_entry* pEntry = deprecated_FadeEffect_conversion_table;
while( (pEntry->meFadeEffect != FadeEffect_NONE) && (!aPresetId.equalsAscii( pEntry->mpPresetId ) ) )
pEntry++;
return pEntry->meFadeEffect;
}
}
return FadeEffect_NONE;
}
struct deprecated_AnimationEffect_conversion_table_entry
{
AnimationEffect meEffect;
const sal_Char* mpPresetId;
const sal_Char* mpPresetSubType;
}
deprecated_AnimationEffect_conversion_table[] =
{
// OOo 1.x entrance effects
{ AnimationEffect_APPEAR, "ooo-entrance-appear",0 },
{ AnimationEffect_FADE_TO_CENTER, "ooo-entrance-box","in" },
{ AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-box","out" },
{ AnimationEffect_VERTICAL_CHECKERBOARD, "ooo-entrance-checkerboard","downward" },
{ AnimationEffect_HORIZONTAL_CHECKERBOARD, "ooo-entrance-checkerboard","across" },
{ AnimationEffect_FADE_FROM_UPPERLEFT, "ooo-entrance-diagonal-squares","right-to-bottom" },
{ AnimationEffect_FADE_FROM_UPPERRIGHT, "ooo-entrance-diagonal-squares","left-to-bottom" },
{ AnimationEffect_FADE_FROM_LOWERLEFT, "ooo-entrance-diagonal-squares","right-to-top" },
{ AnimationEffect_FADE_FROM_LOWERRIGHT, "ooo-entrance-diagonal-squares","left-to-top" },
{ AnimationEffect_DISSOLVE, "ooo-entrance-dissolve-in",0 },
{ AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-fly-in","from-left" },
{ AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-fly-in","from-top" },
{ AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-fly-in","from-right" },
{ AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-fly-in","from-bottom" },
{ AnimationEffect_MOVE_FROM_UPPERLEFT, "ooo-entrance-fly-in","from-top-left" },
{ AnimationEffect_MOVE_FROM_UPPERRIGHT, "ooo-entrance-fly-in","from-top-right" },
{ AnimationEffect_MOVE_FROM_LOWERRIGHT, "ooo-entrance-fly-in","from-bottom-right" },
{ AnimationEffect_MOVE_FROM_LOWERLEFT, "ooo-entrance-fly-in","from-bottom-left" },
{ AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-fly-in-slow", "from-bottom" },
{ AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-fly-in-slow", "from-left" },
{ AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-fly-in-slow", "from-right" },
{ AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-fly-in-slow", "from-top" },
{ AnimationEffect_MOVE_SHORT_FROM_LEFT, "ooo-entrance-peek-in","from-left" },
{ AnimationEffect_MOVE_SHORT_FROM_TOP, "ooo-entrance-peek-in","from-top" },
{ AnimationEffect_MOVE_SHORT_FROM_RIGHT, "ooo-entrance-peek-in","from-right" },
{ AnimationEffect_MOVE_SHORT_FROM_BOTTOM, "ooo-entrance-peek-in","from-bottom" },
{ AnimationEffect_VERTICAL_LINES, "ooo-entrance-random-bars","horizontal" },
{ AnimationEffect_HORIZONTAL_LINES, "ooo-entrance-random-bars","vertical" },
{ AnimationEffect_RANDOM, "ooo-entrance-random",0 },
{ AnimationEffect_CLOSE_VERTICAL, "ooo-entrance-split","horizontal-in" },
{ AnimationEffect_CLOSE_HORIZONTAL, "ooo-entrance-split","vertical-in" },
{ AnimationEffect_OPEN_VERTICAL, "ooo-entrance-split","horizontal-out" },
{ AnimationEffect_OPEN_HORIZONTAL, "ooo-entrance-split","vertical-out" },
{ AnimationEffect_VERTICAL_STRIPES, "ooo-entrance-venetian-blinds","horizontal" },
{ AnimationEffect_HORIZONTAL_STRIPES, "ooo-entrance-venetian-blinds","vertical" },
{ AnimationEffect_FADE_FROM_LEFT, "ooo-entrance-wipe","from-left" },
{ AnimationEffect_FADE_FROM_TOP, "ooo-entrance-wipe","from-bottom" },
{ AnimationEffect_FADE_FROM_RIGHT, "ooo-entrance-wipe","from-right" },
{ AnimationEffect_FADE_FROM_BOTTOM, "ooo-entrance-wipe","from-top" },
{ AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-swivel","vertical" },
{ AnimationEffect_VERTICAL_ROTATE, "ooo-entrance-swivel","horizontal" },
{ AnimationEffect_STRETCH_FROM_LEFT, "ooo-entrance-stretchy","from-left" },
{ AnimationEffect_STRETCH_FROM_UPPERLEFT, "ooo-entrance-stretchy","from-top-left" },
{ AnimationEffect_STRETCH_FROM_TOP, "ooo-entrance-stretchy","from-top" },
{ AnimationEffect_STRETCH_FROM_UPPERRIGHT, "ooo-entrance-stretchy","from-top-right" },
{ AnimationEffect_STRETCH_FROM_RIGHT, "ooo-entrance-stretchy","from-right" },
{ AnimationEffect_STRETCH_FROM_LOWERRIGHT, "ooo-entrance-stretchy","from-bottom-right" },
{ AnimationEffect_STRETCH_FROM_BOTTOM, "ooo-entrance-stretchy","from-bottom" },
{ AnimationEffect_STRETCH_FROM_LOWERLEFT, "ooo-entrance-stretchy","from-bottom-left" },
{ AnimationEffect_HORIZONTAL_STRETCH, "ooo-entrance-expand", 0 },
{ AnimationEffect_CLOCKWISE, "ooo-entrance-wheel","1" },
{ AnimationEffect_COUNTERCLOCKWISE, "ooo-entrance-clock-wipe","counter-clockwise" },
{ AnimationEffect_SPIRALIN_LEFT, "ooo-entrance-spiral-wipe", "from-top-left-clockwise" },
{ AnimationEffect_SPIRALIN_RIGHT, "ooo-entrance-spiral-wipe", "from-top-right-counter-clockwise" },
{ AnimationEffect_SPIRALOUT_LEFT, "ooo-entrance-spiral-wipe", "from-center-clockwise" },
{ AnimationEffect_SPIRALOUT_RIGHT, "ooo-entrance-spiral-wipe", "from-center-counter-clockwise" },
{ AnimationEffect_WAVYLINE_FROM_LEFT, "ooo-entrance-snake-wipe","from-top-left-vertical" },
{ AnimationEffect_WAVYLINE_FROM_TOP, "ooo-entrance-snake-wipe","from-top-left-horizontal" },
{ AnimationEffect_WAVYLINE_FROM_RIGHT, "ooo-entrance-snake-wipe","from-bottom-right-vertical" },
{ AnimationEffect_WAVYLINE_FROM_BOTTOM, "ooo-entrance-snake-wipe","from-bottom-right-horizontal" },
// ooo 1.x exit effects
{ AnimationEffect_HIDE, "ooo-exit-disappear",0 },
{ AnimationEffect_MOVE_TO_LEFT, "ooo-exit-fly-out", "from-right" },
{ AnimationEffect_MOVE_TO_TOP, "ooo-exit-fly-out", "from-bottom" },
{ AnimationEffect_MOVE_TO_RIGHT, "ooo-exit-fly-out", "from-left" },
{ AnimationEffect_MOVE_TO_BOTTOM, "ooo-exit-fly-out", "from-top" },
{ AnimationEffect_MOVE_TO_UPPERLEFT, "ooo-exit-fly-out", "from-top-right" },
{ AnimationEffect_MOVE_TO_UPPERRIGHT, "ooo-exit-fly-out", "from-top-left" },
{ AnimationEffect_MOVE_TO_LOWERRIGHT, "ooo-exit-fly-out", "from-bottom-left" },
{ AnimationEffect_MOVE_TO_LOWERLEFT, "ooo-exit-fly-out", "from-bottom-right" },
{ AnimationEffect_MOVE_SHORT_TO_LEFT, "ooo-exit-peek-out", "from-right" },
{ AnimationEffect_MOVE_SHORT_TO_UPPERLEFT, "ooo-exit-peek-out", "from-right" },
{ AnimationEffect_MOVE_SHORT_TO_TOP, "ooo-exit-peek-out", "from-bottom" },
{ AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT, "ooo-exit-peek-out", "from-bottom" },
{ AnimationEffect_MOVE_SHORT_TO_RIGHT, "ooo-exit-peek-out", "from-left" },
{ AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT, "ooo-exit-peek-out","from-left" },
{ AnimationEffect_MOVE_SHORT_TO_BOTTOM, "ooo-exit-peek-out", "from-top" },
{ AnimationEffect_MOVE_SHORT_TO_LOWERLEFT, "ooo-exit-peek-out", "from-top" },
// no matching in OOo 2.x
{ AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT, "ooo-entrance-peek-in","from-left" },
{ AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT, "ooo-entrance-peek-in","from-top" },
{ AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT, "ooo-entrance-peek-in","from-right" },
{ AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT, "ooo-entrance-peek-in","from-bottom" },
{ AnimationEffect_LASER_FROM_LEFT, "ooo-entrance-fly-in","from-left" },
{ AnimationEffect_LASER_FROM_TOP, "ooo-entrance-fly-in","from-top" },
{ AnimationEffect_LASER_FROM_RIGHT, "ooo-entrance-fly-in","from-right" },
{ AnimationEffect_LASER_FROM_BOTTOM, "ooo-entrance-fly-in","from-bottom" },
{ AnimationEffect_LASER_FROM_UPPERLEFT, "ooo-entrance-fly-in","from-top-left" },
{ AnimationEffect_LASER_FROM_UPPERRIGHT, "ooo-entrance-fly-in","from-top-right" },
{ AnimationEffect_LASER_FROM_LOWERLEFT, "ooo-entrance-fly-in","from-bottom-left" },
{ AnimationEffect_LASER_FROM_LOWERRIGHT, "ooo-entrance-fly-in","from-bottom-right" },
// no matching in OOo 1.x
{ AnimationEffect_FADE_TO_CENTER, "ooo-entrance-circle", "in" },
{ AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-circle", "out" },
{ AnimationEffect_FADE_TO_CENTER, "ooo-entrance-diamond", "in" },
{ AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-diamond", "out" },
{ AnimationEffect_FADE_TO_CENTER, "ooo-entrance-plus", "in" },
{ AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-plus", "out" },
{ AnimationEffect_CLOCKWISE, "ooo-entrance-wedge", 0 },
{ AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "2" },
{ AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "3" },
{ AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "4" },
{ AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "8" },
{ AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-boomerang", 0 },
{ AnimationEffect_MOVE_FROM_UPPERRIGHT, "ooo-entrance-bounce", 0 },
{ AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-curve-up", 0 },
{ AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-float", 0 },
{ AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-glide", 0 },
{ AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-magnify", 0 },
{ AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-pinwheel", 0 },
{ AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-breaks", 0 },
{ AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-sling", 0 },
{ AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-spiral-in", 0 },
{ AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-thread", 0 },
{ AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-ascend", 0 },
{ AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-center-revolve", 0 },
{ AnimationEffect_APPEAR, "ooo-entrance-compress", 0 },
{ AnimationEffect_MOVE_SHORT_FROM_TOP, "ooo-entrance-descend", 0 },
{ AnimationEffect_MOVE_SHORT_FROM_LEFT, "ooo-entrance-ease-in", 0 },
{ AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-rise-up", 0 },
{ AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-spin-in", 0 },
{ AnimationEffect_STRETCH_FROM_LEFT, "ooo-entrance-stretchy", "across" },
{ AnimationEffect_STRETCH_FROM_TOP, "ooo-entrance-stretchy", "downward" },
{ AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in" },
{ AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in-slightly" },
{ AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in-from-screen-center" },
{ AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out" },
{ AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out-slightly" },
{ AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out-from-screen-center" },
{ AnimationEffect_DISSOLVE, "ooo-entrance-fade-in", 0 },
{ AnimationEffect_DISSOLVE, "ooo-entrance-fade-in-and-zoom", 0 },
{ AnimationEffect_DISSOLVE, "ooo-entrance-fade-in-and-swivel", 0 },
// open
/*
{ AnimationEffect_ZOOM_IN_FROM_LEFT, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_IN_FROM_UPPERLEFT, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_IN_FROM_TOP, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_IN_FROM_RIGHT, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_IN_FROM_BOTTOM, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_IN_FROM_LOWERLEFT, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_IN_FROM_CENTER, "ooo-entrance-zoom","in" },
{ AnimationEffect_ZOOM_OUT_FROM_LEFT, "ooo-entrance-appear",0 },
{ AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT, "ooo-entrance-appear",0 },
{ AnimationEffect_ZOOM_OUT_FROM_TOP, "ooo-entrance-appear",0 },
{ AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT, "ooo-entrance-appear",0 },
{ AnimationEffect_ZOOM_OUT_FROM_RIGHT, "ooo-entrance-appear",0 },
{ AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT, "ooo-entrance-appear",0 },
{ AnimationEffect_ZOOM_OUT_FROM_BOTTOM, "ooo-entrance-appear",0 },
{ AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT, "ooo-entrance-appear",0 },
{ AnimationEffect_ZOOM_OUT_FROM_CENTER, "ooo-entrance-appear",0 },
{ AnimationEffect_PATH, "ooo-entrance-spiral-in",0 },
*/
{ AnimationEffect_NONE, 0, 0 }
};
EffectSequence::iterator ImplFindEffect( MainSequencePtr& pMainSequence, const Reference< XShape >& rShape, sal_Int16 nSubItem )
{
EffectSequence::iterator aIter;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( (pEffect->getTargetShape() == rShape) && (pEffect->getTargetSubItem() == nSubItem) )
break;
}
return aIter;
}
static bool implIsInsideGroup( SdrObject* pObj )
{
return pObj && pObj->GetObjList() && pObj->GetObjList()->GetUpList();
}
void EffectMigration::SetAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
{
DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
"sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
return;
SdrObject* pObj = pShape->GetSdrObject();
if( implIsInsideGroup( pObj ) )
return;
OUString aPresetId;
OUString aPresetSubType;
if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
{
DBG_ERROR( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
return;
}
const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
if( pPreset.get() && pMainSequence.get() )
{
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
bool bEffectCreated = false;
if( (aIterOnlyBackground == aEnd) && (aIterAsWhole == aEnd) )
{
// check if there is already an text effect for this shape
EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
if( aIterOnlyText != aEnd )
{
// check if this is an animation text group
sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
if( nGroupId >= 0 )
{
CustomAnimationTextGroupPtr pGroup = pMainSequence->findGroup( nGroupId );
if( pGroup.get() )
{
// add an effect to animate the shape
pMainSequence->setAnimateForm( pGroup, true );
// find this effect
EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
if( aIter != aEnd )
{
if( ((*aIter)->getPresetId() != aPresetId) ||
((*aIter)->getPresetSubType() != aPresetSubType) )
{
(*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
pMainSequence->rebuild();
bEffectCreated = true;
}
}
}
}
}
if( !bEffectCreated )
{
// if there is not yet an effect that target this shape, we generate one
// we insert the shape effect before it
Reference< XAnimationNode > xNode( pPreset->create( aPresetSubType ) );
DBG_ASSERT( xNode.is(), "EffectMigration::SetAnimationEffect(), could not create preset!" );
if( xNode.is() )
{
CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xNode ) );
pEffect->setTarget( makeAny( xShape ) );
SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
if( !bManual )
pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
pMainSequence->append( pEffect );
if( ( pObj->GetObjInventor() == SdrInventor ) && ( pObj->GetObjIdentifier() == OBJ_OUTLINETEXT ) )
{
// special case for outline text, effects are always mapped to text group effect
pMainSequence->
createTextGroup( pEffect, 10, bManual ? -1 : 0.0, sal_False, sal_False );
}
}
}
}
else
{
// if there is already an effect targeting this shape
// just replace it
CustomAnimationEffectPtr pEffect;
if( aIterAsWhole != aEnd )
{
pEffect = (*aIterAsWhole);
}
else
{
pEffect = (*aIterOnlyBackground);
}
if( pEffect.get() )
{
if( (pEffect->getPresetId() != aPresetId) ||
(pEffect->getPresetSubType() != aPresetSubType) )
{
pMainSequence->replace( pEffect, pPreset, aPresetSubType );
}
}
}
}
}
// --------------------------------------------------------------------
AnimationEffect EffectMigration::GetAnimationEffect( SvxShape* pShape )
{
OUString aPresetId;
OUString aPresetSubType;
SdrObject* pObj = pShape->GetSdrObject();
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
if( pMainSequence.get() )
{
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
if( (pEffect->getTargetSubItem() == ShapeAnimationSubType::ONLY_BACKGROUND) ||
(pEffect->getTargetSubItem() == ShapeAnimationSubType::AS_WHOLE))
{
if( pEffect->getDuration() != 0.1 ) // ignore appear effects created from old text effect import
{
aPresetId = (*aIter)->getPresetId();
aPresetSubType = (*aIter)->getPresetSubType();
break;
}
}
}
}
}
// now find old effect
AnimationEffect eEffect = AnimationEffect_NONE;
if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
ConvertPreset( aPresetId, 0, eEffect );
return eEffect;
}
// --------------------------------------------------------------------
void EffectMigration::SetTextAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
{
DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
"sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
return;
SdrObject* pObj = pShape->GetSdrObject();
if( implIsInsideGroup( pObj ) )
return;
// first map the deprecated AnimationEffect to a preset and subtype
OUString aPresetId;
OUString aPresetSubType;
if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
{
DBG_ERROR( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
return;
}
SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj );
// ignore old text effects on shape without text
if( (pTextObj == 0) || (!pTextObj->HasText()) )
return;
const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
// create an effect from this preset
CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
if( pPreset.get() && pMainSequence.get() )
{
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
CustomAnimationTextGroupPtr pGroup;
// is there already an animation text group for this shape?
if( aIterOnlyText != aEnd )
{
const sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
if( nGroupId >= 0 )
pGroup = pMainSequence->findGroup( nGroupId );
}
// if there is not yet a group, create it
if( pGroup.get() == 0 )
{
CustomAnimationEffectPtr pShapeEffect;
EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
if( aIterOnlyBackground != aEnd )
{
pShapeEffect = (*aIterOnlyBackground);
}
else
{
EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
if( aIterAsWhole != aEnd )
{
pShapeEffect = (*aIterAsWhole);
}
else
{
OUString aEmpty;
CustomAnimationPresetPtr pShapePreset( rPresets.getEffectDescriptor( OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo-entrance-appear" ) ) ) );
Reference< XAnimationNode > xNode( pPreset->create( aEmpty ) );
DBG_ASSERT( xNode.is(), "EffectMigration::SetTextAnimationEffect(), could not create preset!" );
if( xNode.is() )
{
pShapeEffect.reset( new CustomAnimationEffect( xNode ) );
pShapeEffect->setTarget( makeAny( xShape ) );
pShapeEffect->setDuration( 0.1 );
pMainSequence->append( pShapeEffect );
SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
if( pPage && pPage->GetPresChange() != PRESCHANGE_MANUAL )
pShapeEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
}
}
}
if( pShapeEffect.get() )
{
SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
// now create effects for each paragraph
pGroup =
pMainSequence->
createTextGroup( pShapeEffect, 10, bManual ? -1 : 0.0, sal_True, sal_False );
}
}
if( pGroup.get() != 0 )
{
const bool bLaserEffect = (eEffect >= AnimationEffect_LASER_FROM_LEFT) && (eEffect <= AnimationEffect_LASER_FROM_LOWERRIGHT);
// now we have a group, so check if all effects are same as we like to have them
const EffectSequence& rEffects = pGroup->getEffects();
EffectSequence::const_iterator aIter;
for( aIter = rEffects.begin(); aIter != rEffects.end(); aIter++ )
{
// only work on paragraph targets
if( (*aIter)->getTarget().getValueType() == ::getCppuType((const ParagraphTarget*)0) )
{
if( ((*aIter)->getPresetId() != aPresetId) ||
((*aIter)->getPresetSubType() != aPresetSubType) )
{
(*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
}
if( bLaserEffect )
{
(*aIter)->setIterateType( TextAnimationType::BY_LETTER );
(*aIter)->setIterateInterval( 0.5 );// TODO:
// Determine
// interval
// according
// to
// total
// effect
// duration
}
}
}
}
pMainSequence->rebuild();
}
}
// --------------------------------------------------------------------
AnimationEffect EffectMigration::GetTextAnimationEffect( SvxShape* pShape )
{
OUString aPresetId;
OUString aPresetSubType;
SdrObject* pObj = pShape->GetSdrObject();
if( pObj )
{
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
if( pMainSequence.get() )
{
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
if( aIter != pMainSequence->getEnd() )
{
aPresetId = (*aIter)->getPresetId();
aPresetSubType = (*aIter)->getPresetSubType();
}
}
}
// now find old effect
AnimationEffect eEffect = AnimationEffect_NONE;
if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
ConvertPreset( aPresetId, 0, eEffect );
return eEffect;
}
// --------------------------------------------------------------------
bool EffectMigration::ConvertPreset( const OUString& rPresetId, const OUString* pPresetSubType, AnimationEffect& rEffect )
{
rEffect = AnimationEffect_NONE;
if( rPresetId.getLength() )
{
// first try a match for preset id and subtype
deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table;
while( p->mpPresetId )
{
if( rPresetId.equalsAscii( p->mpPresetId ) &&
(( p->mpPresetSubType == 0 ) ||
( pPresetSubType == 0) ||
( pPresetSubType->equalsAscii( p->mpPresetSubType )) ) )
{
rEffect = p->meEffect;
return true;
}
p++;
}
return false;
}
else
{
// empty preset id means AnimationEffect_NONE
return true;
}
}
// --------------------------------------------------------------------
bool EffectMigration::ConvertAnimationEffect( const AnimationEffect& rEffect, OUString& rPresetId, OUString& rPresetSubType )
{
deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table;
while( p->mpPresetId )
{
if( p->meEffect == rEffect )
{
rPresetId = OUString::createFromAscii( p->mpPresetId );
rPresetSubType = OUString::createFromAscii( p->mpPresetSubType );
return true;
}
p++;
}
return false;
}
// --------------------------------------------------------------------
double EffectMigration::ConvertAnimationSpeed( AnimationSpeed eSpeed )
{
double fDuration;
switch( eSpeed )
{
case AnimationSpeed_SLOW: fDuration = 2.0; break;
case AnimationSpeed_FAST: fDuration = 0.5; break;
//case AnimationSpeed_MEDIUM:
default:
fDuration = 1.0; break;
}
return fDuration;
}
// --------------------------------------------------------------------
void EffectMigration::SetAnimationSpeed( SvxShape* pShape, AnimationSpeed eSpeed )
{
DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
"sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
return;
SdrObject* pObj = pShape->GetSdrObject();
if( implIsInsideGroup( pObj ) )
return;
double fDuration = ConvertAnimationSpeed( eSpeed );
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
bool bNeedRebuild = false;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
if( pEffect->getDuration() != 0.1 )
pEffect->setDuration( fDuration );
bNeedRebuild = true;
}
}
if( bNeedRebuild )
pMainSequence->rebuild();
}
// --------------------------------------------------------------------
AnimationSpeed EffectMigration::GetAnimationSpeed( SvxShape* pShape )
{
SdrObject* pObj = pShape->GetSdrObject();
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
double fDuration = 1.0;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
if( pEffect->getDuration() != 0.1 )
{
fDuration = pEffect->getDuration();
break;
}
}
}
return ConvertDuration( fDuration );
}
// --------------------------------------------------------------------
AnimationSpeed EffectMigration::ConvertDuration( double fDuration )
{
AnimationSpeed eSpeed;
if( fDuration < 1.0 )
eSpeed = AnimationSpeed_FAST;
else if( fDuration > 1.5 )
eSpeed = AnimationSpeed_SLOW;
else
eSpeed = AnimationSpeed_MEDIUM;
return eSpeed;
}
// --------------------------------------------------------------------
void EffectMigration::SetDimColor( SvxShape* pShape, sal_Int32 nColor )
{
DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
"sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
return;
SdrObject* pObj = pShape->GetSdrObject();
if( implIsInsideGroup( pObj ) )
return;
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
bool bNeedRebuild = false;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
pEffect->setHasAfterEffect( true );
pEffect->setDimColor( makeAny( nColor ) );
pEffect->setAfterEffectOnNext( true );
bNeedRebuild = true;
}
}
if( bNeedRebuild )
pMainSequence->rebuild();
}
// --------------------------------------------------------------------
sal_Int32 EffectMigration::GetDimColor( SvxShape* pShape )
{
sal_Int32 nColor = 0;
if( pShape )
{
SdrObject* pObj = pShape->GetSdrObject();
if( pObj && pObj->GetPage() )
{
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( (pEffect->getTargetShape() == xShape) &&
pEffect->getDimColor().hasValue() &&
pEffect->hasAfterEffect())
{
pEffect->getDimColor() >>= nColor;
break;
}
}
}
}
return nColor;
}
// --------------------------------------------------------------------
void EffectMigration::SetDimHide( SvxShape* pShape, sal_Bool bDimHide )
{
DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
"sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
return;
SdrObject* pObj = pShape->GetSdrObject();
if( implIsInsideGroup( pObj ) )
return;
Any aEmpty;
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
bool bNeedRebuild = false;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
pEffect->setHasAfterEffect( bDimHide ? true : false );
if( bDimHide )
pEffect->setDimColor( aEmpty );
pEffect->setAfterEffectOnNext( false );
bNeedRebuild = true;
}
}
if( bNeedRebuild )
pMainSequence->rebuild();
}
// --------------------------------------------------------------------
sal_Bool EffectMigration::GetDimHide( SvxShape* pShape )
{
sal_Bool bRet = sal_False;
if( pShape )
{
SdrObject* pObj = pShape->GetSdrObject();
if( pObj && pObj->GetPage() )
{
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
bRet = pEffect->hasAfterEffect() &&
!pEffect->getDimColor().hasValue() &&
(!pEffect->IsAfterEffectOnNext());
break;
}
}
}
}
return bRet;
}
// --------------------------------------------------------------------
void EffectMigration::SetDimPrevious( SvxShape* pShape, sal_Bool bDimPrevious )
{
DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
"sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
return;
SdrObject* pObj = pShape->GetSdrObject();
if( implIsInsideGroup( pObj ) )
return;
Any aColor;
if( bDimPrevious )
aColor <<= (sal_Int32)COL_LIGHTGRAY;
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
bool bNeedRebuild = false;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
pEffect->setHasAfterEffect( bDimPrevious );
if( !bDimPrevious || !pEffect->getDimColor().hasValue() )
pEffect->setDimColor( aColor );
pEffect->setAfterEffectOnNext( true );
bNeedRebuild = true;
}
}
if( bNeedRebuild )
pMainSequence->rebuild();
}
// --------------------------------------------------------------------
sal_Bool EffectMigration::GetDimPrevious( SvxShape* pShape )
{
sal_Bool bRet = sal_False;
if( pShape )
{
SdrObject* pObj = pShape->GetSdrObject();
if( pObj && pObj->GetPage() )
{
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
bRet = pEffect->hasAfterEffect() &&
pEffect->getDimColor().hasValue() &&
pEffect->IsAfterEffectOnNext();
break;
}
}
}
}
return bRet;
}
// --------------------------------------------------------------------
void EffectMigration::SetPresentationOrder( SvxShape* pShape, sal_Int32 nNewPos )
{
if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
return;
SdrObject* pObj = pShape->GetSdrObject();
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
EffectSequence& rSequence = pMainSequence->getSequence();
sal_Int32 nPos;
sal_Int32 nCurrentPos = -1;
std::vector< std::vector< EffectSequence::iterator > > aEffectVector(1);
if( !rSequence.empty() )
{
Reference< XShape > xThis( pShape );
Reference< XShape > xCurrent;
EffectSequence::iterator aIter( rSequence.begin() );
EffectSequence::iterator aEnd( rSequence.end() );
for( nPos = 0; aIter != aEnd; aIter++ )
{
CustomAnimationEffectPtr pEffect = (*aIter);
if( !xCurrent.is() )
{
xCurrent = pEffect->getTargetShape();
}
else if( pEffect->getTargetShape() != xCurrent )
{
nPos++;
xCurrent = pEffect->getTargetShape();
aEffectVector.resize( nPos+1 );
}
// is this the first effect for xThis shape?
if(( nCurrentPos == -1 ) && ( xCurrent == xThis ) )
{
nCurrentPos = nPos;
}
aEffectVector[nPos].push_back( aIter );
}
}
// check if there is at least one effect for xThis
if( nCurrentPos == -1 )
{
DBG_ERROR("sd::EffectMigration::SetPresentationOrder() failed cause this shape has no effect" );
return;
}
// check trivial case
if( nCurrentPos != nNewPos )
{
std::vector< CustomAnimationEffectPtr > aEffects;
std::vector< EffectSequence::iterator >::iterator aIter( aEffectVector[nCurrentPos].begin() );
std::vector< EffectSequence::iterator >::iterator aEnd( aEffectVector[nCurrentPos].end() );
while( aIter != aEnd )
{
aEffects.push_back( (*(*aIter)) );
rSequence.erase( (*aIter++) );
}
if( nNewPos > nCurrentPos )
nNewPos++;
std::vector< CustomAnimationEffectPtr >::iterator aTempIter( aEffects.begin() );
std::vector< CustomAnimationEffectPtr >::iterator aTempEnd( aEffects.end() );
if( nNewPos == (sal_Int32)aEffectVector.size() )
{
while( aTempIter != aTempEnd )
{
rSequence.push_back( (*aTempIter++) );
}
}
else
{
EffectSequence::iterator aPos( aEffectVector[nNewPos][0] );
while( aTempIter != aTempEnd )
{
rSequence.insert( aPos, (*aTempIter++) );
}
}
}
}
// --------------------------------------------------------------------
/** Returns the position of the given SdrObject in the Presentation order.
* This function returns -1 if the SdrObject is not in the Presentation order
* or if its the path-object.
*/
sal_Int32 EffectMigration::GetPresentationOrder( SvxShape* pShape )
{
sal_Int32 nPos = -1, nFound = -1;
SdrObject* pObj = pShape->GetSdrObject();
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
EffectSequence& rSequence = pMainSequence->getSequence();
Reference< XShape > xThis( pShape );
Reference< XShape > xCurrent;
EffectSequence::iterator aIter( rSequence.begin() );
EffectSequence::iterator aEnd( rSequence.end() );
for( ; aIter != aEnd; aIter++ )
{
CustomAnimationEffectPtr pEffect = (*aIter);
if( !xCurrent.is() || pEffect->getTargetShape() != xCurrent )
{
nPos++;
xCurrent = pEffect->getTargetShape();
// is this the first effect for xThis shape?
if( xCurrent == xThis )
{
nFound = nPos;
break;
}
}
}
return nFound;
}
// --------------------------------------------------------------------
void EffectMigration::UpdateSoundEffect( SvxShape* pShape, SdAnimationInfo* pInfo )
{
if( pInfo )
{
SdrObject* pObj = pShape->GetSdrObject();
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
bool bNeedRebuild = false;
OUString aSoundFile;
if( pInfo->mbSoundOn )
aSoundFile = pInfo->maSoundFile;
for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
if( aSoundFile.getLength() )
{
pEffect->createAudio( makeAny( aSoundFile ) );
}
else
{
pEffect->removeAudio();
}
bNeedRebuild = true;
}
}
if( bNeedRebuild )
pMainSequence->rebuild();
}
}
// --------------------------------------------------------------------
OUString EffectMigration::GetSoundFile( SvxShape* pShape )
{
OUString aSoundFile;
if( pShape )
{
SdrObject* pObj = pShape->GetSdrObject();
if( pObj && pObj->GetPage() )
{
sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
EffectSequence::iterator aIter;
for( aIter = pMainSequence->getBegin();
(aSoundFile.getLength() == 0) && (aIter != pMainSequence->getEnd());
aIter++ )
{
CustomAnimationEffectPtr pEffect( (*aIter) );
if( pEffect->getTargetShape() == xShape )
{
if( pEffect->getAudio().is() )
pEffect->getAudio()->getSource() >>= aSoundFile;
}
}
}
}
return aSoundFile;
}
// --------------------------------------------------------------------
sal_Bool EffectMigration::GetSoundOn( SvxShape* pShape )
{
return GetSoundFile( pShape ).getLength() != 0;
}
// --------------------------------------------------------------------
void EffectMigration::SetAnimationPath( SvxShape* pShape, SdrPathObj* pPathObj )
{
if( pShape && pPathObj )
{
SdrObject* pObj = pShape->GetSdrObject();
if( pObj )
{
//sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
const Reference< XShape > xShape( pShape );
SdPage* pPage = dynamic_cast< SdPage* >( pPathObj ? pPathObj->GetPage() : 0 );
if( pPage )
{
boost::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() );
if( pMainSequence.get() )
CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, makeAny( xShape ), -1.0 ) );
}
}
}
}
// --------------------------------------------------------------------
static const OUString aServiceNameParallelTimeContainer(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.ParallelTimeContainer"));
static const OUString aServiceNameAnimateSet(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.AnimateSet"));
// #42894# helper which creates the needed XAnimate for changing visibility and all the (currently) needed embeddings
void createVisibilityOnOffNode(Reference< XTimeContainer >& rxParentContainer, SdrObject& rCandidate, bool bVisible, bool bOnClick, double fDuration)
{
Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory());
Any aAny;
// create par container node
Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance(aServiceNameParallelTimeContainer), UNO_QUERY_THROW);
// set begin
aAny <<= (double)(0.0);
xOuterSeqTimeContainer->setBegin(aAny);
// set fill
xOuterSeqTimeContainer->setFill(AnimationFill::HOLD);
// set named values
Sequence< NamedValue > aUserDataSequence;
aUserDataSequence.realloc(1);
aUserDataSequence[0].Name = OUString(RTL_CONSTASCII_USTRINGPARAM("node-type"));
aUserDataSequence[0].Value <<= bOnClick ? EffectNodeType::ON_CLICK : EffectNodeType::AFTER_PREVIOUS;
xOuterSeqTimeContainer->setUserData(aUserDataSequence);
// create animate set to change visibility for rCandidate
Reference< XAnimationNode > xAnimateSetForLast(xMsf->createInstance(aServiceNameAnimateSet), UNO_QUERY_THROW);
// set begin
aAny <<= (double)(0.0);
xAnimateSetForLast->setBegin(aAny);
// set duration
aAny <<= fDuration;
xAnimateSetForLast->setDuration(aAny);
// set fill
xAnimateSetForLast->setFill(AnimationFill::HOLD);
// set target
Reference< XAnimate > xAnimate(xAnimateSetForLast, UNO_QUERY);
Reference< XShape > xTargetShape(rCandidate.getUnoShape(), UNO_QUERY);
aAny <<= xTargetShape;
xAnimate->setTarget(aAny);
// set AttributeName
xAnimate->setAttributeName(OUString(RTL_CONSTASCII_USTRINGPARAM("Visibility")));
// set attribute value
aAny <<= bVisible ? sal_True : sal_False;
xAnimate->setTo(aAny);
// ad set node to par node
Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW);
xParentContainer->appendChild(xAnimateSetForLast);
// add node
rxParentContainer->appendChild(xOuterSeqTimeContainer);
}
// #42894# older AOO formats supported animated group objects, that means all members of the group
// were shown animated by showing one after the other. This is no longer supported, but the following
// fallback will create the needed SMIL animation stuff. Unfortunately the members of the group
// have to be moved directly to the page, else the (explained to be generic, thus I expected this to
// work) animations will not work in slideshow
void EffectMigration::CreateAnimatedGroup(SdrObjGroup& rGroupObj, SdPage& rPage)
{
// aw080 will give a vector immeditately
SdrObjListIter aIter(rGroupObj);
if(aIter.Count())
{
boost::shared_ptr< sd::MainSequence > pMainSequence(rPage.getMainSequence());
if(pMainSequence.get())
{
std::vector< SdrObject* > aObjects;
aObjects.reserve(aIter.Count());
while(aIter.IsMore())
{
// do move to page rough with old/current stuff, will be different in aw080 anyways
SdrObject* pCandidate = aIter.Next();
rGroupObj.GetSubList()->NbcRemoveObject(pCandidate->GetOrdNum());
rPage.NbcInsertObject(pCandidate);
aObjects.push_back(pCandidate);
}
// create main node
Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory());
Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance(aServiceNameParallelTimeContainer), UNO_QUERY_THROW);
Any aAny;
// set begin
aAny <<= (double)(0.0);
xOuterSeqTimeContainer->setBegin(aAny);
// prepare parent container
Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW);
// prepare loop over objects
SdrObject* pLast = 0;
SdrObject* pNext = 0;
const double fDurationShow(0.2);
const double fDurationHide(0.001);
for(sal_uInt32 a(0); a < aObjects.size(); a++)
{
pLast = pNext;
pNext = aObjects[a];
// create node
if(pLast)
{
createVisibilityOnOffNode(xParentContainer, *pLast, false, false, fDurationHide);
}
if(pNext)
{
createVisibilityOnOffNode(xParentContainer, *pNext, true, !a, fDurationShow);
}
}
// create end node
if(pNext)
{
createVisibilityOnOffNode(xParentContainer, *pNext, false, false, fDurationHide);
}
// add to main sequence and rebuild
pMainSequence->createEffects(xOuterSeqTimeContainer);
pMainSequence->rebuild();
}
}
}
// eof