diff options
Diffstat (limited to 'sd/source/filter/ppt')
-rw-r--r-- | sd/source/filter/ppt/makefile.mk | 57 | ||||
-rw-r--r-- | sd/source/filter/ppt/ppt97animations.cxx | 803 | ||||
-rw-r--r-- | sd/source/filter/ppt/ppt97animations.hxx | 158 | ||||
-rw-r--r-- | sd/source/filter/ppt/pptanimations.hxx | 559 | ||||
-rw-r--r-- | sd/source/filter/ppt/pptatom.cpp | 123 | ||||
-rw-r--r-- | sd/source/filter/ppt/pptatom.hxx | 160 | ||||
-rwxr-xr-x | sd/source/filter/ppt/pptin.cxx | 2762 | ||||
-rw-r--r-- | sd/source/filter/ppt/pptin.hxx | 105 | ||||
-rw-r--r-- | sd/source/filter/ppt/pptinanimations.cxx | 3948 | ||||
-rw-r--r-- | sd/source/filter/ppt/pptinanimations.hxx | 132 | ||||
-rw-r--r-- | sd/source/filter/ppt/propread.cxx | 695 | ||||
-rw-r--r-- | sd/source/filter/ppt/propread.hxx | 191 |
12 files changed, 9693 insertions, 0 deletions
diff --git a/sd/source/filter/ppt/makefile.mk b/sd/source/filter/ppt/makefile.mk new file mode 100644 index 000000000000..bb00675147f5 --- /dev/null +++ b/sd/source/filter/ppt/makefile.mk @@ -0,0 +1,57 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=sd +TARGET=ppt +ENABLE_EXCEPTIONS=TRUE +VISIBILITY_HIDDEN=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Common ---------------------------------------------------------- + +.IF "$(dbg_anim_log)"!="" || "$(DBG_ANIM_LOG)"!="" +CDEFS+= -DDBG_ANIM_LOG +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/propread.obj \ + $(SLO)$/pptin.obj \ + $(SLO)$/pptinanimations.obj \ + $(SLO)$/pptatom.obj \ + $(SLO)$/ppt97animations.obj + +# --- Targets -------------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sd/source/filter/ppt/ppt97animations.cxx b/sd/source/filter/ppt/ppt97animations.cxx new file mode 100644 index 000000000000..a4a3564d35b0 --- /dev/null +++ b/sd/source/filter/ppt/ppt97animations.cxx @@ -0,0 +1,803 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "ppt97animations.hxx" + +// header for class SdrObject +#include <svx/svdobj.hxx> +// header for class SdPage +#include "sdpage.hxx" +// header for define DBG_ERROR +#include <tools/debug.hxx> +// header for define GetXShapeForSdrObject +#include <svx/unoapi.hxx> +#include "EffectMigration.hxx" +#include <CustomAnimationPreset.hxx> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/presentation/TextAnimationType.hpp> +#include <com/sun/star/presentation/EffectNodeType.hpp> +#include <com/sun/star/presentation/ShapeAnimationSubType.hpp> + +using namespace ::com::sun::star; + +//--------------------------------------------------------------------------------------- + +void Ppt97AnimationInfoAtom::ReadStream( SvStream& rIn ) +{ + rIn >> nDimColor; + rIn >> nFlags; + rIn >> nSoundRef; + rIn >> nDelayTime; + rIn >> nOrderID; + rIn >> nSlideCount; + rIn >> nBuildType; + rIn >> nFlyMethod; + rIn >> nFlyDirection; + rIn >> nAfterEffect; + rIn >> nSubEffect; + rIn >> nOLEVerb; + rIn >> nUnknown1; + rIn >> nUnknown2; +} + +//--------------------------------------------------------------------------------------- + +#define MEMBER_CONSTRUCTOR_LIST() \ + m_aAtom() \ + , m_aSoundFileUrl() \ + , m_bDirtyCache(true) \ + , m_aPresetId() \ + , m_aSubType() \ + , m_bHasSpecialDuration(false) \ + , m_fDurationInSeconds(0.001) + +Ppt97Animation::Ppt97Animation( SvStream& rInputStream ) + : MEMBER_CONSTRUCTOR_LIST() +{ + m_aAtom.ReadStream( rInputStream ); +} + +Ppt97Animation::Ppt97Animation() + : MEMBER_CONSTRUCTOR_LIST() +{ +} + +Ppt97Animation::Ppt97Animation( const Ppt97Animation& rAnimation ) + : MEMBER_CONSTRUCTOR_LIST() +{ + *this = rAnimation; +} + +Ppt97Animation& Ppt97Animation::operator= ( const Ppt97Animation& rAnimation ) +{ + m_aAtom = rAnimation.m_aAtom; + m_aSoundFileUrl = rAnimation.m_aSoundFileUrl; + m_bDirtyCache = rAnimation.m_bDirtyCache; + m_aPresetId = rAnimation.m_aPresetId; + m_aSubType = rAnimation.m_aSubType; + m_bHasSpecialDuration = rAnimation.m_bHasSpecialDuration; + m_fDurationInSeconds = rAnimation.m_fDurationInSeconds; + + return *this; +} + +Ppt97Animation::~Ppt97Animation() +{ +} + +bool Ppt97Animation::operator < ( const Ppt97Animation& rAnimation ) const +{ + return m_aAtom.nOrderID < rAnimation.m_aAtom.nOrderID; +} +bool Ppt97Animation::operator > ( const Ppt97Animation& rAnimation ) const +{ + return m_aAtom.nOrderID > rAnimation.m_aAtom.nOrderID; +} +bool Ppt97Animation::HasEffect() const +{ + return m_aAtom.nBuildType != 0; +} +bool Ppt97Animation::HasParagraphEffect() const +{ + return m_aAtom.nBuildType > 1; +} +sal_Int32 Ppt97Animation::GetParagraphLevel() const +{ + sal_Int32 nParagraphLevel = 0; + if(m_aAtom.nBuildType>1) + nParagraphLevel = m_aAtom.nBuildType-1; + return nParagraphLevel; +} +bool Ppt97Animation::HasSoundEffect() const +{ + return m_aAtom.nSoundRef && m_aAtom.nFlags & 0x0010; +} +bool Ppt97Animation::HasStopPreviousSound() const +{ + return m_aAtom.nFlags & 0x0040; +} +bool Ppt97Animation::HasReverseOrder() const +{ + return m_aAtom.nFlags & 0x001; +} +bool Ppt97Animation::HasAnimateAssociatedShape() const +{ + return m_aAtom.nFlags & 0x004000; +} +bool Ppt97Animation::HasAfterEffect() const +{ + return m_aAtom.nAfterEffect != 0; +} +bool Ppt97Animation::HasAfterEffect_ChangeColor() const +{ + return m_aAtom.nAfterEffect == 1; +} +bool Ppt97Animation::HasAfterEffect_DimAtNextEffect() const +{ + return m_aAtom.nAfterEffect == 2; +} +bool Ppt97Animation::HasAfterEffect_DimAfterEffect() const +{ + return m_aAtom.nAfterEffect == 3; +} + +UINT32 Ppt97Animation::GetSoundRef() const +{ + return m_aAtom.nSoundRef; +} +void Ppt97Animation::SetSoundFileUrl( const ::rtl::OUString& rSoundFileUrl ) +{ + m_aSoundFileUrl = rSoundFileUrl; +} + +double Ppt97Animation::GetDelayTimeInSeconds() const +{ + return m_aAtom.nDelayTime != 0X7FFFFFFF ? m_aAtom.nDelayTime/1000.0 : 0.0; +} + +bool Ppt97Animation::GetSpecialDuration( double& rfDurationInSeconds ) const +{ + UpdateCacheData(); + if( m_bHasSpecialDuration ) + rfDurationInSeconds = m_fDurationInSeconds; + return m_bHasSpecialDuration; +} + +bool Ppt97Animation::GetSpecialTextIterationDelay( double& rfTextIterationDelay ) const +{ + bool bRet = false; + switch(this->GetTextAnimationType()) + { + case presentation::TextAnimationType::BY_LETTER: + rfTextIterationDelay = 0.075; + bRet = true; + break; + case presentation::TextAnimationType::BY_WORD: + rfTextIterationDelay = 0.3; + bRet = true; + break; + default: + break; + } + return bRet; +} + +sal_Int32 Ppt97Animation::GetDimColor() const +{ + return static_cast<sal_Int32>(m_aAtom.nDimColor); +} + +void Ppt97Animation::SetDimColor( sal_Int32 nDimColor ) +{ + m_aAtom.nDimColor = nDimColor; +} +void Ppt97Animation::SetAnimateAssociatedShape( bool bAnimate ) +{ + if( !bAnimate ) + { + //the appear effect cannot be animated without text + if( this->GetPresetId().equals( ::rtl::OUString::createFromAscii("ooo-entrance-appear") ) ) + return; + //the random effect may be the appear effect and than has the same problem + if( this->GetPresetId().equals( ::rtl::OUString::createFromAscii("ooo-entrance-random") ) ) + { + //this case is not 100% correct -> feel free to complete + //i consider this case as seldom and not that problematic and a simple correct fix is not in sight + DBG_WARNING("you tried to deselect the animation of the form for random animation-> this has been refused"); + return; + } + + } + + if(bAnimate) + m_aAtom.nFlags = m_aAtom.nFlags | 0x004000; + else if( HasAnimateAssociatedShape() ) + { + m_aAtom.nFlags = m_aAtom.nFlags ^ 0x004000; + } +} + +sal_Int16 Ppt97Animation::GetEffectNodeType() const //see com::sun::star::presentation::EffectNodeType +{ + sal_Int16 nRet = presentation::EffectNodeType::ON_CLICK; + if( m_aAtom.nFlags & 0x04 ) + { + nRet = presentation::EffectNodeType::AFTER_PREVIOUS; + } + return nRet; +} + +sal_Int16 Ppt97Animation::GetTextAnimationType() const +{ + sal_Int16 nRet = presentation::TextAnimationType::BY_PARAGRAPH; + switch( m_aAtom.nSubEffect ) + { + case 0: + break; + case 2: + nRet = presentation::TextAnimationType::BY_LETTER; + break; + default: + nRet = presentation::TextAnimationType::BY_WORD; + break; + } + return nRet; +} +::rtl::OUString Ppt97Animation::GetPresetId() const +{ + UpdateCacheData(); + return m_aPresetId; +} +::rtl::OUString Ppt97Animation::GetPresetSubType() const +{ + UpdateCacheData(); + return m_aSubType; +} + +void Ppt97Animation::ClearCacheData() const +{ + m_aPresetId = m_aSubType = rtl::OUString(); + m_bHasSpecialDuration = false; + m_fDurationInSeconds = 0.001; +} +void Ppt97Animation::UpdateCacheData() const +{ + if( !m_bDirtyCache ) + return; + + ClearCacheData(); + + if( !HasEffect() ) + { + m_bDirtyCache = false; + return; + } + + switch( m_aAtom.nFlyMethod ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_APPEAR; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-appear"); // --- appear --- + break; + case 0x01: + //eRetval = ::com::sun::star::presentation::AnimationEffect_RANDOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-random"); // --- random --- + break; + case 0x02: // --- blinds effect --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_VERTICAL_STRIPES; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-venetian-blinds"); + m_aSubType = ::rtl::OUString::createFromAscii("horizontal"); // horizontal + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRIPES; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-venetian-blinds"); + m_aSubType = ::rtl::OUString::createFromAscii("vertical"); // vertical + break; + } + } + break; + case 0x03: // --- (hor/ver) shifted appear --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_CHECKERBOARD; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-checkerboard"); + m_aSubType = ::rtl::OUString::createFromAscii("across"); // vertical ??? + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_VERTICAL_CHECKERBOARD; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-checkerboard"); + m_aSubType = ::rtl::OUString::createFromAscii("downward"); // horizontal ??? + break; + } + } + break; + case 0x05: + //eRetval = ::com::sun::star::presentation::AnimationEffect_DISSOLVE; // --- dissolve ---- + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-dissolve-in"); + break; + case 0x08: // --- (hor/ver) lines --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_LINES; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-random-bars"); + m_aSubType = ::rtl::OUString::createFromAscii("vertical"); // horizontal ??? + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_VERTICAL_LINES; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-random-bars"); + m_aSubType = rtl::OUString::createFromAscii("horizontal"); // vertical ??? + break; + } + } + break; + case 0x09: // --- diagonal --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x4: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERRIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-diagonal-squares"); + m_aSubType = rtl::OUString::createFromAscii("left-to-top"); // to left top + break; + case 0x5: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERLEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-diagonal-squares"); + m_aSubType = rtl::OUString::createFromAscii("right-to-top"); // to right top + break; + case 0x6: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERRIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-diagonal-squares"); + m_aSubType = rtl::OUString::createFromAscii("left-to-bottom"); // to left bottom + break; + case 0x7: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERLEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-diagonal-squares"); + m_aSubType = rtl::OUString::createFromAscii("right-to-bottom"); // to right bottom + break; + } + } + break; + case 0x0a: // --- roll/wipe --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_RIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-wipe"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); // from right + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_BOTTOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-wipe"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); // from bottom + break; + case 0x2: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-wipe"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); // from left + break; + case 0x3: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_TOP; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-wipe"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); // from top + break; + } + } + break; + case 0x0b: //--- fade in --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-box"); + m_aSubType = rtl::OUString::createFromAscii("out"); // from center + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-box"); + m_aSubType = rtl::OUString::createFromAscii("in"); // to center + break; + } + } + break; + case 0x0c: // --- text effects --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); + + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_TOP; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); + break; + case 0x2: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_RIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); + break; + case 0x3: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_BOTTOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); + break; + case 0x4: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERLEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-top-left"); + break; + case 0x5: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERRIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-top-right"); + break; + case 0x6: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERLEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom-left"); + break; + case 0x7: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERRIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom-right"); + break; + case 0x8: // -- short text effects -- + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-peek-in"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); + break; + case 0x9: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_BOTTOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-peek-in"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); + break; + case 0xa: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_RIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-peek-in"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); + break; + case 0xb: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_TOP; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-peek-in"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); + break; + case 0xc: // -- slow text effects -- + { + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LEFT; + //rSpeed = ::com::sun::star::presentation::AnimationSpeed_SLOW; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in-slow"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); + } + break; + case 0xd: + { + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_TOP; + //rSpeed = ::com::sun::star::presentation::AnimationSpeed_SLOW; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in-slow"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); + } + break; + case 0xe: + { + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_RIGHT; + //rSpeed = ::com::sun::star::presentation::AnimationSpeed_SLOW; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in-slow"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); + } + break; + case 0xf: + { + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_BOTTOM; + //rSpeed = ::com::sun::star::presentation::AnimationSpeed_SLOW; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in-slow"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); + } + break; + case 0x10: // --- zoom --- + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("in"); + break; + case 0x11: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("in-slightly"); + break; + case 0x12: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("out"); + break; + case 0x13: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("out-slightly"); + break; + case 0x14: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("in-from-screen-center"); + break; + case 0x15: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("out-from-screen-center"); + break; + case 0x16: // --- stretch --- + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRETCH; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("across"); + break; + case 0x17: + //eRetval = ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); + break; + case 0x18: + //eRetval = ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_TOP; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); + break; + case 0x19: + //eRetval = ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_RIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); + break; + case 0x1a: + //eRetval = ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_BOTTOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); + break; + case 0x1b: // --- rotate --- + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_ROTATE; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-swivel"); + m_aSubType = rtl::OUString::createFromAscii("vertical"); + break; + case 0x1c: // --- spirale --- + //eRetval = ::com::sun::star::presentation::AnimationEffect_SPIRALOUT_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-spiral-in"); + break; + } + } + break; + case 0x0d: // --- open/close --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_OPEN_VERTICAL ; // ??? + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-split"); + m_aSubType = rtl::OUString::createFromAscii("horizontal-out"); //horizontal open + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_CLOSE_VERTICAL; // ??? + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-split"); + m_aSubType = rtl::OUString::createFromAscii("horizontal-in"); //horizontal close + break; + case 0x2: + //eRetval = ::com::sun::star::presentation::AnimationEffect_OPEN_HORIZONTAL; // ??? + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-split"); + m_aSubType = rtl::OUString::createFromAscii("vertical-out"); // vertical open + break; + case 0x3: + //eRetval = ::com::sun::star::presentation::AnimationEffect_CLOSE_HORIZONTAL; // ??? + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-split"); + m_aSubType = rtl::OUString::createFromAscii("vertical-in"); // vertical close + break; + } + } + break; + case 0x0e: // --- blink --- + { + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-flash-once"); + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: //fast + m_fDurationInSeconds = 0.075; + m_bHasSpecialDuration = true; + break; + case 0x1: //medium + m_fDurationInSeconds = 0.5; + m_bHasSpecialDuration = true; + break; + case 0x2: //slow + m_fDurationInSeconds = 1.0; + m_bHasSpecialDuration = true; + break; + } + } + break; + default: + { + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-appear"); + DBG_ERROR("no effect mapped"); + } + break; + } + m_bDirtyCache = false; +} + +void Ppt97Animation::createAndSetCustomAnimationEffect( SdrObject* pObj ) +{ + + if( !this->HasEffect() ) + return; + if( !pObj || !pObj->GetPage() ) + { + DBG_ERROR("no valid SdrObject or page found for ppt import"); + return; + } + + uno::Reference< drawing::XShape > xShape = GetXShapeForSdrObject( pObj ); + if( !xShape.is() ) + { + DBG_ERROR("no XShape interface found for ppt import"); + return; + } + ::sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); + if( !pMainSequence.get() ) + { + DBG_ERROR("no MainSequence found for ppt import"); + return; + } + + const ::sd::CustomAnimationPresets& rPresets( ::sd::CustomAnimationPresets::getCustomAnimationPresets() ); + ::sd::CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( this->GetPresetId() ) ); + if( !pPreset.get() ) + { + DBG_ERROR("no suiteable preset found for ppt import"); + return; + } + + //--------------start doing something + + //1. ------ create an effect from the presets ------ + ::sd::CustomAnimationEffectPtr pEffect( new ::sd::CustomAnimationEffect( pPreset->create( this->GetPresetSubType() ) ) ); + if( !pEffect.get() ) + { + DBG_ASSERT(pEffect.get(),"no suiteable effect found"); + return; + } + + //2. ------ adapt the created effect ------ + + // set the shape targeted by this effect + pEffect->setTarget( makeAny( xShape ) ); + + pEffect->setBegin( this->GetDelayTimeInSeconds() ); + + // some effects need a different duration than that of the mapped preset effect + double fDurationInSeconds = 1.0;//in secunden + if( this->GetSpecialDuration( fDurationInSeconds ) ) + pEffect->setDuration( fDurationInSeconds ); + + // set after effect + if( this->HasAfterEffect() ) + { + pEffect->setHasAfterEffect( sal_True ); + if( this->HasAfterEffect_ChangeColor() ) + pEffect->setDimColor( uno::makeAny( this->GetDimColor() ) ); + else + pEffect->setAfterEffectOnNext( this->HasAfterEffect_DimAtNextEffect() ); + } + + // set sound effect + if( this->HasSoundEffect() ) + pEffect->createAudio( uno::makeAny( m_aSoundFileUrl ) ); + + // text iteration + pEffect->setIterateType( this->GetTextAnimationType() ); + + // some effects need a different delay between text iteration than that of the mapped preset effect + double fTextIterationDelay = 1.0; + if( this->GetSpecialTextIterationDelay( fTextIterationDelay ) ) + pEffect->setIterateInterval( fTextIterationDelay ); + + // is the effect started on click or after the last effect (Another possible value is EffectNodeType::WITH_PREVIOUS ) + pEffect->setNodeType( this->GetEffectNodeType() ); + + //set stop sound effect + if( this->HasStopPreviousSound() ) + pEffect->setStopAudio(); + + // append the effect to the main sequence + if( !this->HasParagraphEffect() ) + { + if( this->HasAnimateAssociatedShape() ) + pEffect->setTargetSubItem( presentation::ShapeAnimationSubType::AS_WHOLE ); + else + pEffect->setTargetSubItem( presentation::ShapeAnimationSubType::AS_WHOLE ); //todo: set ONLY_TEXT again if that is fixed + //pEffect->setTargetSubItem( presentation::ShapeAnimationSubType::ONLY_TEXT ); + } + + //3. ------ put the created effect to the model and do some last changes fro paragraph effects ------ + pMainSequence->append( pEffect ); + if( this->HasParagraphEffect() ) + { + sal_Int32 nParagraphLevel = this->GetParagraphLevel(); + double fDelaySeconds = this->GetDelayTimeInSeconds(); + sal_Bool bAnimateAssociatedShape = this->HasAnimateAssociatedShape();//or only text + sal_Bool bTextReverse = this->HasReverseOrder(); + + // now create effects for each paragraph + ::sd::CustomAnimationTextGroupPtr pGroup = pMainSequence-> + createTextGroup( pEffect, nParagraphLevel, fDelaySeconds, bAnimateAssociatedShape, bTextReverse ); + + if( pGroup ) + { + const ::sd::EffectSequence& rEffects = pGroup->getEffects(); + ::sd::EffectSequence::const_iterator aIter = rEffects.begin(); + + ::sd::CustomAnimationEffectPtr pLastEffect; + sal_Int32 nIndex = 0; + for( ; aIter != rEffects.end(); aIter++ ) + { + ::sd::CustomAnimationEffectPtr pGroupEffect(*aIter); + + ////todo? if( nIndex > 1 && pLastEffect && this->HasSoundEffect() ) + //// pLastEffect->setStopAudio(); + if( nIndex < 2 ) + { + pGroupEffect->setNodeType( this->GetEffectNodeType() ); + } + else if( nIndex > 0 ) + { + bool bAtParagraphBegin = false; + if(!bTextReverse) + bAtParagraphBegin = pGroupEffect->getParaDepth() < nParagraphLevel; + else + bAtParagraphBegin = !pLastEffect || pLastEffect->getParaDepth() < nParagraphLevel; + if( bAtParagraphBegin ) + pGroupEffect->setNodeType( this->GetEffectNodeType() ); + else if( this->GetTextAnimationType() == presentation::TextAnimationType::BY_PARAGRAPH ) + pGroupEffect->setNodeType( presentation::EffectNodeType::WITH_PREVIOUS ); + else + pGroupEffect->setNodeType( presentation::EffectNodeType::AFTER_PREVIOUS ); + } + pLastEffect = pGroupEffect; + nIndex++; + } + } + } + pMainSequence->rebuild(); +} diff --git a/sd/source/filter/ppt/ppt97animations.hxx b/sd/source/filter/ppt/ppt97animations.hxx new file mode 100644 index 000000000000..4aa24ab12de8 --- /dev/null +++ b/sd/source/filter/ppt/ppt97animations.hxx @@ -0,0 +1,158 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPT_97_ANIMATIONS_HXX +#define _SD_PPT_97_ANIMATIONS_HXX + +// header for class SvStream +#include <tools/stream.hxx> + +class SdrObject; +class Ppt97Animation; + +// helper class for reading PPT AnimationInfoAtom +class Ppt97AnimationInfoAtom +{ + friend class Ppt97Animation; + +//-- member + UINT32 nDimColor; + UINT32 nFlags; // 0x0004: time instead of click + UINT32 nSoundRef; + INT32 nDelayTime; // 1/1000 sec + UINT16 nOrderID; + UINT16 nSlideCount; + UINT8 nBuildType; + UINT8 nFlyMethod; + UINT8 nFlyDirection; + UINT8 nAfterEffect; //nAfterEffect: 0: none; 1: change color; 2: dim on next effect; 3: dim after effect; + UINT8 nSubEffect; + UINT8 nOLEVerb; + + // unknown, because whole size needs to be 28 + UINT8 nUnknown1; + UINT8 nUnknown2; + +//-- methods + void ReadStream( SvStream& rIn ); +/* + nFlags: + decimal / hexadecimal / binary + 1040 0x00000410 10000010000 mouseclick + 17428 0x00004414 100010000010100 after previous 0 sec (animate form) + 17412 0x00004404 100010000000100 after previous 0 sec + 1088 0x00000440 10001000000 stop previous sound and mouseclick + 1044 0x00000414 10000010100 play sound automatic + 1041 0x00000411 10000010001 + | | | | | | + | | | | | reverse order + | | | | after previous + | | | sound + | | stop previous sound + | ? + animate form + + nAfterEffect: + 1: color + 0: nothing + 3: hide after animation + 2: hide at next mouse click +*/ +}; + +class Ppt97Animation +{ + /** this is a helping class for import of PPT 97 animations + 1. use the constructor Ppt97Animation( SvStream& rIn ) to import informations from the stream + 2. use the set methods to modify and complete the data + 3. use the method createAndSetCustomAnimationEffect( ) to create an effect in sd model + */ + +public: //public methods + Ppt97Animation( SvStream& rIn ); + + Ppt97Animation(); + Ppt97Animation( const Ppt97Animation& rAnimation ); + Ppt97Animation& operator= ( const Ppt97Animation& rAnimation ); + bool operator < ( const Ppt97Animation& rAnimation ) const;//later is greater + bool operator > ( const Ppt97Animation& rAnimation ) const;//later is greater + ~Ppt97Animation(); + + //get methods + bool HasEffect() const; + bool HasParagraphEffect() const; + bool HasSoundEffect() const; + sal_Int32 GetDimColor() const; + UINT32 GetSoundRef() const; + bool HasAnimateAssociatedShape() const; //true if the shape should be animated in addition to the text + + //set methods + void SetDimColor( sal_Int32 nDimColor ); + void SetSoundFileUrl( const ::rtl::OUString& rSoundFileUrl ); + void SetAnimateAssociatedShape( bool bAnimate ); //true if the shape should be animated in addition to the text + + //action methods + /** this method creates a CustomAnimationEffect for the given SdrObject + from internal data and stores the created effect at the draw model + */ + void createAndSetCustomAnimationEffect( SdrObject* pObj ); + +private: //private methods + + //read methods + ::rtl::OUString GetPresetId() const; + ::rtl::OUString GetPresetSubType() const; + bool HasAfterEffect() const; + bool HasAfterEffect_ChangeColor() const; + bool HasAfterEffect_DimAtNextEffect() const; + bool HasAfterEffect_DimAfterEffect() const; + bool HasStopPreviousSound() const; + bool HasReverseOrder() const; //true if the text paragraphs should be animated in reverse order + sal_Int32 GetParagraphLevel() const; //paragraph level that is animated ( that paragraph and higher levels ) + sal_Int16 GetTextAnimationType() const; //see com::sun::star::presentation::TextAnimationType + sal_Int16 GetEffectNodeType() const; //see com::sun::star::presentation::EffectNodeType + double GetDelayTimeInSeconds() const;//-1 for start on mouseclick or >= 0 for a delay in seconds for automatic start + bool GetSpecialDuration( double& rfDurationInSeconds ) const; + bool GetSpecialTextIterationDelay( double& rfTextIterationDelay ) const; + + void UpdateCacheData() const; + void ClearCacheData() const; + +private: //private member + //input information: + Ppt97AnimationInfoAtom m_aAtom;//pure input from stream + ::rtl::OUString m_aSoundFileUrl;//this needs to be set in addition from outside as this class has not the knowledge to translate the sound bits to a file url/ + + //cached generated output information: + mutable bool m_bDirtyCache; + mutable ::rtl::OUString m_aPresetId; // m_aPresetId and m_aSubType match to the values in sd/xml/effects.xml + mutable ::rtl::OUString m_aSubType; + mutable bool m_bHasSpecialDuration; + mutable double m_fDurationInSeconds; +}; + +#endif diff --git a/sd/source/filter/ppt/pptanimations.hxx b/sd/source/filter/ppt/pptanimations.hxx new file mode 100644 index 000000000000..7f227476e872 --- /dev/null +++ b/sd/source/filter/ppt/pptanimations.hxx @@ -0,0 +1,559 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPT_ANIMATIONS_HXX +#define _SD_PPT_ANIMATIONS_HXX + +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/animations/TransitionType.hpp> +#include <com/sun/star/animations/TransitionSubType.hpp> +#include <com/sun/star/presentation/EffectPresetClass.hpp> + +#include <map> +#include <sal/types.h> + +class SvStream; + +namespace ppt +{ + +// old transition types +#define PPT_TRANSITION_TYPE_NONE 0 +#define PPT_TRANSITION_TYPE_RANDOM 1 +#define PPT_TRANSITION_TYPE_BLINDS 2 +#define PPT_TRANSITION_TYPE_CHECKER 3 +#define PPT_TRANSITION_TYPE_COVER 4 +#define PPT_TRANSITION_TYPE_DISSOLVE 5 +#define PPT_TRANSITION_TYPE_FADE 6 +#define PPT_TRANSITION_TYPE_PULL 7 +#define PPT_TRANSITION_TYPE_RANDOM_BARS 8 +#define PPT_TRANSITION_TYPE_STRIPS 9 +#define PPT_TRANSITION_TYPE_WIPE 10 +#define PPT_TRANSITION_TYPE_ZOOM 11 +#define PPT_TRANSITION_TYPE_SPLIT 13 + +// effects, new in xp +#define PPT_TRANSITION_TYPE_DIAMOND 17 +#define PPT_TRANSITION_TYPE_PLUS 18 +#define PPT_TRANSITION_TYPE_WEDGE 19 +#define PPT_TRANSITION_TYPE_PUSH 20 +#define PPT_TRANSITION_TYPE_COMB 21 +#define PPT_TRANSITION_TYPE_NEWSFLASH 22 +#define PPT_TRANSITION_TYPE_SMOOTHFADE 23 +#define PPT_TRANSITION_TYPE_WHEEL 26 +#define PPT_TRANSITION_TYPE_CIRCLE 27 + + + +// atoms +#define DFF_msofbtAnimEvent 0xf125 +#define DFF_msofbtAnimNode 0xf127 +#define DFF_msofbtAnimTrigger 0xf128 +#define DFF_msofbtAnimValue 0xf129 +#define DFF_msofbtAnimateTarget 0xf12a +#define DFF_msofbtAnimate 0xf12b +#define DFF_msofbtAnimateColor 0xf12c +#define DFF_msofbtAnimateFilter 0xf12d +#define DFF_msofbtAnimateMotion 0xf12e +#define DFF_msofbtAnimateRotation 0xf12f +#define DFF_msofbtAnimateScale 0xf130 +#define DFF_msofbtAnimateSet 0xf131 +#define DFF_msofbtAnimCommand 0xf132 +#define DFF_msofbtAnimateTargetSettings 0xf133 +#define DFF_msofbtAnimateData 0xf134 +#define DFF_msofbtAnimateColorData 0xf135 +#define DFF_msofbtAnimateFilterData 0xf136 +#define DFF_msofbtAnimateMotionData 0xf137 +#define DFF_msofbtAnimateScaleData 0xf139 +#define DFF_msofbtAnimateSetData 0xf13a +#define DFF_msofbtCommandData 0xf13b +#define DFF_msofbtAnimateTargetElement 0xf13c +#define DFF_msofbtAnimPropertySet 0xf13d +#define DFF_msofbtAnimateAttributeNames 0xf13e +#define DFF_msofbtAnimKeyPoints 0xf13f +#define DFF_msofbtAnimIteration 0xf140 +#define DFF_msofbtAnimAction 0xf141 // correct name?? +#define DFF_msofbtAnimAttributeValue 0xf142 +#define DFF_msofbtAnimKeyTime 0xf143 +#define DFF_msofbtAnimGroup 0xf144 +#define DFF_msofbtAnimSubGoup 0xf145 +#define DFF_msofbtAnimateRotationData 0xf138 +#define DFF_msofbtAnimReference 0x2afb + +// property ids +#define DFF_ANIM_ID 1 +#define DFF_ANIM_RUNTIMECONTEXT 2 +#define DFF_ANIM_PATH_EDIT_MODE 3 +#define DFF_ANIM_COLORSPACE 4 +#define DFF_ANIM_DIRECTION 5 // TODO: Conflict? +#define DFF_ANIM_MASTERREL 5 // TODO: Conflict? +#define DFF_ANIM_OVERRIDE 6 +#define DFF_ANIM_PRESET_ID 9 +#define DFF_ANIM_PRESET_SUB_TYPE 10 +#define DFF_ANIM_PRESET_CLASS 11 +#define DFF_ANIM_AFTEREFFECT 13 +#define DFF_ANIM_ENDAFTERSLIDE 15 +#define DFF_ANIM_TIMEFILTER 16 +#define DFF_ANIM_EVENT_FILTER 17 +#define DFF_ANIM_GROUP_ID 19 +#define DFF_ANIM_NODE_TYPE 20 +#define DFF_ANIM_VOLUME 22 +#define DFF_ANIM_PROPERTY_ID_COUNT DFF_ANIM_VOLUME + + + +// property types +#define DFF_ANIM_PROP_TYPE_BYTE 0 +#define DFF_ANIM_PROP_TYPE_INT32 1 +#define DFF_ANIM_PROP_TYPE_FLOAT 2 +#define DFF_ANIM_PROP_TYPE_UNISTRING 3 + +#define DFF_ANIM_PATH_EDIT_MODE_FIXED 0 +#define DFF_ANIM_PATH_EDIT_MODE_RELATIVE 1 + +#define DFF_ANIM_PRESS_CLASS_USER_DEFINED 0 +#define DFF_ANIM_PRESS_CLASS_ENTRANCE 1 +#define DFF_ANIM_PRESS_CLASS_EXIT 2 +#define DFF_ANIM_PRESS_CLASS_EMPHASIS 3 +#define DFF_ANIM_PRESS_CLASS_MOTIONPATH 4 +#define DFF_ANIM_PRESS_CLASS_OLE_ACTION 5 +#define DFF_ANIM_PRESS_CLASS_MEDIACALL 6 + +#define DFF_ANIM_NODE_TYPE_ON_CLICK 1 +#define DFF_ANIM_NODE_TYPE_WITH_PREVIOUS 2 +#define DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS 3 +#define DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE 4 +#define DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ 5 +#define DFF_ANIM_NODE_TYPE_TIMING_ROOT 9 + +#define DFF_ANIM_PROPERTY_AFTEREFFECT 20 + +/* constants for fill entry in AnimationNode */ +const sal_Int32 mso_Anim_GroupType_PAR = 0; +const sal_Int32 mso_Anim_GroupType_SEQ = 1; +const sal_Int32 mso_Anim_GroupType_NODE = 3; +const sal_Int32 mso_Anim_GroupType_MEDIA = 4; + +/* constants for fill entry in AnimationNode */ +const sal_Int32 mso_Anim_Fill_ALWAYS = 1; +const sal_Int32 mso_Anim_Fill_WHENOFF = 2; +const sal_Int32 mso_Anim_Fill_NEVER = 3; + +/* constants for fill entry in AnimationNode */ +const sal_Int32 mso_Anim_Fill_REMOVE = 1; +const sal_Int32 mso_Anim_Fill_FREEZE = 2; +const sal_Int32 mso_Anim_Fill_HOLD = 3; + +/* constants for behaviour entry in PPtAnimationNode */ +const sal_Int32 mso_Anim_Behaviour_FILTER = 24; +const sal_Int32 mso_Anim_Behaviour_ANIMATION= 25; + +typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > PropertySetMap_t; + +class PropertySet +{ +public: + PropertySetMap_t maProperties; + + bool hasProperty( sal_Int32 nProperty ) const; + ::com::sun::star::uno::Any getProperty( sal_Int32 nProperty ) const; +}; + + +enum MS_AttributeNames +{ + MS_PPT_X, MS_PPT_Y, MS_PPT_W, MS_PPT_H, MS_PPT_C, MS_R, MS_XSHEAR, MS_FILLCOLOR, MS_FILLTYPE, + MS_STROKECOLOR, MS_STROKEON, MS_STYLECOLOR, MS_STYLEROTATION, MS_FONTWEIGHT, + MS_STYLEUNDERLINE, MS_STYLEFONTFAMILY, MS_STYLEFONTSIZE, MS_STYLEFONTSTYLE, + MS_STYLEVISIBILITY, MS_STYLEOPACITY, MS_UNKNOWN +}; + +struct ImplAttributeNameConversion +{ + MS_AttributeNames meAttribute; + const char* mpMSName; + const char* mpAPIName; +}; + +/** this atom is the first entry in each animation group */ +struct AnimationNode +{ +public: + /** see mso_Anim_GroupType_? */ + sal_Int32 mnGroupType; + + /** see mso_Anim_Restart_? */ + sal_Int32 mnRestart; + + /** see mso_Anim_Fill_? */ + sal_Int32 mnFill; + + /** see mso_Anim_Behaviour_? */ + sal_Int32 mnNodeType; + + /** duration of this group in 1000th seconds */ + sal_Int32 mnDuration; + + sal_Int32 mnU1, mnU3, mnU4; + +public: + + friend SvStream& operator>>(SvStream& rIn, AnimationNode& rAtom); + friend SvStream& operator<<(SvStream& rOut, AnimationNode& rAtom); +}; + +static const ImplAttributeNameConversion gImplConversionList[] = +{ + { MS_PPT_X, "ppt_x", "X" }, + { MS_PPT_Y, "ppt_y", "Y" }, + { MS_PPT_W, "ppt_w", "Width" }, + { MS_PPT_H, "ppt_h", "Height" }, + { MS_PPT_C, "ppt_c", "DimColor" }, + { MS_R, "r", "Rotate" }, + { MS_XSHEAR, "xshear", "SkewX" }, + { MS_FILLCOLOR, "fillColor", "FillColor" }, + { MS_FILLCOLOR, "fillcolor", "FillColor" }, + { MS_FILLTYPE, "fill.type", "FillStyle" }, + { MS_STROKECOLOR, "stroke.color", "LineColor" }, + { MS_STROKEON, "stroke.on", "LineStyle" }, + { MS_STYLECOLOR, "style.color", "CharColor" }, + { MS_STYLEROTATION, "style.rotation", "Rotate" }, + { MS_FONTWEIGHT, "style.fontWeight", "CharWeight" }, + { MS_STYLEUNDERLINE, "style.textDecorationUnderline","CharUnderline" }, + { MS_STYLEFONTFAMILY, "style.fontFamily", "CharFontName" }, + { MS_STYLEFONTSIZE, "style.fontSize", "CharHeight" }, + { MS_STYLEFONTSTYLE, "style.fontStyle", "CharPosture" }, + { MS_STYLEVISIBILITY, "style.visibility", "Visibility" }, + { MS_STYLEOPACITY, "style.opacity", "Opacity" }, + { MS_UNKNOWN, NULL, NULL } +}; + +struct transition +{ + const sal_Char* mpName; + sal_Int16 mnType; + sal_Int16 mnSubType; + sal_Bool mbDirection; // true: default geometric direction + + static const transition* find( const rtl::OUString& rName ); + static const sal_Char* find( const sal_Int16 mnType, const sal_Int16 mnSubType, const sal_Bool bDirection ); +}; +static const transition gTransitions[] = +{ +{ "wipe(up)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::TOPTOBOTTOM, sal_True }, +{ "wipe(right)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::LEFTTORIGHT, sal_False }, +{ "wipe(left)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::LEFTTORIGHT, sal_True }, +{ "wipe(down)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::TOPTOBOTTOM, sal_False }, +{ "wheel(1)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::ONEBLADE, sal_True }, +{ "wheel(2)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::TWOBLADEVERTICAL, sal_True }, +{ "wheel(3)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::THREEBLADE, sal_True }, +{ "wheel(4)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::FOURBLADE, sal_True }, +{ "wheel(8)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::EIGHTBLADE, sal_True }, +{ "strips(downLeft)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALRIGHT, sal_True }, +{ "strips(upLeft)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALLEFT, sal_False }, +{ "strips(downRight)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALLEFT, sal_True }, +{ "strips(upRight)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALRIGHT, sal_False }, +{ "barn(inVertical)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_False }, +{ "barn(outVertical)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True }, +{ "barn(inHorizontal)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_False }, +{ "barn(outHorizontal)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True }, +{ "randombar(vertical)", ::com::sun::star::animations::TransitionType::RANDOMBARWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True}, +{ "randombar(horizontal)", ::com::sun::star::animations::TransitionType::RANDOMBARWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True }, +{ "checkerboard(down)", ::com::sun::star::animations::TransitionType::CHECKERBOARDWIPE, ::com::sun::star::animations::TransitionSubType::DOWN, sal_True}, +{ "checkerboard(across)", ::com::sun::star::animations::TransitionType::CHECKERBOARDWIPE, ::com::sun::star::animations::TransitionSubType::ACROSS, sal_True }, +{ "plus(out)", ::com::sun::star::animations::TransitionType::FOURBOXWIPE, ::com::sun::star::animations::TransitionSubType::CORNERSIN, sal_False }, +{ "plus(in)", ::com::sun::star::animations::TransitionType::FOURBOXWIPE, ::com::sun::star::animations::TransitionSubType::CORNERSIN, sal_True }, +{ "diamond(out)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::DIAMOND, sal_True }, +{ "diamond(in)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::DIAMOND, sal_False }, +{ "circle(out)", ::com::sun::star::animations::TransitionType::ELLIPSEWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True }, +{ "circle(in)", ::com::sun::star::animations::TransitionType::ELLIPSEWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_False }, +{ "box(out)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::RECTANGLE, sal_True }, +{ "box(in)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::RECTANGLE, sal_False }, +{ "wedge", ::com::sun::star::animations::TransitionType::FANWIPE, ::com::sun::star::animations::TransitionSubType::CENTERTOP, sal_True }, +{ "blinds(vertical)", ::com::sun::star::animations::TransitionType::BLINDSWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True }, +{ "blinds(horizontal)", ::com::sun::star::animations::TransitionType::BLINDSWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True }, +{ "fade", ::com::sun::star::animations::TransitionType::FADE, ::com::sun::star::animations::TransitionSubType::CROSSFADE, sal_True }, +{ "slide(fromTop)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMTOP, sal_True }, +{ "slide(fromRight)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMRIGHT, sal_True }, +{ "slide(fromLeft)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMLEFT, sal_True }, +{ "slide(fromBottom)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMBOTTOM, sal_True }, +{ "dissolve", ::com::sun::star::animations::TransitionType::DISSOLVE, ::com::sun::star::animations::TransitionSubType::DEFAULT, sal_True }, +{ "image", ::com::sun::star::animations::TransitionType::DISSOLVE, ::com::sun::star::animations::TransitionSubType::DEFAULT, sal_True }, // TODO +{ NULL, 0, 0, sal_False } +}; + +struct convert_subtype +{ + sal_Int32 mnID; + const sal_Char* mpStrSubType; +}; +static const convert_subtype gConvertArray[] = +{ + // fly in + { 1, "from-top" }, + { 2, "from-right" }, + { 3, "from-top-right" }, + { 4, "from-bottom" }, + { 5, "horizontal" }, + { 6, "from-bottom-right" }, + { 8, "from-left" }, + { 9, "from-top-left" }, + { 10, "vertical" }, + { 12, "from-bottom-left" }, + { 16, "in" }, + { 21, "vertical-in" }, + { 26, "horizontal-in" }, + { 32, "out" }, + { 36, "out-from-screen-center" }, + { 37, "vertical-out" }, + { 42, "horizontal-out" }, + { 272, "in-slightly" }, + { 288, "out-slightly" }, + { 528, "in-from-screen-center" }, + { 0, 0 } +}; + +struct preset_maping +{ + sal_Int32 mnPresetClass; + sal_Int32 mnPresetId; + const sal_Char* mpStrPresetId; +}; + +static const preset_maping gPresetMaping[] = +{ + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 1 ,"ooo-entrance-appear" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 2 ,"ooo-entrance-fly-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 3 ,"ooo-entrance-venetian-blinds" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 4 ,"ooo-entrance-box" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 5 ,"ooo-entrance-checkerboard" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 6 ,"ooo-entrance-circle" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 7 ,"ooo-entrance-fly-in-slow" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 8 ,"ooo-entrance-diamond" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 9 ,"ooo-entrance-dissolve-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 10 ,"ooo-entrance-fade-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 11 ,"ooo-entrance-flash-once" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 12 ,"ooo-entrance-peek-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 13 ,"ooo-entrance-plus" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 14 ,"ooo-entrance-random-bars" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 15 ,"ooo-entrance-spiral-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 16 ,"ooo-entrance-split" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 17 ,"ooo-entrance-stretchy" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 18 ,"ooo-entrance-diagonal-squares" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 19 ,"ooo-entrance-swivel" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 20 ,"ooo-entrance-wedge" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 21 ,"ooo-entrance-wheel" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 22 ,"ooo-entrance-wipe" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 23 ,"ooo-entrance-zoom" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 24 ,"ooo-entrance-random" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 25 ,"ooo-entrance-boomerang" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 26 ,"ooo-entrance-bounce" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 27 ,"ooo-entrance-colored-lettering" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 28 ,"ooo-entrance-movie-credits" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 29 ,"ooo-entrance-ease-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 30 ,"ooo-entrance-float" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 31 ,"ooo-entrance-turn-and-grow" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 34 ,"ooo-entrance-breaks" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 35 ,"ooo-entrance-pinwheel" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 37 ,"ooo-entrance-rise-up" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 38 ,"ooo-entrance-falling-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 39 ,"ooo-entrance-thread" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 40 ,"ooo-entrance-unfold" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 41 ,"ooo-entrance-whip" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 42 ,"ooo-entrance-ascend" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 43 ,"ooo-entrance-center-revolve" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 45 ,"ooo-entrance-fade-in-and-swivel" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 47 ,"ooo-entrance-descend" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 48 ,"ooo-entrance-sling" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 49 ,"ooo-entrance-spin-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 50 ,"ooo-entrance-compress" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 51 ,"ooo-entrance-magnify" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 52 ,"ooo-entrance-curve-up" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 53 ,"ooo-entrance-fade-in-and-zoom" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 54 ,"ooo-entrance-glide" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 55 ,"ooo-entrance-expand" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 56 ,"ooo-entrance-flip" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 58 ,"ooo-entrance-fold" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 1 ,"ooo-emphasis-fill-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 2 ,"ooo-emphasis-font" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 3 ,"ooo-emphasis-font-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 4 ,"ooo-emphasis-font-size" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 5 ,"ooo-emphasis-font-style" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 6 ,"ooo-emphasis-grow-and-shrink" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 7 ,"ooo-emphasis-line-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 8 ,"ooo-emphasis-spin" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 9 ,"ooo-emphasis-transparency" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 10 ,"ooo-emphasis-bold-flash" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 14 ,"ooo-emphasis-blast" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 15 ,"ooo-emphasis-bold-reveal" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 16 ,"ooo-emphasis-color-over-by-word" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 18 ,"ooo-emphasis-reveal-underline" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 19 ,"ooo-emphasis-color-blend" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 20 ,"ooo-emphasis-color-over-by-letter" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 21 ,"ooo-emphasis-complementary-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 22 ,"ooo-emphasis-complementary-color-2" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 23 ,"ooo-emphasis-contrasting-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 24 ,"ooo-emphasis-darken" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 25 ,"ooo-emphasis-desaturate" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 26 ,"ooo-emphasis-flash-bulb" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 27 ,"ooo-emphasis-flicker" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 28 ,"ooo-emphasis-grow-with-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 30 ,"ooo-emphasis-lighten" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 31 ,"ooo-emphasis-style-emphasis" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 32 ,"ooo-emphasis-teeter" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 33 ,"ooo-emphasis-vertical-highlight" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 34 ,"ooo-emphasis-wave" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 35 ,"ooo-emphasis-blink" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 36 ,"ooo-emphasis-shimmer" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 1 ,"ooo-exit-disappear" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 2 ,"ooo-exit-fly-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 3 ,"ooo-exit-venetian-blinds" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 4 ,"ooo-exit-box" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 5 ,"ooo-exit-checkerboard" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 6 ,"ooo-exit-circle" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 7 ,"ooo-exit-crawl-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 8 ,"ooo-exit-diamond" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 9 ,"ooo-exit-dissolve" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 10 ,"ooo-exit-fade-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 11 ,"ooo-exit-flash-once" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 12 ,"ooo-exit-peek-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 13 ,"ooo-exit-plus" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 14 ,"ooo-exit-random-bars" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 15 ,"ooo-exit-spiral-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 16 ,"ooo-exit-split" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 17 ,"ooo-exit-collapse" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 18 ,"ooo-exit-diagonal-squares" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 19 ,"ooo-exit-swivel" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 20 ,"ooo-exit-wedge" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 21 ,"ooo-exit-wheel" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 22 ,"ooo-exit-wipe" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 23 ,"ooo-exit-zoom" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 24 ,"ooo-exit-random" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 25 ,"ooo-exit-boomerang" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 26 ,"ooo-exit-bounce" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 27 ,"ooo-exit-colored-lettering" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 28 ,"ooo-exit-movie-credits" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 29 ,"ooo-exit-ease-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 30 ,"ooo-exit-float" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 31 ,"ooo-exit-turn-and-grow" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 34 ,"ooo-exit-breaks" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 35 ,"ooo-exit-pinwheel" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 37 ,"ooo-exit-sink-down" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 38 ,"ooo-exit-swish" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 39 ,"ooo-exit-thread" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 40 ,"ooo-exit-unfold" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 41 ,"ooo-exit-whip" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 42 ,"ooo-exit-descend" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 43 ,"ooo-exit-center-revolve" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 45 ,"ooo-exit-fade-out-and-swivel" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 47 ,"ooo-exit-ascend" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 48 ,"ooo-exit-sling" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 53 ,"ooo-exit-fade-out-and-zoom" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 55 ,"ooo-exit-contract" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 49 ,"ooo-exit-spin-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 50 ,"ooo-exit-stretchy" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 51 ,"ooo-exit-magnify" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 52 ,"ooo-exit-curve-down" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 54 ,"ooo-exit-glide" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 56 ,"ooo-exit-flip" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 58 ,"ooo-exit-fold" }, + + + + + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 16 ,"ooo-motionpath-4-point-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 5 ,"ooo-motionpath-5-point-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 11 ,"ooo-motionpath-6-point-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 17 ,"ooo-motionpath-8-point-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 1 ,"ooo-motionpath-circle" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 6 ,"ooo-motionpath-crescent-moon" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 3 ,"ooo-motionpath-diamond" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 13 ,"ooo-motionpath-equal-triangle" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 12 ,"ooo-motionpath-oval" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 9 ,"ooo-motionpath-heart" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 4 ,"ooo-motionpath-hexagon" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 10 ,"ooo-motionpath-octagon" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 14 ,"ooo-motionpath-parallelogram" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 15 ,"ooo-motionpath-pentagon" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 2 ,"ooo-motionpath-right-triangle" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 7 ,"ooo-motionpath-square" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 18 ,"ooo-motionpath-teardrop" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 8 ,"ooo-motionpath-trapezoid" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 37 ,"ooo-motionpath-arc-down" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 51 ,"ooo-motionpath-arc-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 58 ,"ooo-motionpath-arc-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 44 ,"ooo-motionpath-arc-up" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 41 ,"ooo-motionpath-bounce-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 54 ,"ooo-motionpath-bounce-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 48 ,"ooo-motionpath-curvy-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 61 ,"ooo-motionpath-curvy-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 60 ,"ooo-motionpath-decaying-wave" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 49 ,"ooo-motionpath-diagonal-down-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 56 ,"ooo-motionpath-diagonal-up-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 42 ,"ooo-motionpath-down" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 52 ,"ooo-motionpath-funnel" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 53 ,"ooo-motionpath-spring" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 62 ,"ooo-motionpath-stairs-down" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 50 ,"ooo-motionpath-turn-down" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 36 ,"ooo-motionpath-turn-down-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 43 ,"ooo-motionpath-turn-up" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 57 ,"ooo-motionpath-turn-up-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 64 ,"ooo-motionpath-up" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 47 ,"ooo-motionpath-wave" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 38 ,"ooo-motionpath-zigzag" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 31 ,"ooo-motionpath-bean" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 25 ,"ooo-motionpath-buzz-saw" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 20 ,"ooo-motionpath-curved-square" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 21 ,"ooo-motionpath-curved-x" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 23 ,"ooo-motionpath-curvy-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 28 ,"ooo-motionpath-figure-8-four" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 26 ,"ooo-motionpath-horizontal-figure-8" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 34 ,"ooo-motionpath-inverted-square" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 33 ,"ooo-motionpath-inverted-triangle" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 24 ,"ooo-motionpath-loop-de-loop" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 29 ,"ooo-motionpath-neutron" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 27 ,"ooo-motionpath-peanut" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 32 ,"ooo-motionpath-clover" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 19 ,"ooo-motionpath-pointy-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 30 ,"ooo-motionpath-swoosh" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 22 ,"ooo-motionpath-vertical-figure-8" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 35 ,"ooo-motionpath-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 63 ,"ooo-motionpath-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 55 ,"ooo-motionpath-spiral-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 46 ,"ooo-motionpath-spiral-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 40 ,"ooo-motionpath-sine-wave" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 59 ,"ooo-motionpath-s-curve-1" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 39 ,"ooo-motionpath-s-curve-2" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 45 ,"ooo-motionpath-heartbeat" }, + + + { 0,0,0 } +}; + +} // namespace ppt + +#endif diff --git a/sd/source/filter/ppt/pptatom.cpp b/sd/source/filter/ppt/pptatom.cpp new file mode 100644 index 000000000000..21a0c3c3f9f8 --- /dev/null +++ b/sd/source/filter/ppt/pptatom.cpp @@ -0,0 +1,123 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _STREAM_HXX +#include <tools/stream.hxx> +#endif + +#ifndef _PPTATOM_HXX_ +#include "pptatom.hxx" +#endif + +using namespace ppt; + +Atom::Atom( const DffRecordHeader& rRecordHeader, SvStream& rStream ) +: mrStream( rStream ) +, maRecordHeader( rRecordHeader ) +, mpFirstChild( 0 ) +, mpNextAtom( 0 ) +{ + if( isContainer() ) + { + if( seekToContent() ) + { + DffRecordHeader aChildHeader; + + Atom* pLastAtom = NULL; + + while( (mrStream.GetError() == 0 ) && ( mrStream.Tell() < maRecordHeader.GetRecEndFilePos() ) ) + { + mrStream >> aChildHeader; + + if( mrStream.GetError() == 0 ) + { + Atom* pAtom = new Atom( aChildHeader, mrStream ); + + if( pLastAtom ) + pLastAtom->mpNextAtom = pAtom; + if( mpFirstChild == NULL ) + mpFirstChild = pAtom; + + pLastAtom = pAtom; + } + } + } + } + + maRecordHeader.SeekToEndOfRecord( mrStream ); +} + +Atom::~Atom() +{ + Atom* pChild = mpFirstChild; + while( pChild ) + { + Atom* pNextChild = pChild->mpNextAtom; + delete pChild; + pChild = pNextChild; + } +} + +/** imports this atom and its child atoms */ +Atom* Atom::import( const DffRecordHeader& rRootRecordHeader, SvStream& rStCtrl ) +{ + Atom* pRootAtom = new Atom( rRootRecordHeader, rStCtrl ); + + if( rStCtrl.GetError() == 0 ) + { + return pRootAtom; + } + else + { + delete pRootAtom; + return NULL; + } +} + +/** returns the next child atom after pLast with nRecType or NULL */ +const Atom* Atom::findNextChildAtom( sal_uInt16 nRecType, const Atom* pLast ) const +{ + Atom* pChild = pLast != NULL ? pLast->mpNextAtom : mpFirstChild; + while( pChild && pChild->maRecordHeader.nRecType != nRecType ) + { + pChild = pChild->mpNextAtom; + } + + return pChild; +} + +/** returns the next child atom after pLast with nRecType and nRecInstance or NULL */ +const Atom* Atom::findNextChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance, const Atom* pLast ) const +{ + const Atom* pChild = pLast != NULL ? pLast->mpNextAtom : mpFirstChild; + while( pChild && (pChild->maRecordHeader.nRecType != nRecType) && (pChild->maRecordHeader.nRecInstance != nRecInstance) ) + { + pChild = findNextChildAtom( pChild ); + } + + return pChild; +} diff --git a/sd/source/filter/ppt/pptatom.hxx b/sd/source/filter/ppt/pptatom.hxx new file mode 100644 index 000000000000..0b13dc314584 --- /dev/null +++ b/sd/source/filter/ppt/pptatom.hxx @@ -0,0 +1,160 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PPTATOM_HXX_ +#define _PPTATOM_HXX_ + +#include <svx/msdffdef.hxx> +#include <filter/msfilter/msdffimp.hxx> + +class SvStream; + +namespace ppt +{ + +class Atom +{ +public: + ~Atom(); + + /** imports this atom and its child atoms */ + static Atom* import( const DffRecordHeader& rRootRecordHeader, SvStream& rStCtrl ); + + inline const DffRecordHeader& getHeader() const; + + /** returns true if at least one atim with the given nRecType is found */ + inline bool hasChildAtom( sal_uInt16 nRecType ) const; + + /** returns true if at least one atim with the given nRecType and nRecInstnace is found */ + inline bool hasChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const; + + /** returns the first child atom with nRecType or NULL */ + inline const Atom* findFirstChildAtom( sal_uInt16 nRecType ) const; + + /** returns the next child atom after pLast with nRecType or NULL */ + const Atom* findNextChildAtom( sal_uInt16 nRecType, const Atom* pLast ) const; + + /** returns the first child atom with nRecType and nRecInstance or NULL */ + inline const Atom* findFirstChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const; + + /** returns the next child atom after pLast with nRecType and nRecInstance or NULL */ + const Atom* findNextChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance, const Atom* pLast ) const; + + /** returns the first child atom or NULL */ + inline const Atom* findFirstChildAtom() const; + + /** returns the next child atom after pLast or NULL */ + inline const Atom* findNextChildAtom( const Atom* pLast ) const; + + /** returns true if this atom is a container */ + inline bool isContainer() const; + + /** seeks to the contents of this atom */ + inline bool seekToContent() const; + + /** returns the record type */ + inline sal_uInt16 getType() const; + + /** returns the record instance */ + inline sal_uInt16 getInstance() const; + + /** returns the record length */ + inline sal_uInt32 getLength() const; + +private: + Atom( const DffRecordHeader& rRecordHeader, SvStream& rStCtrl ); + + SvStream& mrStream; + DffRecordHeader maRecordHeader; + Atom* mpFirstChild; + Atom* mpNextAtom; +}; + +inline bool Atom::hasChildAtom( sal_uInt16 nRecType ) const +{ + return findFirstChildAtom( nRecType ) != NULL; +} + +inline bool Atom::hasChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const +{ + return findFirstChildAtom( nRecType, nRecInstance ) != NULL; +} + +inline const Atom* Atom::findFirstChildAtom( sal_uInt16 nRecType ) const +{ + return findNextChildAtom( nRecType, NULL ); +} + +inline const DffRecordHeader& Atom::getHeader() const +{ + return maRecordHeader; +} + +inline const Atom* Atom::findFirstChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const +{ + return findNextChildAtom( nRecType, nRecInstance, NULL ); +} + +inline const Atom* Atom::findFirstChildAtom() const +{ + return mpFirstChild; +} + +inline const Atom* Atom::findNextChildAtom( const Atom* pLast ) const +{ + return pLast ? pLast->mpNextAtom : pLast; +} + +inline bool Atom::isContainer() const +{ + return (bool)maRecordHeader.IsContainer(); +} + +inline bool Atom::seekToContent() const +{ + maRecordHeader.SeekToContent( mrStream ); + return mrStream.GetError() == 0; +} + +inline sal_uInt16 Atom::getType() const +{ + return maRecordHeader.nRecType; +} + +inline sal_uInt16 Atom::getInstance() const +{ + return maRecordHeader.nRecInstance; +} + +inline sal_uInt32 Atom::getLength() const +{ + return maRecordHeader.nRecLen; +} + +} // namespace ppt + +#endif diff --git a/sd/source/filter/ppt/pptin.cxx b/sd/source/filter/ppt/pptin.cxx new file mode 100755 index 000000000000..6a5ce08bc912 --- /dev/null +++ b/sd/source/filter/ppt/pptin.cxx @@ -0,0 +1,2762 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include <editeng/numitem.hxx> + +#include <unotools/ucbstreamhelper.hxx> +#include <vcl/wrkwin.hxx> +#include <svl/urihelper.hxx> +#include <svx/svxids.hrc> +#include <filter/msfilter/svdfppt.hxx> +#include <svx/svditer.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/app.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdlayer.hxx> +#include <vcl/msgbox.hxx> +#include <svl/style.hxx> +#include <svx/xflclit.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/colritem.hxx> +#include <svl/whiter.hxx> +#include <svx/xgrad.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xbtmpit.hxx> +#include <svx/xlnclit.hxx> +#include <editeng/adjitem.hxx> +#include <editeng/editeng.hxx> +#include <editeng/bulitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/lspcitem.hxx> +#include <editeng/tstpitem.hxx> + +#include <sfx2/docinf.hxx> + +#include "glob.hrc" +#include "pptin.hxx" +#include "Outliner.hxx" +#include "drawdoc.hxx" +#include "sdpage.hxx" +#include "sdresid.hxx" +#include "pres.hxx" +#include "sdresid.hxx" +#include "stlpool.hxx" +#include "anminfo.hxx" +#include <svx/gallery.hxx> +#include <tools/urlobj.hxx> +#include <editeng/numitem.hxx> +#include <svl/itempool.hxx> +#include <editeng/fhgtitem.hxx> +#include <svx/svdopage.hxx> +#include <svx/svdomedia.hxx> +#include <svx/svdogrp.hxx> +#include "propread.hxx" +#include <cusshow.hxx> +#include <vcl/bmpacc.hxx> + +#include "../../ui/inc/DrawDocShell.hxx" +#include "../../ui/inc/FrameView.hxx" +#include "../../ui/inc/optsitem.hxx" + +#include <unotools/fltrcfg.hxx> +#include <sfx2/progress.hxx> +#include <unotools/localfilehelper.hxx> +#include <editeng/editstat.hxx> +#include <unotools/pathoptions.hxx> +#include <sfx2/docfac.hxx> +#define MAX_USER_MOVE 2 + +#include "pptinanimations.hxx" +#include "ppt97animations.hxx" + +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> + + +using namespace ::com::sun::star; + + +SdPPTImport::SdPPTImport( SdDrawDocument* pDocument, SvStream& rDocStream, SvStorage& rStorage, SfxMedium& rMedium, MSFilterTracer* pTracer ) +{ + + sal_uInt32 nImportFlags = 0; + +#ifdef DBG_UTIL + PropRead* pSummaryInformation = new PropRead( rStorage, String( RTL_CONSTASCII_USTRINGPARAM( "\005SummaryInformation" ) ) ); + if ( pSummaryInformation->IsValid() ) + { + pSummaryInformation->Read(); + sal_uInt8 aPropSetGUID[ 16 ] = + { + 0xe0, 0x85, 0x9f, 0xf2, 0xf9, 0x4f, 0x68, 0x10, 0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9 + }; + Section* pSection = (Section*)pSummaryInformation->GetSection( aPropSetGUID ); + if ( pSection ) + { + PropItem aPropItem; + if ( pSection->GetProperty( PID_COMMENTS, aPropItem ) ) + { + String aComment; + aPropItem.Read( aComment ); + if ( aComment.Search( String( RTL_CONSTASCII_USTRINGPARAM( "Applixware" ) ), 0 ) != STRING_NOTFOUND ) + { + nImportFlags |= PPT_IMPORTFLAGS_NO_TEXT_ASSERT; + } + } + } + } + delete pSummaryInformation; +#endif + + PowerPointImportParam aParam( rDocStream, nImportFlags, pTracer ); + SvStream* pCurrentUserStream = rStorage.OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Current User" ) ), STREAM_STD_READ ); + if( pCurrentUserStream ) + { + *pCurrentUserStream >> aParam.aCurrentUserAtom; + delete pCurrentUserStream; + } + + if( pDocument ) + { + // iterate over all styles + SdStyleSheetPool* pStyleSheetPool = pDocument->GetSdStyleSheetPool(); + + sal_uInt32 nStyles = pStyleSheetPool ? pStyleSheetPool->GetStyles().size() : 0; + for (sal_uInt32 nStyle = 0; nStyle < nStyles; nStyle++) + { + SfxStyleSheet* pSheet = static_cast<SfxStyleSheet*>( pStyleSheetPool->GetStyles()[nStyle].get() ); + SfxItemSet& rSet = pSheet->GetItemSet(); + + // if autokerning is set in style, override it, ppt has no autokerning + if( rSet.GetItemState( EE_CHAR_PAIRKERNING, FALSE ) == SFX_ITEM_SET ) + rSet.ClearItem( EE_CHAR_PAIRKERNING ); + } + } + + pFilter = new ImplSdPPTImport( pDocument, rStorage, rMedium, aParam ); +} + +sal_Bool SdPPTImport::Import() +{ + return pFilter->Import(); +} + +SdPPTImport::~SdPPTImport() +{ + delete pFilter; +} + +ImplSdPPTImport::ImplSdPPTImport( SdDrawDocument* pDocument, SvStorage& rStorage_, SfxMedium& rMedium, PowerPointImportParam& rParam ) +: SdrPowerPointImport ( rParam, rMedium.GetBaseURL() ) +, mrMed ( rMedium ) +, mrStorage ( rStorage_ ) +, mbDocumentFound ( FALSE ) +, mnFilterOptions ( 0 ) +{ + mpDoc = pDocument; + if ( bOk ) + { + mbDocumentFound = SeekToDocument( &maDocHd ); // maDocHd = the latest DocumentHeader + while ( SeekToRec( rStCtrl, PPT_PST_Document, nStreamLen, &maDocHd ) ) + mbDocumentFound = TRUE; + + UINT32 nDggContainerOfs = 0; + + if ( mbDocumentFound ) + { + ULONG nPosMerk = rStCtrl.Tell(); + + pStData = rStorage_.OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ), STREAM_STD_READ ); + + rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); + ULONG nDocLen = maDocHd.GetRecEndFilePos(); + DffRecordHeader aPPDGHd; + if ( SeekToRec( rStCtrl, PPT_PST_PPDrawingGroup, nDocLen, &aPPDGHd ) ) + { + ULONG nPPDGLen = aPPDGHd.GetRecEndFilePos(); + if ( SeekToRec( rStCtrl, DFF_msofbtDggContainer, nPPDGLen, NULL ) ) + nDggContainerOfs = rStCtrl.Tell(); + } + rStCtrl.Seek( nPosMerk ); + } + sal_uInt32 nSvxMSDffOLEConvFlags2 = 0; + + SvtFilterOptions* pBasOpt = SvtFilterOptions::Get(); + if ( pBasOpt ) + { + if ( pBasOpt->IsLoadPPointBasicCode() ) + mnFilterOptions |= 1; + if ( pBasOpt->IsMathType2Math() ) + nSvxMSDffOLEConvFlags2 |= OLE_MATHTYPE_2_STARMATH; + if ( pBasOpt->IsWinWord2Writer() ) + nSvxMSDffOLEConvFlags2 |= OLE_WINWORD_2_STARWRITER; + if ( pBasOpt->IsExcel2Calc() ) + nSvxMSDffOLEConvFlags2 |= OLE_EXCEL_2_STARCALC; + if ( pBasOpt->IsPowerPoint2Impress() ) + nSvxMSDffOLEConvFlags2 |= OLE_POWERPOINT_2_STARIMPRESS; + } + + InitSvxMSDffManager( nDggContainerOfs, pStData, nSvxMSDffOLEConvFlags2 ); + SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS + | SVXMSDFF_SETTINGS_IMPORT_PPT ); + SetModel( mpDoc, 576 ); + } +} + +////////////////////////////////////////////////////////////////////////// +// +// Dtor +// +////////////////////////////////////////////////////////////////////////// + +ImplSdPPTImport::~ImplSdPPTImport() +{ + for ( void* pPtr = maSlideNameList.First(); pPtr; pPtr = maSlideNameList.Next() ) + delete (String*)pPtr; + delete pStData; +} + +////////////////////////////////////////////////////////////////////////// +// +// Import +// +////////////////////////////////////////////////////////////////////////// + +sal_Bool ImplSdPPTImport::Import() +{ + if ( !bOk ) + return FALSE; + + pSdrModel->setLock( sal_True ); + pSdrModel->EnableUndo(false); + + SdrOutliner& rOutl = mpDoc->GetDrawOutliner(); + sal_uInt32 nControlWord = rOutl.GetEditEngine().GetControlWord(); + nControlWord |= EE_CNTRL_ULSPACESUMMATION; + nControlWord &=~ EE_CNTRL_ULSPACEFIRSTPARA; + ((EditEngine&)rOutl.GetEditEngine()).SetControlWord( nControlWord ); + + SdrLayerAdmin& rAdmin = mpDoc->GetLayerAdmin(); + mnBackgroundLayerID = rAdmin.GetLayerID( String( SdResId( STR_LAYER_BCKGRND )), FALSE ); + mnBackgroundObjectsLayerID = rAdmin.GetLayerID( String( SdResId( STR_LAYER_BCKGRNDOBJ )), FALSE ); + + ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh(); + if ( pDocShell ) + SeekOle( pDocShell, mnFilterOptions ); + + // hyperlinks + PropRead* pDInfoSec2 = new PropRead( mrStorage, String( RTL_CONSTASCII_USTRINGPARAM( "\005DocumentSummaryInformation" ) ) ); + if ( pDInfoSec2->IsValid() ) + { + PropItem aPropItem; + + UINT32 nType, nPropSize, nPropCount; + + pDInfoSec2->Read(); + + BYTE aPropSetGUID[ 16 ] = + { + 0x02, 0xd5, 0xcd, 0xd5, 0x9c, 0x2e, 0x1b, 0x10, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae + }; + Section* pSection = (Section*)pDInfoSec2->GetSection( aPropSetGUID ); + if ( pSection ) + { + if ( pSection->GetProperty( PID_SLIDECOUNT, aPropItem ) ) + { + aPropItem >> nType; + if ( ( nType == VT_I4 ) || ( nType == VT_UI4 ) ) + { + // examine PID_HEADINGPAIR to get the correct entry for PID_DOCPARTS + UINT32 nSlideCount, nVecCount; + aPropItem >> nSlideCount; + if ( nSlideCount && pSection->GetProperty( PID_HEADINGPAIR, aPropItem ) ) + { + UINT32 nSlideTitleIndex = 0, nSlideTitleCount = 0; + UINT32 nFontIndex, nFontCount = 0; + UINT32 nDesignTemplateIndex, nDesignTemplateCount = 0; + UINT32 i, nTemp, nEntryCount = 0; + + String aUString; + + aPropItem >> nType + >> nVecCount; + + if ( ( nType == ( VT_VARIANT | VT_VECTOR ) ) && ( nVecCount ^ 1 ) ) + { + nVecCount >>= 1; + + for ( i = 0; i < nVecCount; i++ ) + { + if ( !aPropItem.Read( aUString, VT_EMPTY, FALSE ) ) + break; + aPropItem >> nType; + if ( ( nType != VT_I4 ) && ( nType != VT_UI4 ) ) + break; + aPropItem >> nTemp; + if ( aUString.EqualsAscii("Slide Titles") || aUString.EqualsAscii("Folientitel") ) + { + nSlideTitleCount = nTemp; + nSlideTitleIndex = nEntryCount; + } + else if ( aUString.EqualsAscii("Fonts Used") ) + { + nFontCount = nTemp; + nFontIndex = nEntryCount; + } + else if ( aUString.EqualsAscii("Design Template") ) + { + nDesignTemplateCount = nTemp; + nDesignTemplateIndex = nEntryCount; + } + nEntryCount += nTemp; + } + } + if ( ( nSlideCount == nSlideTitleCount ) && pSection->GetProperty( PID_DOCPARTS, aPropItem ) ) + { + aPropItem >> nType + >> nVecCount; + + if ( ( nVecCount >= ( nSlideTitleIndex + nSlideTitleCount ) ) + && ( nType == ( VT_LPSTR | VT_VECTOR ) ) ) + { + for ( i = 0; i != nSlideTitleIndex; i++ ) + { + aPropItem >> nTemp; + aPropItem.SeekRel( nTemp ); + } + for ( i = 0; i < nSlideTitleCount; i++ ) + { + if ( !aPropItem.Read( aUString, nType, FALSE ) ) + break; + String* pString = new String( aUString ); + if ( pString->EqualsAscii( "No Slide Title" )) + *pString = String(); + else + { + void* pPtr; + for ( pPtr = maSlideNameList.First(); pPtr; pPtr = maSlideNameList.Next() ) + { + if ( *((String*)pPtr ) == *pString ) + { + *pString = String(); + break; + } + } + } + maSlideNameList.Insert( pString, LIST_APPEND ); + } + } + } + } + } + } + + BYTE aUserPropSetGUID[ 16 ] = + { + 0x05, 0xd5, 0xcd, 0xd5, 0x9c, 0x2e, 0x1b, 0x10, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae + }; + pSection = (Section*)pDInfoSec2->GetSection( aUserPropSetGUID ); + if ( pSection ) + { + Dictionary aDict; + if ( pSection->GetDictionary( aDict ) ) + { + UINT32 nPropId = aDict.GetProperty( rtl::OUString::createFromAscii("_PID_HLINKS" )); + if ( nPropId ) + { + if ( pSection->GetProperty( nPropId, aPropItem ) ) + { + aPropItem.Seek( STREAM_SEEK_TO_BEGIN ); + aPropItem >> nType; + if ( nType == VT_BLOB ) + { + aPropItem >> nPropSize + >> nPropCount; + + if ( ! ( nPropCount % 6 ) ) + { + UINT32 i; + + nPropCount /= 6; // 6 propertys a hyperlink + + SdHyperlinkEntry* pHyperlink = 0; + for ( i = 0; i < nPropCount; i++ ) + { + pHyperlink = new SdHyperlinkEntry; + pHyperlink->nIndex = 0; + aPropItem >> nType; + if ( nType != VT_I4 ) + break; + aPropItem >> pHyperlink->nPrivate1 + >> nType; + if ( nType != VT_I4 ) + break; + aPropItem >> pHyperlink->nPrivate2 + >> nType; + if ( nType != VT_I4 ) + break; + aPropItem >> pHyperlink->nPrivate3 + >> nType; + if ( nType != VT_I4 ) + break; + aPropItem >> pHyperlink->nInfo; + if ( !aPropItem.Read( pHyperlink->aTarget, VT_EMPTY ) ) + break; + if ( !aPropItem.Read( pHyperlink->aSubAdress, VT_EMPTY ) ) + break; + pHyperlink->nStartPos = pHyperlink->nEndPos = -1; + + if ( pHyperlink->aSubAdress.Len() ) // get the converted subadress + { + sal_uInt32 nPageNumber = 0; + String aString( pHyperlink->aSubAdress ); + ByteString aStringAry[ 3 ]; + sal_uInt16 nTokenCount = aString.GetTokenCount( ',' ); + if ( nTokenCount > 3 ) + nTokenCount = 3; + sal_uInt16 nToken; + for( nToken = 0; nToken < nTokenCount; nToken++ ) + aStringAry[ nToken ] = ByteString( aString.GetToken( nToken, (sal_Unicode)',' ), RTL_TEXTENCODING_UTF8 ); + + sal_Bool bSucceeded = sal_False; + + // first pass, searching for a SlideId + for( nToken = 0; nToken < nTokenCount; nToken++ ) + { + if ( aStringAry[ nToken ].IsNumericAscii() ) + { + sal_Int32 nNumber = aStringAry[ nToken ].ToInt32(); + if ( nNumber & ~0xff ) + { + PptSlidePersistList* pPageList = GetPageList( PPT_SLIDEPAGE ); + if ( pPageList ) + { + sal_uInt16 nPage = pPageList->FindPage( nNumber ); + if ( nPage != PPTSLIDEPERSIST_ENTRY_NOTFOUND ) + { + nPageNumber = nPage; + bSucceeded = sal_True; + break; + } + } + } + } + } + if ( !bSucceeded ) + { // second pass, searching for a SlideName + for ( nToken = 0; nToken < nTokenCount; nToken++ ) + { + String aToken( aString.GetToken( nToken, (sal_Unicode)',' ) ); + for ( void* pPtr = maSlideNameList.First(); pPtr; pPtr = maSlideNameList.Next() ) + { + if ( *(String*)pPtr == aToken ) + { + nPageNumber = maSlideNameList.GetCurPos(); + bSucceeded = sal_True; + break; + } + } + } + } + if ( !bSucceeded ) + { // third pass, searching for a slide number + for ( nToken = 0; nToken < nTokenCount; nToken++ ) + { + if ( aStringAry[ nToken ].IsNumericAscii() ) + { + sal_Int32 nNumber = aStringAry[ nToken ].ToInt32(); + if ( ( nNumber & ~0xff ) == 0 ) + { + nPageNumber = (sal_uInt32)nNumber - 1; + bSucceeded = sal_True; + break; + } + } + } + } + if ( bSucceeded ) + { + if ( nPageNumber < maSlideNameList.Count() ) + pHyperlink->aConvSubString = *(String*)maSlideNameList.GetObject( nPageNumber ); + if ( !pHyperlink->aConvSubString.Len() ) + { + pHyperlink->aConvSubString = String( SdResId( STR_PAGE ) ); + pHyperlink->aConvSubString.Append( sal_Unicode( ' ' ) ); + pHyperlink->aConvSubString.Append( mpDoc->CreatePageNumValue( (USHORT)nPageNumber + 1 ) ); + } + } + } + aHyperList.Insert( pHyperlink, LIST_APPEND ); + } + if ( i != nPropCount ) + delete pHyperlink; + } + } + } + } + } + } + } + } + delete pDInfoSec2; + + if ( mbDocumentFound ) + { + rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); + // HyperList lesen / Indexe der einzelnen Eintraege setzen + DffRecordHeader aHyperHd; + if ( SeekToRec( rStCtrl, PPT_PST_ExObjList, maDocHd.GetRecEndFilePos(), &aHyperHd ) ) + { + UINT32 nExObjHyperListLen = aHyperHd.GetRecEndFilePos(); + for ( void* pPtr = aHyperList.First(); pPtr; pPtr = aHyperList.Next() ) + { + DffRecordHeader aHyperE; + if ( !SeekToRec( rStCtrl, PPT_PST_ExHyperlink, nExObjHyperListLen, &aHyperE ) ) + break; + if ( !SeekToRec( rStCtrl, PPT_PST_ExHyperlinkAtom, nExObjHyperListLen, NULL, 0 ) ) + break; + rStCtrl.SeekRel( 8 ); + rStCtrl >> ((SdHyperlinkEntry*)pPtr)->nIndex; + aHyperE.SeekToEndOfRecord( rStCtrl ); + } + } + } + + Size aVisAreaSize; + switch ( aUserEditAtom.eLastViewType ) + { + case 5 : // notes master + case 3 : // notes + aVisAreaSize = aDocAtom.GetNotesPageSize(); + break; + default : + aVisAreaSize = aDocAtom.GetSlidesPageSize(); + } + Scale( aVisAreaSize ); + pDocShell->SetVisArea( Rectangle( Point(), aVisAreaSize ) ); + + /////////////////////////////////////////////////////////// + // create master pages: + /////////////////////////////////////////////////////////// + SfxProgress* pStbMgr = new SfxProgress( pDocShell, String( SdResId( STR_POWERPOINT_IMPORT ) ), + pMasterPages->Count() + pSlidePages->Count() + pNotePages->Count() ); + + UINT32 nImportedPages = 0; + { + UINT16 nMasterAnz = GetPageCount( PPT_MASTERPAGE ); + + for ( USHORT nMasterNum = 0; nMasterNum < nMasterAnz; nMasterNum++ ) + { + SetPageNum( nMasterNum, PPT_MASTERPAGE ); + SdPage* pPage = (SdPage*)MakeBlancPage( TRUE ); + if ( pPage ) + { + BOOL bNotesMaster = (*GetPageList( eAktPageKind ) )[ nAktPageNum ]->bNotesMaster; + BOOL bStarDrawFiller = (*GetPageList( eAktPageKind ) )[ nAktPageNum ]->bStarDrawFiller; + + PageKind ePgKind = ( bNotesMaster ) ? PK_NOTES : PK_STANDARD; + pPage->SetPageKind( ePgKind ); + pSdrModel->InsertMasterPage( (SdrPage*)pPage ); + if ( bNotesMaster && bStarDrawFiller ) + ((SdPage*)pPage)->SetAutoLayout( AUTOLAYOUT_NOTES, TRUE ); + if ( nMasterNum ) + { + boost::optional< sal_Int16 > oStartNumbering; + SfxStyleSheet* pSheet; + if ( nMasterNum == 1 ) + { + /////////////////// + // standardsheet // + /////////////////// + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( String(SdResId( STR_STANDARD_STYLESHEET_NAME )), SD_STYLE_FAMILY_GRAPHICS ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_TYPE_TEXT_IN_SHAPE, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, TSS_TYPE_TEXT_IN_SHAPE, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + } + + // PSEUDO + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( String(SdResId( STR_PSEUDOSHEET_BACKGROUNDOBJECTS )), SD_STYLE_FAMILY_PSEUDO ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_TYPE_TEXT_IN_SHAPE, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, TSS_TYPE_TEXT_IN_SHAPE, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + + /////////////////////////////////////////////////////////// + // create layoutstylesheets, set layoutname and stylesheet + // (nur auf Standard- und Notizseiten) + /////////////////////////////////////////////////////////// + String aLayoutName( SdResId( STR_LAYOUT_DEFAULT_NAME ) ); + if ( nMasterNum > 2 ) + { + if ( ePgKind == PK_STANDARD ) + { // Standardseite: Neues Praesentationslayout erzeugen + aLayoutName = String( SdResId( STR_LAYOUT_DEFAULT_TITLE_NAME ) ); + aLayoutName += String::CreateFromInt32( (sal_Int32)( ( nMasterNum + 1 ) / 2 - 1 ) ); + ( (SdStyleSheetPool*)mpDoc->GetStyleSheetPool() )->CreateLayoutStyleSheets( aLayoutName ); + } + else // Notizseite: Praesentationslayout von der Standardseite verwenden + aLayoutName = ( (SdPage*)mpDoc->GetMasterPage( nMasterNum - 1 ) )->GetName(); + } + pPage->SetName( aLayoutName ); + aLayoutName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR )); + aLayoutName += String( SdResId( STR_LAYOUT_OUTLINE ) ); + pPage->SetLayoutName( aLayoutName ); + + ///////////////////// + // set stylesheets // + ///////////////////// + if ( pPage->GetPageKind() == PK_STANDARD ) + { + UINT32 nTitleInstance = TSS_TYPE_PAGETITLE; + UINT32 nOutlinerInstance = TSS_TYPE_BODY; +// BOOL bSwapStyleSheet = pSlideLayout->eLayout == PPT_LAYOUT_TITLEMASTERSLIDE; +// if ( bSwapStyleSheet ) +// { +// nTitleInstance = TSS_TYPE_TITLE; +// nOutlinerInstance = TSS_TYPE_SUBTITLE; +// } + ///////////////////// + // titelstylesheet // + ///////////////////// + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, nTitleInstance, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, nTitleInstance, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + //////////////////////// + // outlinerstylesheet // + //////////////////////// + UINT16 nLevel; + PPTParagraphObj* pParagraphs[ 9 ]; + PPTParagraphObj* pPreviousPara = NULL; + + for ( nLevel = 0; nLevel < 9; nLevel++ ) + { + String aName( pPage->GetLayoutName() ); + aName.Append( (sal_Unicode)( ' ' ) ); + aName.Append( String::CreateFromInt32( nLevel + 1 ) ); + SfxStyleSheet* pOutlineSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( aName, SD_STYLE_FAMILY_MASTERPAGE ); + DBG_ASSERT( pOutlineSheet, "Vorlage fuer Gliederungsobjekt nicht gefunden" ); + if ( pOutlineSheet ) + { + pParagraphs[ nLevel ] = new PPTParagraphObj( *pPPTStyleSheet, nOutlinerInstance, nLevel ); + SfxItemSet& rItemSet = pOutlineSheet->GetItemSet(); + PPTPortionObj aPortion( *pPPTStyleSheet, nOutlinerInstance, nLevel ); + pParagraphs[ nLevel ]->AppendPortion( aPortion ); + pParagraphs[ nLevel ]->ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, pPreviousPara ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + pPreviousPara = pParagraphs[ nLevel ]; + } + else + pParagraphs[ nLevel ] = NULL; + } + for ( nLevel = 0; nLevel < 9; delete pParagraphs[ nLevel++ ] ) ; + ///////////////////////// + // subtitle stylesheet // + ///////////////////////// + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_TYPE_SUBTITLE, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, TSS_TYPE_SUBTITLE, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + } + else if ( ePgKind == PK_NOTES ) + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_TYPE_NOTES, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, TSS_TYPE_NOTES, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + } + } + } + } + } + SdPage* pMPage; + sal_uInt16 i; + for ( i = 1; i < mpDoc->GetMasterPageCount() && ( (pMPage = (SdPage*)mpDoc->GetMasterPage( i )) != 0 ); i++ ) + { + SetPageNum( i, PPT_MASTERPAGE ); + ///////////////////////////////////////////// + // importing master page objects // + ///////////////////////////////////////////// + PptSlidePersistList* pList = GetPageList( eAktPageKind ); + PptSlidePersistEntry* pPersist = ( pList && ( nAktPageNum < pList->Count() ) ) + ? (*pList)[ nAktPageNum ] : NULL; + if ( pPersist ) + { + if ( pPersist->bStarDrawFiller && pPersist->bNotesMaster && ( nAktPageNum > 2 ) && ( ( nAktPageNum & 1 ) == 0 ) ) + { + pSdrModel->DeleteMasterPage( nAktPageNum ); + SdrPage* pNotesClone = ((SdPage*)pSdrModel->GetMasterPage( 2 ))->Clone(); + pSdrModel->InsertMasterPage( pNotesClone, nAktPageNum ); + if ( pNotesClone ) + { + String aLayoutName( ((SdPage*)pSdrModel->GetMasterPage( nAktPageNum - 1 ))->GetLayoutName() ); + ((SdPage*)pNotesClone)->SetPresentationLayout( aLayoutName, sal_False, sal_False, sal_False ); + ((SdPage*)pNotesClone)->SetLayoutName( aLayoutName ); + } + } + else if ( ( pPersist->bStarDrawFiller == FALSE ) ) + { + PptSlidePersistEntry* pE = pPersist; + while( ( pE->aSlideAtom.nFlags & 4 ) && pE->aSlideAtom.nMasterId ) + { + sal_uInt16 nNextMaster = pMasterPages->FindPage( pE->aSlideAtom.nMasterId ); + if ( nNextMaster == PPTSLIDEPERSIST_ENTRY_NOTFOUND ) + break; + else + pE = (*pList)[ nNextMaster ]; + } + SdrObject* pObj = ImportPageBackgroundObject( *pMPage, pE->nBackgroundOffset, TRUE ); // import background + if ( pObj ) + pMPage->NbcInsertObject( pObj ); + + sal_Bool bNewAnimationsUsed = sal_False; + ProcessData aProcessData( *(*pList)[ nAktPageNum ], (SdPage*)pMPage ); + sal_uInt32 nFPosMerk = rStCtrl.Tell(); + DffRecordHeader aPageHd; + if ( SeekToAktPage( &aPageHd ) ) + { + if ( mbTracing ) + mpTracer->AddAttribute( rtl::OUString::createFromAscii( "MasterPage" ), rtl::OUString::valueOf( (sal_Int32) (nAktPageNum + 1) ) ); + + while( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPageHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aHd; + rStCtrl >> aHd; + switch( aHd.nRecType ) + { + case PPT_PST_PPDrawing : + { + aHd.SeekToBegOfRecord( rStCtrl ); + DffRecordHeader aPPDrawHd; + if ( SeekToRec( rStCtrl, PPT_PST_PPDrawing, aHd.GetRecEndFilePos(), &aPPDrawHd ) ) + { + sal_uInt32 nPPDrawEnd = aPPDrawHd.GetRecEndFilePos(); + DffRecordHeader aEscherF002Hd; + if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, nPPDrawEnd, &aEscherF002Hd ) ) + { + sal_uInt32 nEscherF002End = aEscherF002Hd.GetRecEndFilePos(); + DffRecordHeader aEscherObjListHd; + if ( SeekToRec( rStCtrl, DFF_msofbtSpgrContainer, nEscherF002End, &aEscherObjListHd ) ) + { + sal_uInt32 nObjCount = 0; + while( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aEscherObjListHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aHd2; + rStCtrl >> aHd2; + if ( ( aHd2.nRecType == DFF_msofbtSpContainer ) || ( aHd2.nRecType == DFF_msofbtSpgrContainer ) ) + { + if ( nObjCount++ ) // skipping the first object + { + Rectangle aEmpty; + aHd2.SeekToBegOfRecord( rStCtrl ); + SdrObject* pImpObj = ImportObj( rStCtrl, (void*)&aProcessData, aEmpty, aEmpty ); + if ( pImpObj ) + { + pImpObj->SetLayer( mnBackgroundObjectsLayerID ); + pMPage->NbcInsertObject( pImpObj ); + } + } + } + aHd2.SeekToEndOfRecord( rStCtrl ); + } + } + } + } + } + break; + + case PPT_PST_ProgTags : + { + DffRecordHeader aProgTagHd; + if ( SeekToContentOfProgTag( 10, rStCtrl, aPageHd, aProgTagHd ) ) + { + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aProgTagHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aProgTagContentHd; + rStCtrl >> aProgTagContentHd; + switch( aProgTagContentHd.nRecType ) + { + case DFF_msofbtAnimGroup : + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > xPage( pMPage->getUnoPage(), ::com::sun::star::uno::UNO_QUERY ); + ppt::AnimationImporter aImporter( this, rStCtrl ); + aImporter.import( xPage, aProgTagContentHd ); + bNewAnimationsUsed = sal_True; + } + break; + } + aProgTagContentHd.SeekToEndOfRecord( rStCtrl ); + } + } + } + break; + } + aHd.SeekToEndOfRecord( rStCtrl ); + } + if ( mbTracing ) + mpTracer->RemoveAttribute( rtl::OUString::createFromAscii( "MasterPage" ) ); + } + rStCtrl.Seek( nFPosMerk ); + ImportPageEffect( (SdPage*)pMPage, bNewAnimationsUsed ); + + /////////////////////// + // background object // + /////////////////////// + pObj = pMPage->GetObj( 0 ); + if ( pObj && pObj->GetObjIdentifier() == OBJ_RECT ) + { + if ( pMPage->GetPageKind() == PK_STANDARD ) + { + // transform data from imported background object to new form + // and delete the object. It was used as container to transport + // the attributes of the MasterPage background fill + SfxStyleSheet* pSheet = pMPage->GetStyleSheetForMasterPageBackground(); + + if(pSheet) + { + // if we have a StyleSheet (for Masterpages), set attributes there and use it + pSheet->GetItemSet().ClearItem(); + pSheet->GetItemSet().Put(pObj->GetMergedItemSet()); + pMPage->getSdrPageProperties().ClearItem(); + pMPage->getSdrPageProperties().SetStyleSheet(pSheet); + } + else + { + // without StyleSheet, set attributes directly. This + // should not be done at all and is an error (will be asserted by SdrPage) + pMPage->getSdrPageProperties().ClearItem(); + pMPage->getSdrPageProperties().PutItemSet(pObj->GetMergedItemSet()); + } + + pMPage->RemoveObject(pObj->GetOrdNum()); + SdrObject::Free(pObj); + } + } + } + } + if( pStbMgr ) + pStbMgr->SetState( nImportedPages++ ); + } + //////////////////////////////////// + // importing slide pages // + //////////////////////////////////// + { + UINT32 nFPosMerk = rStCtrl.Tell(); + PptPageKind ePageKind = eAktPageKind; + UINT16 nPageNum = nAktPageNum; + + SdPage* pHandoutPage = (SdPage*)MakeBlancPage( FALSE ); + pHandoutPage->SetPageKind( PK_HANDOUT ); + pSdrModel->InsertPage( pHandoutPage ); + + USHORT nPageAnz = GetPageCount( PPT_SLIDEPAGE ); + if ( nPageAnz ) + { + for ( USHORT nPage = 0; nPage < nPageAnz; nPage++ ) + { + sal_Bool bNewAnimationsUsed = sal_False; + + mePresChange = PRESCHANGE_SEMIAUTO; + SetPageNum( nPage, PPT_SLIDEPAGE ); + SdPage* pPage = (SdPage*)MakeBlancPage( FALSE ); + PptSlidePersistEntry* pMasterPersist = NULL; + if ( HasMasterPage( nPage, PPT_SLIDEPAGE ) ) // try to get the LayoutName from the masterpage + { + sal_uInt16 nMasterNum = GetMasterPageIndex( nAktPageNum, eAktPageKind ); + pPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nMasterNum)); + PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); + if ( pPageList && nMasterNum < pPageList->Count() ) + pMasterPersist = (*pPageList)[ nMasterNum ]; + pPage->SetLayoutName(((SdPage&)pPage->TRG_GetMasterPage()).GetLayoutName()); + } + pPage->SetPageKind( PK_STANDARD ); + pSdrModel->InsertPage( pPage ); // SJ: #i29625# because of form controls, the + ImportPage( pPage, pMasterPersist ); // page must be inserted before importing + SetHeaderFooterPageSettings( pPage, pMasterPersist ); + // CWS preseng01: pPage->SetPageKind( PK_STANDARD ); + + DffRecordHeader aPageHd; + if ( SeekToAktPage( &aPageHd ) ) + { + aPageHd.SeekToContent( rStCtrl ); + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPageHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aHd; + rStCtrl >> aHd; + switch ( aHd.nRecType ) + { + case PPT_PST_ProgTags : + { + DffRecordHeader aProgTagHd; + if ( SeekToContentOfProgTag( 10, rStCtrl, aPageHd, aProgTagHd ) ) + { + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aProgTagHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aProgTagContentHd; + rStCtrl >> aProgTagContentHd; + switch( aProgTagContentHd.nRecType ) + { +/* + case PPT_PST_CommentContainer : + { + + } + break; +*/ + case DFF_msofbtAnimGroup : + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > xPage( pPage->getUnoPage(), ::com::sun::star::uno::UNO_QUERY ); + ppt::AnimationImporter aImporter( this, rStCtrl ); + aImporter.import( xPage, aProgTagContentHd ); + bNewAnimationsUsed = sal_True; + } + break; + + case PPT_PST_NewlyAddedAtomByXP11008 : // ??? + break; + + case PPT_PST_NewlyAddedAtomByXP12011 : // ??? don't know, this atom is always 8 bytes big + break; // and is appearing in nearly every l10 progtag + } + aProgTagContentHd.SeekToEndOfRecord( rStCtrl ); + } + } + } + break; + + case PPT_PST_HeadersFooters : + case PPT_PST_PPDrawing : + default: + break; + } + + aHd.SeekToEndOfRecord( rStCtrl ); + } + ImportPageEffect( (SdPage*)pPage, bNewAnimationsUsed ); + } + + // creating the corresponding note page + eAktPageKind = PPT_NOTEPAGE; + SdPage* pNotesPage = (SdPage*)MakeBlancPage( FALSE ); + sal_uInt16 nNotesMasterNum = GetMasterPageIndex( nPage, PPT_SLIDEPAGE ) + 1; + sal_uInt32 nNotesPageId = GetNotesPageId( nPage ); + if ( nNotesPageId ) + { + nImportedPages++; + sal_uInt16 nNotesPageIndex = pNotePages->FindPage( nNotesPageId ); + if ( nNotesPageIndex == PPTSLIDEPERSIST_ENTRY_NOTFOUND ) + nNotesPageIndex = 0; + SetPageNum( nNotesPageIndex, PPT_NOTEPAGE ); + PptSlidePersistEntry* pMasterPersist2 = NULL; + if ( HasMasterPage( nNotesPageIndex, PPT_NOTEPAGE ) ) // try to get the LayoutName from the masterpage + { + pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); + PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); + if ( pPageList && nNotesMasterNum < pPageList->Count() ) + pMasterPersist2 = (*pPageList)[ nNotesMasterNum ]; + pNotesPage->SetLayoutName( ((SdPage&)pNotesPage->TRG_GetMasterPage()).GetLayoutName() ); + } + pNotesPage->SetPageKind( PK_NOTES ); + pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); + pSdrModel->InsertPage( pNotesPage ); // SJ: #i29625# because of form controls, the + ImportPage( pNotesPage, pMasterPersist2 ); // page must be inserted before importing + SetHeaderFooterPageSettings( pNotesPage, pMasterPersist2 ); + pNotesPage->SetAutoLayout( AUTOLAYOUT_NOTES, FALSE ); + } + else + { + pNotesPage->SetPageKind( PK_NOTES ); + pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); + pNotesPage->SetAutoLayout( AUTOLAYOUT_NOTES, TRUE ); + pSdrModel->InsertPage( pNotesPage ); + SdrObject* pPageObj = pNotesPage->GetPresObj( PRESOBJ_PAGE, 1 ); + if ( pPageObj ) + ((SdrPageObj*)pPageObj)->SetReferencedPage(pSdrModel->GetPage(( nPage << 1 ) + 1)); + } + + if( pStbMgr ) + pStbMgr->SetState( nImportedPages++ ); + } + ////////////// + } + else + { + // Das kann bei Dokumentvorlagen vorkommen + eAktPageKind = PPT_SLIDEPAGE; + SdrPage* pPage = MakeBlancPage( FALSE ); + pSdrModel->InsertPage( pPage ); + + // #i37397#, trying to set the title master for the first page + sal_uInt16 nMaster, nMasterCount = pSdrModel->GetMasterPageCount(); + SdPage* pFoundMaster = NULL; + for ( nMaster = 1; nMaster < nMasterCount; nMaster++ ) + { + SdPage* pMaster = static_cast<SdPage*>( pSdrModel->GetMasterPage( nMaster ) ); + if ( pMaster->GetPageKind() == PK_STANDARD ) + { + SetPageNum( nMaster, PPT_MASTERPAGE ); + if ( !pFoundMaster ) + pFoundMaster = pMaster; + else if ( GetSlideLayoutAtom()->eLayout == PPT_LAYOUT_TITLEMASTERSLIDE ) + pFoundMaster = pMaster; + if ( GetSlideLayoutAtom()->eLayout == PPT_LAYOUT_TITLEMASTERSLIDE ) + break; + } + } + if ( pFoundMaster ) + { + ((SdPage*)pPage)->TRG_SetMasterPage( *((SdPage*)pFoundMaster) ); + ((SdPage*)pPage)->SetLayoutName( ((SdPage*)pFoundMaster)->GetLayoutName() ); + } + ((SdPage*)pPage)->SetAutoLayout( AUTOLAYOUT_TITLE, TRUE, TRUE ); + + eAktPageKind = PPT_NOTEPAGE; + SdrPage* pNPage = MakeBlancPage( FALSE ); + pSdrModel->InsertPage( pNPage ); + } + SetPageNum( nPageNum, ePageKind ); + rStCtrl.Seek( nFPosMerk ); + } + /////////////////////////////////////////////////////////////////// + // Handzettel und Notiz-Seiten erzeugen // + /////////////////////////////////////////////////////////////////// + bOk = mpDoc->CreateMissingNotesAndHandoutPages(); + if ( bOk ) + { + for ( i = 0; i < mpDoc->GetSdPageCount( PK_STANDARD ); i++ ) + { + //////////////////// + // set AutoLayout // + //////////////////// + SetPageNum( i, PPT_SLIDEPAGE ); + SdPage* pPage = mpDoc->GetSdPage( i, PK_STANDARD ); + AutoLayout eAutoLayout = AUTOLAYOUT_NONE; + const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom(); + if ( pSlideLayout ) + { + switch ( pSlideLayout->eLayout ) // Praesentationslayouts fuer Standard-Seiten + { + case PPT_LAYOUT_TITLEANDBODYSLIDE : + { + eAutoLayout = AUTOLAYOUT_ENUM; + USHORT nID1 = pSlideLayout->aPlaceholderId[ 1 ]; + switch ( nID1 ) + { + case PPT_PLACEHOLDER_BODY : + eAutoLayout = AUTOLAYOUT_ENUM; + break; + case PPT_PLACEHOLDER_TABLE : + eAutoLayout = AUTOLAYOUT_TAB; + break; + case PPT_PLACEHOLDER_ORGANISZATIONCHART : + eAutoLayout = AUTOLAYOUT_ORG; + break; + case PPT_PLACEHOLDER_GRAPH : + eAutoLayout = AUTOLAYOUT_CHART; + break; + case PPT_PLACEHOLDER_OBJECT : + eAutoLayout = AUTOLAYOUT_OBJ; + break; + case PPT_PLACEHOLDER_VERTICALTEXTBODY : + eAutoLayout = AUTOLAYOUT_TITLE_VERTICAL_OUTLINE; + break; + } + } + break; + + case PPT_LAYOUT_2COLUMNSANDTITLE : + { + eAutoLayout = AUTOLAYOUT_2TEXT; + USHORT nID1 = pSlideLayout->aPlaceholderId[ 1 ]; + USHORT nID2 = pSlideLayout->aPlaceholderId[ 2 ]; + if ( nID1 == PPT_PLACEHOLDER_BODY && nID2 == PPT_PLACEHOLDER_GRAPH ) + eAutoLayout = AUTOLAYOUT_TEXTCHART; + else if ( nID1 == PPT_PLACEHOLDER_GRAPH && nID2 == PPT_PLACEHOLDER_BODY ) + eAutoLayout = AUTOLAYOUT_CHARTTEXT; + else if ( nID1 == PPT_PLACEHOLDER_BODY && nID2 == PPT_PLACEHOLDER_CLIPART ) + eAutoLayout = AUTOLAYOUT_TEXTCLIP; + else if ( nID1 == PPT_PLACEHOLDER_CLIPART && nID2 == PPT_PLACEHOLDER_BODY ) + eAutoLayout = AUTOLAYOUT_CLIPTEXT; + else if ( nID1 == PPT_PLACEHOLDER_CLIPART && nID2 == PPT_PLACEHOLDER_VERTICALTEXTBODY ) + eAutoLayout = AUTOLAYOUT_TITLE_VERTICAL_OUTLINE_CLIPART; + else if ( ( nID1 == PPT_PLACEHOLDER_BODY ) + && ( ( nID2 == PPT_PLACEHOLDER_OBJECT ) || ( nID2 == PPT_PLACEHOLDER_MEDIACLIP ) ) ) + eAutoLayout = AUTOLAYOUT_TEXTOBJ; + else if ( ( nID2 == PPT_PLACEHOLDER_BODY ) + && ( ( nID1 == PPT_PLACEHOLDER_OBJECT ) || ( nID1 == PPT_PLACEHOLDER_MEDIACLIP ) ) ) + eAutoLayout = AUTOLAYOUT_OBJTEXT; + else if ( ( nID1 == PPT_PLACEHOLDER_OBJECT ) && ( nID2 == PPT_PLACEHOLDER_OBJECT ) ) + eAutoLayout = AUTOLAYOUT_OBJ; + } + break; + + case PPT_LAYOUT_2ROWSANDTITLE : + { + eAutoLayout = AUTOLAYOUT_2TEXT; + USHORT nID1 = pSlideLayout->aPlaceholderId[ 1 ]; + USHORT nID2 = pSlideLayout->aPlaceholderId[ 2 ]; + if ( nID1 == PPT_PLACEHOLDER_BODY && nID2 == PPT_PLACEHOLDER_OBJECT ) + eAutoLayout = AUTOLAYOUT_TEXTOVEROBJ; + else if ( nID1 == PPT_PLACEHOLDER_OBJECT && nID2 == PPT_PLACEHOLDER_BODY ) + eAutoLayout = AUTOLAYOUT_OBJOVERTEXT; + } + break; + + case PPT_LAYOUT_TITLESLIDE : + eAutoLayout = AUTOLAYOUT_TITLE; + break; + case PPT_LAYOUT_ONLYTITLE : + eAutoLayout = AUTOLAYOUT_ONLY_TITLE; + break; + case PPT_LAYOUT_RIGHTCOLUMN2ROWS : + eAutoLayout = AUTOLAYOUT_TEXT2OBJ; + break; + case PPT_LAYOUT_LEFTCOLUMN2ROWS : + eAutoLayout = AUTOLAYOUT_2OBJTEXT; + break; + case PPT_LAYOUT_TOPROW2COLUMN : + eAutoLayout = AUTOLAYOUT_2OBJOVERTEXT; + break; + case PPT_LAYOUT_4OBJECTS : + eAutoLayout = AUTOLAYOUT_4OBJ; + break; + case PPT_LAYOUT_BIGOBJECT : + eAutoLayout = AUTOLAYOUT_OBJ; + break; + case PPT_LAYOUT_TITLERIGHTBODYLEFT : + eAutoLayout = AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE; // AUTOLAYOUT_ENUM; + break; + case PPT_LAYOUT_TITLERIGHT2BODIESLEFT : + eAutoLayout = AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART; // AUTOLAYOUT_TEXT2OBJ; + break; + + case PPT_LAYOUT_BOTTOMROW2COLUMNS : + case PPT_LAYOUT_BLANCSLIDE : + case PPT_LAYOUT_MASTERSLIDE : // Layout der Standard- und Titel-MasterPage + case PPT_LAYOUT_TITLEMASTERSLIDE : + case PPT_LAYOUT_MASTERNOTES : // Layout der Notizen-MasterPage + case PPT_LAYOUT_NOTESTITLEBODY : // Praesentationslayout fuer Notiz-Seiten + case PPT_LAYOUT_HANDOUTLAYOUT : // Praesentationslayout fuer Handzettelseiten + eAutoLayout = AUTOLAYOUT_NONE; + break; + } + if ( eAutoLayout != AUTOLAYOUT_NONE ) + pPage->SetAutoLayout( eAutoLayout, FALSE ); + } + } + ////////////////////////////////////////////////////////////// + // Handzettel-MasterPage: Autolayout setzen // + ////////////////////////////////////////////////////////////// + SdPage* pHandoutMPage = mpDoc->GetMasterSdPage( 0, PK_HANDOUT ); + pHandoutMPage->SetAutoLayout( AUTOLAYOUT_HANDOUT6, TRUE, TRUE ); + } + + UINT32 nSlideCount = GetPageCount(); + for ( i = 0; ( i < nSlideCount) && ( i < maSlideNameList.Count() ); i++ ) + { + SdPage* pPage = mpDoc->GetSdPage( i, PK_STANDARD ); + String* pName = (String*)maSlideNameList.GetObject( i ); + if ( pPage && pName ) + { + if ( pName->Len() ) + pPage->SetName( *pName ); + else + *pName = pPage->GetName(); + } + } + if ( mbDocumentFound ) + { + mpDoc->SetSummationOfParagraphs( sal_True ); + if ( pDocShell ) + { + ::sd::FrameView* pFrameView = mpDoc->GetFrameView( 0 ); + if ( !pFrameView ) + { + List* pFrameViewList = mpDoc->GetFrameViewList(); + if ( pFrameViewList ) + { + pFrameView = new ::sd::FrameView( mpDoc ); + if ( pFrameView ) + pFrameViewList->Insert( pFrameView ); + } + } + if ( pFrameView ) + { + sal_uInt16 nSelectedPage = 0; + PageKind ePageKind = PK_STANDARD; + EditMode eEditMode = EM_PAGE; + + switch ( aUserEditAtom.eLastViewType ) + { + case 7 : // outliner view + { + SfxItemSet* pSet = mrMed.GetItemSet(); + if ( pSet ) + pSet->Put( SfxUInt16Item( SID_VIEW_ID, 3 ) ); + } + break; + case 8 : // slide sorter + { + SfxItemSet* pSet = mrMed.GetItemSet(); + if ( pSet ) + pSet->Put( SfxUInt16Item( SID_VIEW_ID, 2 ) ); + } + break; + case 10 : // titlemaster + nSelectedPage = 1; + case 2 : // master + { + ePageKind = PK_STANDARD; + eEditMode = EM_MASTERPAGE; + } + break; + case 5 : // notes master + eEditMode = EM_MASTERPAGE; + case 3 : // notes + ePageKind = PK_NOTES; + break; + case 4 : // handout + ePageKind = PK_HANDOUT; + break; + default : + case 1 : // normal + break; + } + pFrameView->SetPageKind( ePageKind ); + pFrameView->SetSelectedPage( nSelectedPage ); + pFrameView->SetViewShEditMode( eEditMode, ePageKind ); + } + } + DffRecordHeader aCustomShowHeader; + // custom show einlesen und setzen + rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); + if ( SeekToRec( rStCtrl, PPT_PST_NamedShows, maDocHd.GetRecEndFilePos(), &aCustomShowHeader ) ) + { + DffRecordHeader aCuHeader; + while( SeekToRec( rStCtrl, PPT_PST_NamedShow, aCustomShowHeader.GetRecEndFilePos(), &aCuHeader ) ) + { + DffRecordHeader aContent; + if ( SeekToRec( rStCtrl, PPT_PST_CString, aCuHeader.GetRecEndFilePos(), &aContent ) ) + { + String aCuShow; + aContent.SeekToBegOfRecord( rStCtrl ); + if ( ReadString( aCuShow ) ) + { + if ( SeekToRec( rStCtrl, PPT_PST_NamedShowSlides, aCuHeader.GetRecEndFilePos(), &aContent ) ) + { + PptSlidePersistList* pPageList = GetPageList( PPT_SLIDEPAGE ); + UINT32 nSCount = aContent.nRecLen >> 2; + if ( pPageList && nSCount ) + { + List* pList = mpDoc->GetCustomShowList( TRUE ); + if ( pList ) + { + SdCustomShow* pSdCustomShow = new SdCustomShow( mpDoc ); + if ( pSdCustomShow ) + { + pSdCustomShow->SetName( aCuShow ); + UINT32 nFound = 0; + for ( UINT32 nS = 0; nS < nSCount; nS++ ) + { + UINT32 nPageNumber; + rStCtrl >> nPageNumber; + USHORT nPage = pPageList->FindPage( nPageNumber ); + if ( nPage != PPTSLIDEPERSIST_ENTRY_NOTFOUND ) + { + SdPage* pPage = mpDoc->GetSdPage( nPage, PK_STANDARD ); + if ( pPage ) + { + pSdCustomShow->Insert( pPage, LIST_APPEND ); + nFound++; + } + } + } + if ( nFound ) + pList->Insert( pSdCustomShow, LIST_APPEND ); + else + delete pSdCustomShow; + } + } + } + } + } + } + } + } + // this is defaulted, maybe there is no SSDocInfoAtom + String aCustomShow; + sal_uInt32 nFlags = 1; // Bit 0: Auto advance + sal_uInt32 nPenColor = 0x1000000; + sal_Int32 nRestartTime = 0x7fffffff; + sal_uInt16 nStartSlide = 0; + sal_Int16 nEndSlide = 0; + + // read the pres. configuration + rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); + if ( SeekToRec( rStCtrl, PPT_PST_SSDocInfoAtom, maDocHd.GetRecEndFilePos(), &aCustomShowHeader ) ) + { + rStCtrl >> nPenColor + >> nRestartTime + >> nStartSlide + >> nEndSlide; + + sal_Unicode nChar; + for ( UINT32 i2 = 0; i2 < 32; i2++ ) + { + rStCtrl >> nChar; + if ( nChar ) + aCustomShow.Append( nChar ); + else + { + rStCtrl.SeekRel( ( 31 - i2 ) << 1 ); + break; + } + } + rStCtrl >> nFlags; + } + // set the current custom show + if ( aCustomShow.Len() ) + { + void* pPtr; + List* pList = mpDoc->GetCustomShowList( FALSE ); + if ( pList ) + { + for ( pPtr = pList->First(); pPtr; pPtr = pList->Next() ) + { + if ( ((SdCustomShow*)pPtr)->GetName() == aCustomShow ) + break; + } + if ( !pPtr ) + pList->First(); + } + } + sd::PresentationSettings& rPresSettings = mpDoc->getPresentationSettings(); + + rPresSettings.mbManual = ( nFlags & 1 ) == 0; + rPresSettings.mbAnimationAllowed = ( nFlags & 2 ) == 0; + rPresSettings.mbAll = ( nFlags & 4 ) == 0; + rPresSettings.mbCustomShow = ( nFlags & 8 ) != 0; + rPresSettings.mbEndless = ( nFlags & 0x80 ) != 0; + rPresSettings.mbFullScreen = ( nFlags & 0x10 ) == 0; +// rPresSettings.mnPauseTimeout; +// rPresSettings.mbShowLogo; + if ( nStartSlide && ( nStartSlide <= GetPageCount() ) ) + { + SdPage* pPage = mpDoc->GetSdPage( nStartSlide - 1, PK_STANDARD ); + if ( pPage ) + rPresSettings.maPresPage = pPage->GetName(); + } + } + + delete pStbMgr; + + // read DocumentInfo + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + mpDoc->GetObjectShell()->GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps + = xDPS->getDocumentProperties(); + sfx2::LoadOlePropertySet(xDocProps, &mrStorage); + xDocProps->setTemplateName(::rtl::OUString()); + + pSdrModel->setLock( sal_False ); + pSdrModel->EnableUndo(true); + return bOk; +} + +void ImplSdPPTImport::SetHeaderFooterPageSettings( SdPage* pPage, const PptSlidePersistEntry* pMasterPersist ) +{ + sal_uInt32 i; + PptSlidePersistList* pList = GetPageList( eAktPageKind ); + if ( ( !pList ) || ( pList->Count() <= nAktPageNum ) ) + return; + PptSlidePersistEntry& rSlidePersist = *(*pList)[ nAktPageNum ]; + HeaderFooterEntry* pHFE = rSlidePersist.pHeaderFooterEntry; + if ( pHFE ) + { + for ( i = 0; i < 4; i++ ) + { + bool bVisible = pHFE->IsToDisplay( i ); + if ( ( eAktPageKind == PPT_SLIDEPAGE ) + && ( rSlidePersist.aSlideAtom.aLayout.eLayout == PPT_LAYOUT_TITLESLIDE ) + && ( aDocAtom.bTitlePlaceholdersOmitted == TRUE ) ) + { + bVisible = sal_False; + } + if ( bVisible && pMasterPersist ) + { + sal_uInt32 nPosition = pHFE->NeedToImportInstance( i, rSlidePersist ); + if ( nPosition ) + { + Rectangle aEmpty; + bVisible = sal_False; + rStCtrl.Seek( nPosition ); + ProcessData aProcessData( rSlidePersist, (SdPage*)pPage ); + SdrObject* pObj = ImportObj( rStCtrl, (void*)&aProcessData, aEmpty, aEmpty ); + if ( pObj ) + pPage->NbcInsertObject( pObj, 0 ); + } + } + String aPlaceHolderString; + if ( pHFE->pPlaceholder ) + aPlaceHolderString = pHFE->pPlaceholder[ i ]; + + sd::HeaderFooterSettings rHeaderFooterSettings( pPage->getHeaderFooterSettings() ); + switch( i ) + { + case 0 : + { + rHeaderFooterSettings.mbDateTimeVisible = bVisible; + rHeaderFooterSettings.mbDateTimeIsFixed = ( pHFE->nAtom & 0x20000 ) == 0; + rHeaderFooterSettings.maDateTimeText = aPlaceHolderString; + SvxDateFormat eDateFormat; + SvxTimeFormat eTimeFormat; + PPTFieldEntry::GetDateTime( pHFE->nAtom & 0xff, eDateFormat, eTimeFormat ); + rHeaderFooterSettings.meDateTimeFormat = eDateFormat | ( eTimeFormat << 4 ); + } + break; + case 1 : + { + rHeaderFooterSettings.mbHeaderVisible = bVisible; + rHeaderFooterSettings.maHeaderText = aPlaceHolderString; + } + break; + case 2 : + { + rHeaderFooterSettings.mbFooterVisible = bVisible; + rHeaderFooterSettings.maFooterText = aPlaceHolderString; + } + break; + case 3 : + { + rHeaderFooterSettings.mbSlideNumberVisible = bVisible; + } + break; + } + pPage->setHeaderFooterSettings( rHeaderFooterSettings ); + } + } +} + +////////////////////////////////////////////////////////////////////////// +// +// Import von Seiten +// +////////////////////////////////////////////////////////////////////////// + +struct Ppt97AnimationStlSortHelper +{ + bool operator()( const std::pair< SdrObject*, Ppt97AnimationPtr >& p1, const std::pair< SdrObject*, Ppt97AnimationPtr >& p2 ); +}; + +bool Ppt97AnimationStlSortHelper::operator()( const std::pair< SdrObject*, Ppt97AnimationPtr >& p1, const std::pair< SdrObject*, Ppt97AnimationPtr >& p2 ) +{ + if( !p1.second.get() || !p2.second.get() ) + return true; + if( *p1.second < *p2.second ) + return true; + if( *p1.second > *p2.second ) + return false; + if( p1.first->GetOrdNum() < p2.first->GetOrdNum() ) + return true; + return false; +} + +void ImplSdPPTImport::ImportPageEffect( SdPage* pPage, const sal_Bool bNewAnimationsUsed ) +{ + ULONG nFilePosMerk = rStCtrl.Tell(); + + // PageKind an der Seite setzen (bisher nur PK_STANDARD oder PK_NOTES) + if ( pPage->GetPageKind() == PK_STANDARD ) + { + PptSlidePersistList* pPersistList = GetPageList( eAktPageKind ); + PptSlidePersistEntry* pActualSlidePersist = ( pPersistList && ( nAktPageNum < pPersistList->Count() ) ) + ? (*pPersistList)[ nAktPageNum ] : NULL; + + if ( pActualSlidePersist && ( eAktPageKind == PPT_SLIDEPAGE ) ) + { + if ( ! ( pActualSlidePersist->aSlideAtom.nFlags & 1 ) ) // do not follow master objects ? + { + if(pPage->TRG_HasMasterPage()) + { + SetOfByte aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); + aVisibleLayers.Set(mnBackgroundObjectsLayerID, FALSE); + pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); + } + } + } + DffRecordHeader aPageRecHd; + if ( pPage && SeekToAktPage( &aPageRecHd ) ) + { + ULONG nPageRecEnd = aPageRecHd.GetRecEndFilePos(); + + BOOL bTryTwice = ( eAktPageKind == PPT_SLIDEPAGE ); + BOOL bSSSlideInfoAtom = FALSE; + while ( TRUE ) + { + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nPageRecEnd ) ) + { + DffRecordHeader aHd; + rStCtrl >> aHd; + switch ( aHd.nRecType ) + { + case PPT_PST_SSSlideInfoAtom: + { + bSSSlideInfoAtom = TRUE; + if ( eAktPageKind == PPT_MASTERPAGE ) + { + if ( pActualSlidePersist ) + pActualSlidePersist->aPersistAtom.nReserved = aHd.GetRecBegFilePos(); + } + else + { + sal_Int8 nDirection, nTransitionType, nByteDummy, nSpeed; + sal_Int16 nBuildFlags; + sal_Int32 nSlideTime, nSoundRef; + rStCtrl >> nSlideTime // Standzeit (in Ticks) + >> nSoundRef // Index in SoundCollection + >> nDirection // Richtung des Ueberblendeffekts + >> nTransitionType // Ueberblendeffekt + >> nBuildFlags // Buildflags (s.u.) + >> nSpeed // Geschwindigkeit (langsam, mittel, schnell) + >> nByteDummy >> nByteDummy >> nByteDummy; + + switch ( nTransitionType ) + { + case PPT_TRANSITION_TYPE_BLINDS : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_VERTICAL_STRIPES );// Vertikal blenden + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_HORIZONTAL_STRIPES );// Horizontal blenden + } + break; + case PPT_TRANSITION_TYPE_CHECKER : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_HORIZONTAL_CHECKERBOARD );// Vertikal versetzt einblenden ?? + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_VERTICAL_CHECKERBOARD );// Horizontal versetzt einblenden ?? + } + break; + case PPT_TRANSITION_TYPE_COVER : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_RIGHT ); // Von rechts ueberdecken + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_BOTTOM ); // Von unten ueberdecken + else if ( nDirection == 2 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LEFT ); // Von links ueberdecken + else if ( nDirection == 3 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_TOP ); // Von oben ueberdecken + else if ( nDirection == 4 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LOWERRIGHT );// Von rechts unten ueberdecken ?? + else if ( nDirection == 5 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LOWERLEFT ); // Von links unten ueberdecken ?? + else if ( nDirection == 6 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_UPPERRIGHT );// Von rechts oben ueberdecken + else if ( nDirection == 7 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_UPPERLEFT ); // Von links oben ueberdecken ?? + } + break; + case PPT_TRANSITION_TYPE_NONE : + { + if ( nBuildFlags ) + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_NONE ); // Direkt + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_NONE ); // Direkt ueber Schwarz + } + else + pPage->setTransitionType( 0 ); + } + break; + case PPT_TRANSITION_TYPE_DISSOLVE : + pPage->SetFadeEffect(::com::sun::star::presentation::FadeEffect_DISSOLVE); // Aufloesen + break; + case PPT_TRANSITION_TYPE_RANDOM_BARS : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_HORIZONTAL_LINES ); // Horizontale Linien + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_VERTICAL_LINES ); // Vertikale Linien + } + break; + case PPT_TRANSITION_TYPE_SPLIT : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_OPEN_VERTICAL ); // Horizontal oeffnen + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_CLOSE_VERTICAL ); // Horizontal schliessen + else if ( nDirection == 2 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_OPEN_HORIZONTAL ); // Vertikal oeffnen + else if ( nDirection == 3 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_CLOSE_HORIZONTAL );// Vertikal schliessen + } + break; + case PPT_TRANSITION_TYPE_STRIPS : + { + if ( nDirection == 4 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_LOWERRIGHT );// Diagonal nach links oben + else if ( nDirection == 5 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_LOWERLEFT ); // Diagonal nach rechts oben + else if ( nDirection == 6 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_UPPERRIGHT );// Diagonal nach links unten + else if ( nDirection == 7 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_UPPERLEFT ); // Diagonal nach rechts unten + } + break; + case PPT_TRANSITION_TYPE_PULL : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LEFT ); // Nach links aufdecken + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_TOP ); // Nach oben aufdecken + else if ( nDirection == 2 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_RIGHT ); // Nach rechts aufdecken + else if ( nDirection == 3 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_BOTTOM ); // Nach unten aufdecken + else if ( nDirection == 4 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_UPPERLEFT );// Nach links oben aufdecken + else if ( nDirection == 5 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT );// Nach rechts oben aufdecken + else if ( nDirection == 6 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LOWERLEFT );// Nach links unten aufdecken + else if ( nDirection == 7 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT );// Nach rechts unten aufdecken + } + break; + case PPT_TRANSITION_TYPE_WIPE : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_RIGHT ); // Von rechts rollen + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_BOTTOM );// Von unten rollen + else if ( nDirection == 2 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_LEFT ); // Von links rollen + else if ( nDirection == 3 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_TOP ); // Von oben rollen + } + break; + case PPT_TRANSITION_TYPE_RANDOM : + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_RANDOM ); // Automatisch + break; + case PPT_TRANSITION_TYPE_FADE : + { + pPage->setTransitionType( animations::TransitionType::FADE ); + pPage->setTransitionSubtype( animations::TransitionSubType::FADEOVERCOLOR ); + pPage->setTransitionFadeColor( 0 ); + } + break; + case PPT_TRANSITION_TYPE_ZOOM : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_CENTER );// Von innen einblenden + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_TO_CENTER ); // Von aussen einblenden + } + break; + case PPT_TRANSITION_TYPE_DIAMOND : + { + pPage->setTransitionType( animations::TransitionType::IRISWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::DIAMOND ); + } + break; + case PPT_TRANSITION_TYPE_PLUS : + { + pPage->setTransitionType( animations::TransitionType::FOURBOXWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CORNERSOUT ); + } + break; + case PPT_TRANSITION_TYPE_CIRCLE : + { + pPage->setTransitionType( animations::TransitionType::ELLIPSEWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CIRCLE ); + } + break; + case PPT_TRANSITION_TYPE_WEDGE : + { + pPage->setTransitionType( animations::TransitionType::FANWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CENTERTOP ); + } + break; + case PPT_TRANSITION_TYPE_WHEEL : + { + pPage->setTransitionType( animations::TransitionType::PINWHEELWIPE ); + sal_Int16 nSubType; + switch( nDirection ) + { + default: + case 1 : nSubType = animations::TransitionSubType::ONEBLADE; break; + case 2 : nSubType = animations::TransitionSubType::TWOBLADEVERTICAL; break; + case 3 : nSubType = animations::TransitionSubType::THREEBLADE; break; + case 4 : nSubType = animations::TransitionSubType::FOURBLADE; break; + case 8 : nSubType = animations::TransitionSubType::EIGHTBLADE; break; + } + pPage->setTransitionSubtype( nSubType ); + } + break; + case PPT_TRANSITION_TYPE_PUSH : + { + pPage->setTransitionType( animations::TransitionType::PUSHWIPE ); + sal_Int16 nSubType; + switch( nDirection ) + { + default: + case 0 : nSubType = animations::TransitionSubType::FROMRIGHT; break; + case 1 : nSubType = animations::TransitionSubType::FROMBOTTOM; break; + case 2 : nSubType = animations::TransitionSubType::FROMLEFT; break; + case 3 : nSubType = animations::TransitionSubType::FROMTOP; break; + } + pPage->setTransitionSubtype( nSubType ); + } + break; + case PPT_TRANSITION_TYPE_COMB : + { + pPage->setTransitionType( animations::TransitionType::PUSHWIPE ); + pPage->setTransitionSubtype( nDirection ? animations::TransitionSubType::COMBVERTICAL : animations::TransitionSubType::COMBHORIZONTAL ); + } + break; + case PPT_TRANSITION_TYPE_NEWSFLASH : + { + pPage->setTransitionType( animations::TransitionType::FOURBOXWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CORNERSOUT ); +/* + pPage->setTransitionType( animations::TransitionType::ZOOM ); + pPage->setTransitionSubtype( animations::TransitionSubType::ROTATEIN ); +*/ + } + break; + case PPT_TRANSITION_TYPE_SMOOTHFADE : + { + pPage->setTransitionType( animations::TransitionType::FADE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CROSSFADE ); + } + break; + } + + if ( nSpeed == 0 ) + pPage->setTransitionDuration( 3.0 ); // langsam + else if ( nSpeed == 1 ) + pPage->setTransitionDuration( 2.0 ); // mittel + else if ( nSpeed == 2 ) + pPage->setTransitionDuration( 1.0 ); // schnell + + if ( nBuildFlags & 0x400 ) // slidechange by time + { // Standzeit (in Ticks) + pPage->SetPresChange( PRESCHANGE_AUTO ); + pPage->SetTime( nSlideTime / 1000 ); + } + else + pPage->SetPresChange( mePresChange ); + +// if ( nBuildFlags & 1 ) // slidechange by mouseclick +// pPage->SetPresChange( mePresChange ); + + if ( nBuildFlags & 4 ) + pPage->SetExcluded( TRUE ); // Dia nicht anzeigen + if ( nBuildFlags & 16 ) + { // Dia mit Soundeffekt + pPage->SetSound( TRUE ); + String aSoundFile( ReadSound( nSoundRef ) ); + pPage->SetSoundFile( aSoundFile ); + } + if ( nBuildFlags & ( 1 << 6 ) ) // Loop until next sound + pPage->SetLoopSound( sal_True ); + if ( nBuildFlags & ( 1 << 8 ) ) // Stop the previous sound + pPage->SetStopSound( sal_True ); + break; + } + } + } + aHd.SeekToEndOfRecord( rStCtrl ); + } + if ( bTryTwice && ( bSSSlideInfoAtom == FALSE ) ) + { + bTryTwice = FALSE; + if ( HasMasterPage( nAktPageNum, eAktPageKind ) ) + { + USHORT nMasterNum = GetMasterPageIndex( nAktPageNum, eAktPageKind ); + PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); + if ( pPageList && ( nMasterNum < pPageList->Count() ) ) + { + PptSlidePersistEntry* pE = (*pPageList)[ nMasterNum ]; + if ( pE ) + { + UINT32 nOfs = pE->aPersistAtom.nReserved; + if ( nOfs ) + { + rStCtrl.Seek( nOfs ); + nPageRecEnd = nOfs + 16; + continue; + } + } + } + + } + } + break; + } + } + } + + if ( !bNewAnimationsUsed ) + { + tAnimationVector aAnimationsOnThisPage; + + // add effects from page in correct order + SdrObjListIter aSdrIter( *pPage, IM_FLAT ); + while ( aSdrIter.IsMore() ) + { + SdrObject* pObj = aSdrIter.Next(); + tAnimationMap::iterator aFound = maAnimations.find( pObj ); + if( aFound != maAnimations.end() ) + { + std::pair< SdrObject*, Ppt97AnimationPtr > aPair( (*aFound).first, (*aFound).second ); + aAnimationsOnThisPage.push_back( aPair ); + } + } + + Ppt97AnimationStlSortHelper aSortHelper; + std::sort( aAnimationsOnThisPage.begin(), aAnimationsOnThisPage.end(), aSortHelper ); + + tAnimationVector::iterator aIter( aAnimationsOnThisPage.begin() ); + const tAnimationVector::iterator aEnd( aAnimationsOnThisPage.end() ); + + for( ;aIter != aEnd; aIter++ ) + { + Ppt97AnimationPtr pPpt97Animation = (*aIter).second;; + if( pPpt97Animation.get() ) + pPpt97Animation->createAndSetCustomAnimationEffect( (*aIter).first ); + } + } + rStCtrl.Seek( nFilePosMerk ); +} + +////////////////////////////////////////////////////////////////////////// +// +// Import von Sounds +// +// Die Sounds werden nicht nur als String importiert sondern auch +// in die Gallery einefuegt, falls dort noch nicht vorhanden. +// +/////////////////////////////////////////////////////////////////////////// + +String ImplSdPPTImport::ReadSound(UINT32 nSoundRef) const +{ + String aRetval; + UINT32 nPosMerk = rStCtrl.Tell(); + DffRecordHeader aDocHd; + if ( SeekToDocument( &aDocHd ) ) + { + UINT32 nSoundLen = aDocHd.GetRecEndFilePos(); + DffRecordHeader aSoundBlockRecHd; + if( SeekToRec( rStCtrl, PPT_PST_SoundCollection, nSoundLen, &aSoundBlockRecHd ) ) + { + UINT32 nDataLen = aSoundBlockRecHd.GetRecEndFilePos(); + DffRecordHeader aSoundRecHd; + BOOL bRefStrValid = FALSE; + BOOL bDone = FALSE; + + while( !bDone && SeekToRec( rStCtrl, PPT_PST_Sound, nDataLen, &aSoundRecHd ) ) + { + UINT32 nStrLen = aSoundRecHd.GetRecEndFilePos(); + String aRefStr; + UINT32 nPosMerk2 = rStCtrl.Tell(); + if ( SeekToRec( rStCtrl, PPT_PST_CString, nStrLen, NULL, 2 ) ) + { + if ( ReadString( aRefStr ) ) + bRefStrValid = TRUE; + } + if ( bRefStrValid ) + { + if ( UniString::CreateFromInt32( nSoundRef ) == aRefStr ) + { + rStCtrl.Seek( nPosMerk2 ); + if ( SeekToRec( rStCtrl, PPT_PST_CString, nStrLen, NULL, 0 ) ) + { + ReadString( aRetval ); + bDone = TRUE; + } + } + } + if ( bDone ) + { + // ueberpruefen, ob diese Sound-Datei schon + // existiert. Wenn nicht, exportiere diese + // in unser lokales Sound-Verzeichnis. + BOOL bSoundExists = FALSE; + List* pSoundList = new List(); + + GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, *pSoundList ); + GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, *pSoundList ); + + for( ULONG n = 0; ( n < pSoundList->Count() ) && !bSoundExists; n++ ) + { + INetURLObject aURL( *(String*)pSoundList->GetObject( n ) ); + String aSoundName( aURL.GetName() ); + + if( aSoundName == aRetval ) + { + aRetval = *(String*)pSoundList->GetObject( n ); + bSoundExists = TRUE; + } + } + + for ( void* pPtr = pSoundList->First(); pPtr; pPtr = pSoundList->Next() ) + delete (String*)pPtr; + + delete pSoundList; + + if ( !bSoundExists ) + { + rStCtrl.Seek( nPosMerk2 ); + DffRecordHeader aSoundDataRecHd; + if ( SeekToRec( rStCtrl, PPT_PST_SoundData, nStrLen, &aSoundDataRecHd, 0 ) ) + { + String aGalleryDir( SvtPathOptions().GetGalleryPath() ); + INetURLObject aGalleryUserSound( aGalleryDir.GetToken( aGalleryDir.GetTokenCount( ';' ) - 1 ) ); + + aGalleryUserSound.Append( aRetval ); + UINT32 nSoundDataLen = aSoundDataRecHd.nRecLen; + UINT8* pBuf = new UINT8[ nSoundDataLen ]; + + rStCtrl.Read( pBuf, nSoundDataLen ); + SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aGalleryUserSound.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_TRUNC ); + + if( pOStm ) + { + pOStm->Write( pBuf, nSoundDataLen ); + + if( pOStm->GetError() == ERRCODE_NONE ) + { + GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aGalleryUserSound.GetMainURL( INetURLObject::NO_DECODE ) ); + aRetval = aGalleryUserSound.GetMainURL( INetURLObject::NO_DECODE ); + } + + delete pOStm; + } + + delete[] pBuf; + } + } + } + if ( !bDone ) + aSoundRecHd.SeekToEndOfRecord( rStCtrl ); + } + } + } + rStCtrl.Seek( nPosMerk ); + return aRetval; +} + +////////////////////////////////////////////////////////////////////////// +// +// media object import, the return value is the url to the media object +// +////////////////////////////////////////////////////////////////////////// + +String ImplSdPPTImport::ReadMedia( sal_uInt32 nMediaRef ) const +{ + String aRetVal; + DffRecordHeader* pHd( const_cast<ImplSdPPTImport*>(this)->aDocRecManager.GetRecordHeader( PPT_PST_ExObjList, SEEK_FROM_BEGINNING ) ); + if ( pHd ) + { + pHd->SeekToContent( rStCtrl ); + while ( ( rStCtrl.Tell() < pHd->GetRecEndFilePos() ) && !aRetVal.Len() ) + { + DffRecordHeader aHdMovie; + rStCtrl >> aHdMovie; + switch( aHdMovie.nRecType ) + { + case PPT_PST_ExAviMovie : + case PPT_PST_ExMCIMovie : + { + DffRecordHeader aExVideoHd; + if ( SeekToRec( rStCtrl, PPT_PST_ExVideo, aHdMovie.GetRecEndFilePos(), &aExVideoHd ) ) + { + DffRecordHeader aExMediaAtomHd; + if ( SeekToRec( rStCtrl, PPT_PST_ExMediaAtom, aExVideoHd.GetRecEndFilePos(), &aExMediaAtomHd ) ) + { + sal_uInt32 nRef; + rStCtrl >> nRef; + if ( nRef == nMediaRef ) + { + aExVideoHd.SeekToContent( rStCtrl ); + while( rStCtrl.Tell() < aExVideoHd.GetRecEndFilePos() ) + { + DffRecordHeader aHd; + rStCtrl >> aHd; + switch( aHd.nRecType ) + { + case PPT_PST_CString : + { + aHd.SeekToBegOfRecord( rStCtrl ); + String aStr; + if ( ReadString( aStr ) ) + { + if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aStr, aRetVal ) ) + { + aRetVal = INetURLObject( aRetVal ).GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ); + } + } + } + break; + } + aHd.SeekToEndOfRecord( rStCtrl ); + } + break; + } + } + } + } + break; + } + aHdMovie.SeekToEndOfRecord( rStCtrl ); + } + } + return aRetVal; +} + +////////////////////////////////////////////////////////////////////////// +// +// Import von Objekten +// +////////////////////////////////////////////////////////////////////////// + +void ImplSdPPTImport::FillSdAnimationInfo( SdAnimationInfo* pInfo, PptInteractiveInfoAtom* pIAtom, String aMacroName ) +{ + // Lokale Informationen in pInfo eintragen + if( pIAtom->nSoundRef ) + { + pInfo->SetBookmark( ReadSound( pIAtom->nSoundRef ) ); // Pfad zum Soundfile in MSDOS-Notation + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_SOUND; // RunProgramAction + } +// if ( nFlags & 0x01 ) // koennen wir nicht ( beim Anklicken markieren ) + switch ( pIAtom->nAction ) + { +// case 0x01 : // MacroAction +// { +// pInfo->meClickAction = ::com::sun::star::presentation::::com::sun::star::presentation::ClickAction_MACRO; +// // aMacro liegt in folgender Form vor: +// // "Macroname.Modulname.Libname.Dokumentname" oder +// // "Macroname.Modulname.Libname.Applikationsname" +// pInfo->maBookmark = aMacroName; +// } +// break; + case 0x02 : // RunProgramAction + { + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_PROGRAM; + pInfo->SetBookmark( aMacroName ); // Programmname in aBookmark + } + break; + case 0x03 : // JumpAction + { + switch( pIAtom->nJump ) + { + case 0x01 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_NEXTPAGE; // Next slide + break; + case 0x02 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_PREVPAGE; // Previous slide + break; + case 0x03 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_FIRSTPAGE; // First slide + break; + case 0x04 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_LASTPAGE; // last Slide + break; + case 0x05 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_PREVPAGE; // Last slide viewed + break; + case 0x06 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_STOPPRESENTATION; // End show + break; + default : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_NONE; // 0x00: no action, else unknown + break; + } + } + break; + case 0x04 : + { + SdHyperlinkEntry* pPtr; + for ( pPtr = (SdHyperlinkEntry*)aHyperList.First(); pPtr; pPtr = (SdHyperlinkEntry*)aHyperList.Next() ) + { + if ( pPtr->nIndex == pIAtom->nExHyperlinkId ) + break; + } + if ( pPtr ) + { + switch( pIAtom->nHyperlinkType ) + { + case 9: + case 8: // hyperlink : URL + { + if ( pPtr->aTarget.Len() ) + { + ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh(); + if ( pDocShell ) + { + String aBaseURL = pDocShell->GetMedium()->GetBaseURL(); + String aBookmarkURL( pInfo->GetBookmark() ); + INetURLObject aURL( pPtr->aTarget ); + if( INET_PROT_NOT_VALID == aURL.GetProtocol() ) + utl::LocalFileHelper::ConvertSystemPathToURL( pPtr->aTarget, aBaseURL, aBookmarkURL ); + if( !aBookmarkURL.Len() ) + aBookmarkURL = URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), pPtr->aTarget, URIHelper::GetMaybeFileHdl(), true ); + pInfo->SetBookmark( aBookmarkURL ); + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_PROGRAM; + } + } + } + break; + + case 10: + break; + + case 7: // hyperlink auf eine Seite + { + if ( pPtr->aConvSubString.Len() ) + { + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_BOOKMARK; + pInfo->SetBookmark( pPtr->aConvSubString ); + } + } + break; + } + } + } + break; + case 0x05 : // OLEAction ( OLEVerb to use, 0==first, 1==secnd, .. ) + case 0x06 : // MediaAction + case 0x07 : // CustomShowAction + default : // 0x00: no action, else unknown action + break; + } +} + +SdrObject* ImplSdPPTImport::ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pObj, SdPage* pPage, + SfxStyleSheet* pSheet, SfxStyleSheet** ppStyleSheetAry ) const +{ + SfxStyleSheet* pStyleSheetAry[ 9 ]; + SdrTextObj* pText = pObj; + SdrObject* pRet = pText; + + ppStyleSheetAry = NULL; + + PresObjKind ePresKind = PRESOBJ_NONE; + PptOEPlaceholderAtom* pPlaceHolder = pTextObj->GetOEPlaceHolderAtom(); + String aPresentationText; + if ( pPlaceHolder ) + { + switch( pPlaceHolder->nPlaceholderId ) + { + case PPT_PLACEHOLDER_MASTERNOTESSLIDEIMAGE : + case PPT_PLACEHOLDER_MASTERCENTEREDTITLE : + case PPT_PLACEHOLDER_MASTERTITLE : + { + ePresKind = PRESOBJ_TITLE; + aPresentationText = pPage->GetPresObjText( ePresKind ); + } + break; + case PPT_PLACEHOLDER_MASTERBODY : + { + ePresKind = PRESOBJ_OUTLINE; + aPresentationText = pPage->GetPresObjText( ePresKind ); + } + break; + case PPT_PLACEHOLDER_MASTERSUBTITLE : + { + ePresKind = PRESOBJ_TEXT; + aPresentationText = pPage->GetPresObjText( ePresKind ); + } + break; + case PPT_PLACEHOLDER_MASTERNOTESBODYIMAGE : + { + ePresKind = PRESOBJ_NOTES; + aPresentationText = pPage->GetPresObjText( ePresKind ); + } + break; + case PPT_PLACEHOLDER_MASTERDATE : ePresKind = PRESOBJ_DATETIME; break; + case PPT_PLACEHOLDER_MASTERSLIDENUMBER : ePresKind = PRESOBJ_SLIDENUMBER;break; + case PPT_PLACEHOLDER_MASTERFOOTER : ePresKind = PRESOBJ_FOOTER; break; + case PPT_PLACEHOLDER_MASTERHEADER : ePresKind = PRESOBJ_HEADER; break; + } + } + switch ( pTextObj->GetDestinationInstance() ) + { + case TSS_TYPE_PAGETITLE : + case TSS_TYPE_TITLE : + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for titleobject (SJ)" ); + } + break; + case TSS_TYPE_SUBTITLE : + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for subtitleobject (SJ)" ); + } + break; + case TSS_TYPE_BODY : + case TSS_TYPE_HALFBODY : + case TSS_TYPE_QUARTERBODY : + { + for ( UINT16 nLevel = 9; nLevel; nLevel-- ) + { + String aName( pPage->GetLayoutName() ); + aName.Append( (sal_Unicode)( ' ' ) ); + aName.Append( String::CreateFromInt32( nLevel ) ); + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( aName, SD_STYLE_FAMILY_MASTERPAGE ); + if ( pSheet ) + pText->StartListening( *pSheet ); + pStyleSheetAry[ nLevel - 1 ] = pSheet; + } + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for outlinerobject (SJ)" ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + ppStyleSheetAry = &pStyleSheetAry[ 0 ]; + } + break; + case TSS_TYPE_NOTES : + { + if ( pPlaceHolder && ( ( pPlaceHolder->nPlaceholderId == PPT_PLACEHOLDER_NOTESSLIDEIMAGE ) + || ( pPlaceHolder->nPlaceholderId == PPT_PLACEHOLDER_MASTERNOTESSLIDEIMAGE ) ) ) + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for titleobject (SJ)" ); + } + else + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES ); + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for notesobj (SJ)" ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + } + } + break; + case TSS_TYPE_UNUSED : + case TSS_TYPE_TEXT_IN_SHAPE : + { + switch( ePresKind ) + { + case PRESOBJ_DATETIME : + case PRESOBJ_SLIDENUMBER : + case PRESOBJ_FOOTER : + case PRESOBJ_HEADER : + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( String(SdResId( STR_PSEUDOSHEET_BACKGROUNDOBJECTS )), SD_STYLE_FAMILY_PSEUDO ); + break; + default : + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( String(SdResId( STR_STANDARD_STYLESHEET_NAME )), SD_STYLE_FAMILY_GRAPHICS ); + } + } + break; + } + pText = (SdrTextObj*)SdrPowerPointImport::ApplyTextObj( pTextObj, pText, pPage, pSheet, ppStyleSheetAry ); + if ( pPlaceHolder && pPlaceHolder->nPlaceholderId ) + { + if ( eAktPageKind == PPT_MASTERPAGE ) + { + sal_Bool bCreatePlaceHolder = ( pTextObj->GetInstance() != TSS_TYPE_SUBTITLE ) && ( pTextObj->GetInstance() != TSS_TYPE_UNUSED ); + sal_Bool bIsHeaderFooter = ( ePresKind == PRESOBJ_HEADER) || (ePresKind == PRESOBJ_FOOTER) + || (ePresKind == PRESOBJ_DATETIME) || (ePresKind == PRESOBJ_SLIDENUMBER); + if ( bCreatePlaceHolder && ( pTextObj->GetInstance() == TSS_TYPE_TEXT_IN_SHAPE ) ) + bCreatePlaceHolder = bIsHeaderFooter; + if ( bCreatePlaceHolder ) + { + if ( !bIsHeaderFooter ) + { + pText->SetNotVisibleAsMaster( TRUE ); + pText->SetEmptyPresObj( TRUE ); + } + pText->SetUserCall( pPage ); + pPage->InsertPresObj( pText, ePresKind ); + SdrOutliner* pOutl = NULL; + if ( pTextObj->GetInstance() == TSS_TYPE_NOTES ) + pOutl = GetDrawOutliner( pText ); + if ( aPresentationText.Len() ) + pPage->SetObjText( (SdrTextObj*)pText, pOutl, ePresKind, aPresentationText ); + + if ( pPage->GetPageKind() != PK_NOTES ) + { + SfxStyleSheet* pSheet2( pPage->GetStyleSheetForPresObj( ePresKind ) ); + if ( pSheet2 ) + { + SfxItemSet& rItemSet = pSheet2->GetItemSet(); + rItemSet.Put( (SdrTextLeftDistItem&)pText->GetMergedItem( SDRATTR_TEXT_LEFTDIST ) ); + rItemSet.Put( (SdrTextRightDistItem&)pText->GetMergedItem( SDRATTR_TEXT_RIGHTDIST ) ); + rItemSet.Put( (SdrTextUpperDistItem&)pText->GetMergedItem( SDRATTR_TEXT_UPPERDIST ) ); + rItemSet.Put( (SdrTextLowerDistItem&)pText->GetMergedItem( SDRATTR_TEXT_LOWERDIST ) ); + rItemSet.Put( (SdrTextVertAdjustItem&)pText->GetMergedItem( SDRATTR_TEXT_VERTADJUST ) ); + rItemSet.Put( (SdrTextHorzAdjustItem&)pText->GetMergedItem( SDRATTR_TEXT_HORZADJUST ) ); + } + pText->NbcSetStyleSheet( pSheet2, FALSE ); + } + + SfxItemSet aTempAttr( mpDoc->GetPool() ); + SdrTextMinFrameHeightItem aMinHeight( pText->GetLogicRect().GetSize().Height() ); + aTempAttr.Put( aMinHeight ); + SdrTextAutoGrowHeightItem aAutoGrowHeight( FALSE ); + aTempAttr.Put( aAutoGrowHeight ); + pText->SetMergedItemSet(aTempAttr); + } + else + { + pRet = NULL; + } + } + else + { + const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom(); + if ( pSlideLayout || ( eAktPageKind == PPT_NOTEPAGE ) ) + { + INT16 nPlaceholderId = pPlaceHolder->nPlaceholderId; + UINT16 i = 0; + if ( eAktPageKind == PPT_SLIDEPAGE ) + { + for ( ; i < 8; i++ ) + { + if ( pSlideLayout->aPlaceholderId[ i ] == nPlaceholderId ) + break; + } + } + if ( i < 8 ) + { + PresObjKind ePresObjKind = PRESOBJ_NONE; + sal_Bool bEmptyPresObj = sal_True; + sal_Bool bVertical = sal_False; + if ( ( pTextObj->GetShapeType() == mso_sptRectangle ) || ( pTextObj->GetShapeType() == mso_sptTextBox ) ) + { + if ( pTextObj->Count() ) + bEmptyPresObj = sal_False; + switch ( nPlaceholderId ) + { + case PPT_PLACEHOLDER_NOTESBODY : ePresObjKind = PRESOBJ_NOTES; break; + case PPT_PLACEHOLDER_VERTICALTEXTTITLE : + bVertical = sal_True; // PASSTHROUGH !!! + case PPT_PLACEHOLDER_TITLE : ePresObjKind = PRESOBJ_TITLE; break; + case PPT_PLACEHOLDER_VERTICALTEXTBODY : + bVertical = sal_True; // PASSTHROUGH !!! + case PPT_PLACEHOLDER_BODY : ePresObjKind = PRESOBJ_OUTLINE; break; + case PPT_PLACEHOLDER_CENTEREDTITLE : ePresObjKind = PRESOBJ_TITLE; break; + case PPT_PLACEHOLDER_SUBTITLE : ePresObjKind = PRESOBJ_TEXT; break; // PRESOBJ_OUTLINE + + default : + { + if ( !pTextObj->Count() ) + { + switch ( nPlaceholderId ) + { + case PPT_PLACEHOLDER_MEDIACLIP : + case PPT_PLACEHOLDER_OBJECT : ePresObjKind = PRESOBJ_OBJECT; break; + case PPT_PLACEHOLDER_GRAPH : ePresObjKind = PRESOBJ_CHART; break; + case PPT_PLACEHOLDER_TABLE : ePresObjKind = PRESOBJ_TABLE; break; + case PPT_PLACEHOLDER_CLIPART : ePresObjKind = PRESOBJ_GRAPHIC; break; + case PPT_PLACEHOLDER_ORGANISZATIONCHART : ePresObjKind = PRESOBJ_ORGCHART; break; + } + } + }; + } + } + else if ( pTextObj->GetShapeType() == mso_sptPictureFrame ) + { + if ( !pTextObj->Count() && pObj->ISA( SdrGrafObj ) ) + { + bEmptyPresObj = sal_False; + switch ( nPlaceholderId ) + { + case PPT_PLACEHOLDER_MEDIACLIP : + case PPT_PLACEHOLDER_OBJECT : ePresObjKind = PRESOBJ_OBJECT; break; + case PPT_PLACEHOLDER_GRAPH : ePresObjKind = PRESOBJ_CHART; break; + case PPT_PLACEHOLDER_TABLE : ePresObjKind = PRESOBJ_CALC; break; + case PPT_PLACEHOLDER_CLIPART : ePresObjKind = PRESOBJ_GRAPHIC; break; + case PPT_PLACEHOLDER_ORGANISZATIONCHART : ePresObjKind = PRESOBJ_ORGCHART; break; + } + } + } + if ( ePresObjKind != PRESOBJ_NONE ) + { + if ( !bEmptyPresObj ) + { + pPage->InsertPresObj( pRet, ePresObjKind ); + } + else + { + SdrObject* pPresObj = pPage->CreatePresObj( ePresObjKind, bVertical, pText->GetLogicRect(), TRUE ); + pPresObj->SetUserCall( pPage ); + + SfxItemSet aSet( pSdrModel->GetItemPool() ); + ApplyAttributes( rStCtrl, aSet ); + pPresObj->SetMergedItemSet(aSet); + + if ( ( eAktPageKind != PPT_NOTEPAGE ) && ( pSlideLayout->aPlacementId[ i ] != (ULONG)-1 ) ) + { + SdrObject* pTitleObj = ((SdPage&)pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_TITLE ); + SdrObject* pOutlineObj = ((SdPage&)pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_OUTLINE ); + + Rectangle aTitleRect; + Rectangle aOutlineRect; + Size aOutlineSize; + + if ( pTitleObj ) + aTitleRect = pTitleObj->GetLogicRect(); + if ( pOutlineObj ) + { + aOutlineRect = pOutlineObj->GetLogicRect(); + aOutlineSize = aOutlineRect.GetSize(); + } + Rectangle aLogicRect( pPresObj->GetLogicRect() ); + Size aLogicSize( aLogicRect.GetSize() ); + + switch ( pSlideLayout->aPlacementId[ i ] ) + { + case 0 : // Lage im Titelbereich + { + if ( aLogicRect != aTitleRect ) + pPresObj->SetUserCall( NULL ); + } + break; + + case 1: + { + if ( pSlideLayout->eLayout == PPT_LAYOUT_TITLEANDBODYSLIDE ) + { // Lage im Outlinebereich + if ( aLogicRect != aOutlineRect ) + pPresObj->SetUserCall( NULL ); + } + else if ( pSlideLayout->eLayout == PPT_LAYOUT_2COLUMNSANDTITLE ) + { // Lage im Outlinebereich links + if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || + aLogicSize.Width() / aOutlineSize.Width() < 0.48 || + aLogicSize.Width() / aOutlineSize.Width() > 0.5) + { + pPresObj->SetUserCall(NULL); + } + } + else if ( pSlideLayout->eLayout == PPT_LAYOUT_2ROWSANDTITLE ) + { // Lage im Outlinebereich oben + if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || + Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE) + { + pPresObj->SetUserCall( NULL ); + } + } + else if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE) + { // Lage im Outlinebereich links oben + pPresObj->SetUserCall( NULL ); + } + } + break; + + case 2: + { + if ( pSlideLayout->eLayout == PPT_LAYOUT_2COLUMNSANDTITLE ) + { // Lage im Outlinebereich rechts + if (Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || + aLogicSize.Width() / aOutlineSize.Width() < 0.48 || + aLogicSize.Width() / aOutlineSize.Width() > 0.5) + { + pPresObj->SetUserCall( NULL ); + } + } + else if ( pSlideLayout->eLayout == PPT_LAYOUT_2ROWSANDTITLE ) + { // Lage im Outlinebereich unten + if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || + Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE) + { + pPresObj->SetUserCall( NULL ); + } + } + else if (Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE) + { // Lage im Outlinebereich rechts oben + pPresObj->SetUserCall(NULL); + } + } + break; + + case 3: + { // Lage im Outlinebereich links unten + if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE) + { + pPresObj->SetUserCall( NULL ); + } + } + break; + + case 4: + { // Lage im Outlinebereich rechts unten + if (Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE) + { + pObj->SetUserCall( NULL ); + } + } + break; + } + } + pRet = NULL; // return zero cause this obj was already inserted by CreatePresObj + } + } + else if ( !pTextObj->Count() ) + pRet = NULL; + } + } + } + } + if ( pRet != pText ) + { + SdrObject* pFree( pText ); + SdrObject::Free( pFree ); + } + return pRet; +} + +SdrObject* ImplSdPPTImport::ProcessObj( SvStream& rSt, DffObjData& rObjData, void* pData, Rectangle& rTextRect, SdrObject* pRet ) +{ + SdrObject* pObj = SdrPowerPointImport::ProcessObj( rSt, rObjData, pData, rTextRect, pRet ); + + // Animationseffekte des Objektes lesen + if ( pObj ) + { + // further setup placeholder objects + if( pObj->ISA(SdrPageObj) && pData ) + { + const ProcessData* pProcessData=(const ProcessData*)pData; + if( pProcessData->pPage ) + pProcessData->pPage->InsertPresObj( pObj, PRESOBJ_PAGE ); + } + + BOOL bInhabitanceChecked = FALSE; + BOOL bAnimationInfoFound = FALSE; + DffRecordHeader aMasterShapeHd; + + if ( maShapeRecords.SeekToContent( rSt, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) ) + { + DffRecordHeader& rHdClientData = *maShapeRecords.Current(); + while( TRUE ) + { + UINT32 nClientDataLen = rHdClientData.GetRecEndFilePos(); + DffRecordHeader aHd; + do + { + rSt >> aHd; + UINT32 nHdRecEnd = aHd.GetRecEndFilePos(); + switch ( aHd.nRecType ) + { + case PPT_PST_AnimationInfo : + { + DffRecordHeader aHdAnimInfoAtom; + if ( SeekToRec( rSt, PPT_PST_AnimationInfoAtom, nHdRecEnd, &aHdAnimInfoAtom ) ) + { + // read data from stream + Ppt97AnimationPtr pAnimation( new Ppt97Animation( rSt ) ); + // store animation informations + if( pAnimation->HasEffect() ) + { + // translate color to RGB + pAnimation->SetDimColor( MSO_CLR_ToColor(pAnimation->GetDimColor()).GetColor() ); + // translate sound bits to file url + if( pAnimation->HasSoundEffect() ) + pAnimation->SetSoundFileUrl( ReadSound( pAnimation->GetSoundRef() ) ); + + bool bDontAnimateInvisibleShape = false; + { + SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj); + + if( pTextObj && pTextObj->HasText() && + !pObj->ISA( SdrObjGroup ) && + pAnimation->HasAnimateAssociatedShape() ) + { + const SfxItemSet& rObjItemSet = pObj->GetMergedItemSet(); + + XFillStyle eFillStyle = ((XFillStyleItem&)(rObjItemSet.Get(XATTR_FILLSTYLE))).GetValue(); + XLineStyle eLineStyle = ((XLineStyleItem&)(rObjItemSet.Get(XATTR_LINESTYLE))).GetValue(); + + if ( ( eFillStyle == XFILL_NONE ) && ( eLineStyle == XLINE_NONE ) ) + bDontAnimateInvisibleShape = true; + } + } + if( bDontAnimateInvisibleShape ) + pAnimation->SetAnimateAssociatedShape(false); + + //maybe some actions necessary to ensure that animations on master pages are played before animations on normal pages + ///mabe todo in future: bool bIsEffectOnMasterPage = !bInhabitanceChecked;? + + maAnimations[pObj] = pAnimation; + + bAnimationInfoFound = TRUE; + } + } + } + break; + case PPT_PST_InteractiveInfo: + { + UINT32 nFilePosMerk2 = rSt.Tell(); + String aMacroName; + + if(SeekToRec( rSt, PPT_PST_CString, nHdRecEnd, NULL, 0 ) ) + ReadString(aMacroName); + + rSt.Seek( nFilePosMerk2 ); + DffRecordHeader aHdInteractiveInfoAtom; + if ( SeekToRec( rSt, PPT_PST_InteractiveInfoAtom, nHdRecEnd, &aHdInteractiveInfoAtom ) ) + { + PptInteractiveInfoAtom aInteractiveInfoAtom; + rSt >> aInteractiveInfoAtom; + + // interactive object + SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pObj, true); + + ( (ImplSdPPTImport*) this )->FillSdAnimationInfo( pInfo, &aInteractiveInfoAtom, aMacroName ); + if ( aInteractiveInfoAtom.nAction == 6 ) // Sj -> media action + { + rHdClientData.SeekToContent( rStCtrl ); + DffRecordHeader aObjRefAtomHd; + if ( SeekToRec( rSt, PPT_PST_ExObjRefAtom, nHdRecEnd, &aObjRefAtomHd ) ) + { + sal_uInt32 nRef; + rSt >> nRef; + String aMediaURL( ReadMedia( nRef ) ); + if ( !aMediaURL.Len() ) + aMediaURL = ReadSound( nRef ); + if ( aMediaURL.Len() ) + { + SdrMediaObj* pMediaObj = new SdrMediaObj( pObj->GetSnapRect() ); + pMediaObj->SetModel( pObj->GetModel() ); + pMediaObj->SetMergedItemSet( pObj->GetMergedItemSet() ); + + //--remove object from maAnimations list and add the new object instead + Ppt97AnimationPtr pAnimation; + { + tAnimationMap::iterator aFound = maAnimations.find( pObj ); + if( aFound != maAnimations.end() ) + { + pAnimation = (*aFound).second; + maAnimations.erase(aFound); + } + maAnimations[pMediaObj] = pAnimation; + } + //-- + + SdrObject::Free( pObj ), pObj = pMediaObj; // SJ: hoping that pObj is not inserted in any list + pMediaObj->setURL( aMediaURL ); + } + } + } + } + } + break; + } + aHd.SeekToEndOfRecord( rSt ); + } + while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nClientDataLen ) ); + + if ( bInhabitanceChecked || bAnimationInfoFound ) + break; + bInhabitanceChecked = TRUE; + if ( ! ( IsProperty( DFF_Prop_hspMaster ) && SeekToShape( rSt, pData, GetPropertyValue( DFF_Prop_hspMaster ) ) ) ) + break; + rSt >> aMasterShapeHd; + if ( !SeekToRec( rSt, DFF_msofbtClientData, aMasterShapeHd.GetRecEndFilePos(), &aMasterShapeHd ) ) + break; + aMasterShapeHd.SeekToContent( rSt ); + rHdClientData = aMasterShapeHd; + } + } + } + return pObj; +} + +// --------------------- +// - exported function - +// --------------------- + +extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL ImportPPT( const ::rtl::OUString& rConfigPath, + uno::Sequence< beans::PropertyValue >* pConfigData, + SdDrawDocument* pDocument, SvStream& rDocStream, SvStorage& rStorage, SfxMedium& rMedium ) +{ + sal_Bool bRet = sal_False; + + MSFilterTracer aTracer( rConfigPath, pConfigData ); + aTracer.StartTracing(); + + SdPPTImport* pImport = new SdPPTImport( pDocument, rDocStream, rStorage, rMedium, &aTracer ); + bRet = pImport->Import(); + + aTracer.EndTracing(); + delete pImport; + + return bRet; +} diff --git a/sd/source/filter/ppt/pptin.hxx b/sd/source/filter/ppt/pptin.hxx new file mode 100644 index 000000000000..24e300bd79e9 --- /dev/null +++ b/sd/source/filter/ppt/pptin.hxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPTIN_HXX +#define _SD_PPTIN_HXX + +#include <filter/msfilter/svdfppt.hxx> +#include <svx/msdffdef.hxx> +#include <diadef.h> +#include <svx/svdtypes.hxx> +#include <filter/msfilter/msfiltertracer.hxx> +#include <com/sun/star/uno/Any.h> +#include <boost/shared_ptr.hpp> + +class SdDrawDocument; +class SfxMedium; + +/************************************************************************* +|* +|* lokaler Import +|* +\************************************************************************/ + +class SdPage; +class SdAnimationInfo; +struct PptInteractiveInfoAtom; +class Ppt97Animation; + +typedef boost::shared_ptr< Ppt97Animation > Ppt97AnimationPtr; +typedef ::std::map < SdrObject*, Ppt97AnimationPtr > tAnimationMap; +typedef std::vector< std::pair< SdrObject*, Ppt97AnimationPtr > > tAnimationVector; + +class ImplSdPPTImport : public SdrPowerPointImport +{ + SfxMedium& mrMed; + SvStorage& mrStorage; +// SvStream* mpPicStream; + DffRecordHeader maDocHd; + List maSlideNameList; + BOOL mbDocumentFound; + sal_uInt32 mnFilterOptions; + SdDrawDocument* mpDoc; + PresChange mePresChange; + SdrLayerID mnBackgroundLayerID; + SdrLayerID mnBackgroundObjectsLayerID; + + tAnimationMap maAnimations; + + void SetHeaderFooterPageSettings( SdPage* pPage, const PptSlidePersistEntry* pMasterPersist ); + void ImportPageEffect( SdPage* pPage, const sal_Bool bNewAnimationsUsed ); + + void FillSdAnimationInfo( SdAnimationInfo* pInfo, PptInteractiveInfoAtom* pIAtom, String aMacroName ); + + virtual SdrObject* ProcessObj( SvStream& rSt, DffObjData& rData, void* pData, Rectangle& rTextRect, SdrObject* pObj ); + virtual SdrObject* ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pText, SdPage* pPage, + SfxStyleSheet*, SfxStyleSheet** ) const; + +public: + + String ReadSound( sal_uInt32 nSoundRef ) const; + String ReadMedia( sal_uInt32 nMediaRef ) const; + + ImplSdPPTImport( SdDrawDocument* pDoc, SvStorage& rStorage, SfxMedium& rMed, PowerPointImportParam& ); + ~ImplSdPPTImport(); + + sal_Bool Import(); +}; + +class SdPPTImport +{ + ImplSdPPTImport* pFilter; + + public: + + SdPPTImport( SdDrawDocument* pDoc, SvStream& rDocStream, SvStorage& rStorage, SfxMedium& rMed, MSFilterTracer* pTracer = NULL ); + ~SdPPTImport(); + + sal_Bool Import(); +}; + +#endif // _SD_PPTIN_HXX diff --git a/sd/source/filter/ppt/pptinanimations.cxx b/sd/source/filter/ppt/pptinanimations.cxx new file mode 100644 index 000000000000..16fc1a99dd8a --- /dev/null +++ b/sd/source/filter/ppt/pptinanimations.cxx @@ -0,0 +1,3948 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <com/sun/star/animations/XAnimationNodeSupplier.hpp> +#include <com/sun/star/animations/AnimationFill.hpp> +#include <com/sun/star/animations/AnimationRestart.hpp> +#include <com/sun/star/animations/Timing.hpp> +#include <com/sun/star/animations/Event.hpp> +#include <com/sun/star/animations/AnimationEndSync.hpp> +#include <com/sun/star/animations/EventTrigger.hpp> +#include <com/sun/star/presentation/EffectNodeType.hpp> +#include <com/sun/star/presentation/EffectPresetClass.hpp> +#include <com/sun/star/animations/AnimationNodeType.hpp> +#include <com/sun/star/animations/AnimationTransformType.hpp> +#include <com/sun/star/animations/AnimationCalcMode.hpp> +#include <com/sun/star/animations/AnimationValueType.hpp> +#include <com/sun/star/animations/AnimationAdditiveMode.hpp> +#include <com/sun/star/animations/XIterateContainer.hpp> +#include <com/sun/star/animations/XAnimateSet.hpp> +#include <com/sun/star/animations/XAudio.hpp> +#include <com/sun/star/animations/XCommand.hpp> +#include <com/sun/star/animations/XTransitionFilter.hpp> +#include <com/sun/star/animations/XAnimateColor.hpp> +#include <com/sun/star/animations/XAnimateMotion.hpp> +#include <com/sun/star/animations/XAnimateTransform.hpp> +#include <com/sun/star/animations/ValuePair.hpp> +#include <com/sun/star/animations/AnimationColorSpace.hpp> +#include <com/sun/star/presentation/ShapeAnimationSubType.hpp> +#include <com/sun/star/presentation/EffectCommands.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/presentation/ParagraphTarget.hpp> +#include <com/sun/star/presentation/TextAnimationType.hpp> +#include <comphelper/processfactory.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/math.hxx> + +#include <vcl/vclenum.hxx> +#include <svx/svdotext.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/editobj.hxx> +#include <pptinanimations.hxx> +#include <pptatom.hxx> +#include "pptin.hxx" +#include <algorithm> + +using ::std::map; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::makeAny; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::beans::NamedValue; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::lang::XMultiServiceFactory; + +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::animations; +using namespace ::com::sun::star::presentation; + +namespace sd +{ +extern Reference< XInterface > RandomAnimationNode_createInstance( sal_Int16 nPresetClass ); +} + +namespace ppt +{ + +const transition* transition::find( const OUString& rName ) +{ + const transition* p = gTransitions; + + while( p->mpName ) + { + if( rName.compareToAscii( p->mpName ) == 0 ) + return p; + + p++; + } + + return NULL; +} + +// ==================================================================== + + + +// ==================================================================== + +SvStream& operator>>(SvStream& rIn, AnimationNode& rNode ) +{ + rIn >> rNode.mnU1; + rIn >> rNode.mnRestart; + rIn >> rNode.mnGroupType; + rIn >> rNode.mnFill; + rIn >> rNode.mnU3; + rIn >> rNode.mnU4; + rIn >> rNode.mnDuration; + rIn >> rNode.mnNodeType; + + return rIn; +} + +// ==================================================================== + +static bool convertMeasure( OUString& rString ) +{ + bool bRet = false; + + const sal_Char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", NULL }; + const sal_Char* pDest[] = { "x", "y", "width", "height", NULL }; + sal_Int32 nIndex = 0; + + const sal_Char** ps = pSource; + const sal_Char** pd = pDest; + + while( *ps ) + { + const OUString aSearch( OUString::createFromAscii( *ps ) ); + while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1 ) + { + sal_Int32 nLength = aSearch.getLength(); + if( nIndex && (rString.getStr()[nIndex-1] == '#' ) ) + { + nIndex--; + nLength++; + } + + const OUString aNew( OUString::createFromAscii( *pd ) ); + rString = rString.replaceAt( nIndex, nLength, aNew ); + nIndex += aNew.getLength(); + bRet = true; + } + ps++; + pd++; + } + + return bRet; +} + + +// ==================================================================== + +bool PropertySet::hasProperty( sal_Int32 nProperty ) const +{ + return maProperties.find( nProperty ) != maProperties.end(); +} + +// -------------------------------------------------------------------- + +Any PropertySet::getProperty( sal_Int32 nProperty ) const +{ + PropertySetMap_t::const_iterator aIter( maProperties.find( nProperty ) ); + if( aIter != maProperties.end() ) + return (*aIter).second; + else + return Any(); +} + +// ==================================================================== + +/** this adds an any to another any. + if rNewValue is empty, rOldValue is returned. + if rOldValue is empty, rNewValue is returned. + if rOldValue contains a value, a sequence with rOldValue and rNewValue is returned. + if rOldValue contains a sequence, a new sequence with the old sequence and rNewValue is returned. +*/ +static Any addToSequence( const Any& rOldValue, const Any& rNewValue ) +{ + if( !rNewValue.hasValue() ) + { + return rOldValue; + } + else if( !rOldValue.hasValue() ) + { + return rNewValue; + } + else + { + Sequence< Any > aNewSeq; + if( rOldValue >>= aNewSeq ) + { + sal_Int32 nSize = aNewSeq.getLength(); + aNewSeq.realloc(nSize+1); + aNewSeq[nSize] = rNewValue; + } + else + { + aNewSeq.realloc(2); + aNewSeq[0] = rOldValue; + aNewSeq[1] = rNewValue; + } + return makeAny( aNewSeq ); + } +} + +// ==================================================================== + +AnimationImporter::AnimationImporter( ImplSdPPTImport* pPPTImport, SvStream& rStCtrl ) +: mpPPTImport( pPPTImport ), mrStCtrl( rStCtrl ) +{ +} + +// -------------------------------------------------------------------- + +void AnimationImporter::import( const Reference< XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd ) +{ +#ifdef DBG_ANIM_LOG + mpFile = fopen( "c:\\output.xml", "w+" ); + //mpFile = stdout; +#endif + dump("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + + Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY ); + if( xNodeSupplier.is() ) + { + mxRootNode = xNodeSupplier->getAnimationNode(); + if( mxRootNode.is() ) + { + Reference< XAnimationNode > xParent; + + const Atom* pAtom = Atom::import( rProgTagContentHd, mrStCtrl ); + if( pAtom ) + { + importAnimationContainer( pAtom, xParent ); + } + + processAfterEffectNodes(); + } + } + +#ifdef DBG_ANIM_LOG + fclose( mpFile ); +#endif +} + +// -------------------------------------------------------------------- + +void AnimationImporter::processAfterEffectNodes() +{ + std::for_each( maAfterEffectNodes.begin(), maAfterEffectNodes.end(), sd::stl_process_after_effect_node_func ); +} + +// -------------------------------------------------------------------- + +Reference< XAnimationNode > AnimationImporter::createNode( const Atom* pAtom, const AnimationNode& rNode ) +{ + const char* pServiceName = NULL; + + switch( rNode.mnGroupType ) + { + case mso_Anim_GroupType_PAR: + if( pAtom->hasChildAtom( DFF_msofbtAnimIteration ) ) + pServiceName = "com.sun.star.animations.IterateContainer"; + else + pServiceName = "com.sun.star.animations.ParallelTimeContainer"; + break; + case mso_Anim_GroupType_SEQ: + pServiceName = "com.sun.star.animations.SequenceTimeContainer"; + break; + case mso_Anim_GroupType_NODE: + { + switch( rNode.mnNodeType ) + { + case mso_Anim_Behaviour_FILTER: +/* + pServiceName = "com.sun.star.animations.TransitionFilter"; + break; +*/ + case mso_Anim_Behaviour_ANIMATION: + if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) ) + pServiceName = "com.sun.star.animations.AnimateSet"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) ) + pServiceName = "com.sun.star.animations.AnimateColor"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) ) + pServiceName = "com.sun.star.animations.AnimateTransform"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) ) + pServiceName = "com.sun.star.animations.AnimateTransform"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) ) + pServiceName = "com.sun.star.animations.AnimateMotion"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) ) + pServiceName = "com.sun.star.animations.TransitionFilter"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) + pServiceName = "com.sun.star.animations.Command"; + else + pServiceName = "com.sun.star.animations.Animate"; + break; + } + break; + } + case mso_Anim_GroupType_MEDIA: + pServiceName = "com.sun.star.animations.Audio"; + break; + + default: + pServiceName = "com.sun.star.animations.Animate"; + break; + } + + Reference< XAnimationNode > xNode; + if( pServiceName ) + { + const OUString aServiceName( OUString::createFromAscii(pServiceName) ); + Reference< XInterface > xFac( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName) ); + xNode.set(xFac , UNO_QUERY ); + } + + DBG_ASSERT( xNode.is(), "sd::AnimationImporter::createNode(), node creation failed!" ); + return xNode; +} + +// -------------------------------------------------------------------- + +static bool is_random( const AnimationNode& rNode, const PropertySet& rSet, sal_Int32& rPresetClass ) +{ + if( rNode.mnGroupType != mso_Anim_GroupType_PAR ) + return false; + + if( !rSet.hasProperty( DFF_ANIM_PRESET_ID ) || !rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) ) + return false; + + sal_Int32 nPresetId = 0; + if( !(rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId) || (nPresetId != 24) ) + return false; + + sal_Int32 nPresetClass = 0; + if( !(rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass) ) + return false; + + switch( nPresetClass ) + { + case DFF_ANIM_PRESS_CLASS_ENTRANCE: rPresetClass = EffectPresetClass::ENTRANCE; return true; + case DFF_ANIM_PRESS_CLASS_EXIT: rPresetClass = EffectPresetClass::EXIT; return true; + } + return false; +} + + +void AnimationImporter::importAnimationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xParent ) +{ + if( pAtom->seekToContent() ) + { + AnimationNode aNode; + const Atom* pAnimationNodeAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimNode ); + if( pAnimationNodeAtom && pAnimationNodeAtom->seekToContent() ) + mrStCtrl >> aNode; + + PropertySet aSet; + const Atom* pAnimationPropertySetAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimPropertySet ); + if( pAnimationPropertySetAtom ) + importPropertySetContainer( pAnimationPropertySetAtom, aSet ); + + Reference< XAnimationNode > xNode; + + if( xParent.is() ) + { + sal_Int32 nPresetClass; + if( is_random( aNode, aSet, nPresetClass ) ) + { + // create a random animation node with the given preset class + xNode.set( sd::RandomAnimationNode_createInstance( (sal_Int16)nPresetClass ), UNO_QUERY ); + } + + if( !xNode.is() ) + { + // create a node for the given atom + xNode = createNode( pAtom, aNode ); + } + } + else + { + // if we have no parent we fill the root node + xNode = mxRootNode; + } + + // import if we have a node and its not random + if( xNode.is() ) + { + fillNode( xNode, aNode, aSet ); + + switch( aNode.mnGroupType ) + { + case mso_Anim_GroupType_PAR: + { + dump( "<par" ); + dump( aNode ); + dump( aSet ); + importTimeContainer( pAtom, xNode ); + dump( "</par>\n" ); + + // for iteration containers, map target from childs to iteration + Reference< XIterateContainer > xIter( xNode, UNO_QUERY ); + if( xIter.is() ) + { + double fDuration = 0.0; + Any aTarget, aEmpty; + Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY ); + if( xEnumerationAccess.is() ) + { + Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY ); + if( xEnumeration.is() ) + { + while( xEnumeration->hasMoreElements() ) + { + Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY ); + if( xChildNode.is() ) + { + double fChildBegin = 0.0; + double fChildDuration = 0.0; + xChildNode->getBegin() >>= fChildBegin; + xChildNode->getDuration() >>= fChildDuration; + + fChildDuration += fChildBegin; + if( fChildDuration > fDuration ) + fDuration = fChildDuration; + + if( !aTarget.hasValue() ) + aTarget = xChildNode->getTarget(); + + xChildNode->setTarget( aEmpty ); + } + } + } + } + + xIter->setTarget( aTarget ); + + double fIterateInterval = xIter->getIterateInterval() * fDuration / 100; + xIter->setIterateInterval( fIterateInterval ); + } + } + break; + + case mso_Anim_GroupType_SEQ: + { + dump( "<seq" ); + dump( aNode ); + dump( aSet ); + importTimeContainer( pAtom, xNode ); + dump( "</seq>\n" ); + + if( aSet.hasProperty( DFF_ANIM_NODE_TYPE ) ) + { + sal_Int32 nPPTNodeType = 0; + if( aSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType ) + { + switch(nPPTNodeType) + { + case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: + fixMainSequenceTiming( xNode ); + break; + case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ: + fixInteractiveSequenceTiming( xNode ); + break; + } + } + } + } + break; + + case mso_Anim_GroupType_NODE: + { +#ifdef DBG_ANIM_LOG + if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) ) + { + dump( "<set" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) ) + { + dump( "<animateColor" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) ) + { + dump( "<animateScale" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) ) + { + dump( "<animateRotation" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) ) + { + dump( "<animateMotion" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimate ) ) + { + dump( "<animate" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) ) + { + dump( "<animateFilter" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) + { + dump( "<command" ); + } + else + { + DBG_ERROR( "unknown node atom!" ); + dump_atom_header( pAtom, true, false ); + dump_atom( pAtom ); + dump_atom_header( pAtom, false, false ); + break; + } + dump( aNode ); + dump( aSet ); +#endif + importAnimationNodeContainer( pAtom, xNode ); + if( !convertAnimationNode( xNode, xParent ) ) + xNode = 0; + dump( "/>\n"); + + } + break; + + case mso_Anim_GroupType_MEDIA: + { + dump( "<audio" ); + dump( aNode ); + dump( aSet ); + importAudioContainer( pAtom, xNode ); + dump( "</audio>\n" ); + } + break; + + default: + DBG_ERROR( "unknown group atom!" ); + + dump_atom_header( pAtom, true, false ); + dump_atom( pAtom ); + dump_atom_header( pAtom, false, false ); + break; + + } + } + + if( xParent.is() && xNode.is() ) + { + Reference< XTimeContainer > xParentContainer( xParent, UNO_QUERY ); + DBG_ASSERT( xParentContainer.is(), "parent is no container, then why do I have a child here?" ); + if( xParentContainer.is() ) + { + xParentContainer->appendChild( xNode ); + } + } + } +} + +// -------------------------------------------------------------------- +void AnimationImporter::fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) +{ + try + { + bool bFirst = true; + Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW ); + while( xE->hasMoreElements() ) + { + // click node + Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY ); + + Event aEvent; + aEvent.Trigger = EventTrigger::ON_NEXT; + aEvent.Repeat = 0; + xClickNode->setBegin( makeAny( aEvent ) ); + + if( bFirst ) + { + bFirst = false; + Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW ); + if( xE2->hasMoreElements() ) + { + // with node + xE2->nextElement() >>= xEA2; + if( xEA2.is() ) + xE2.query( xEA2->createEnumeration() ); + else + xE2.clear(); + + if( xE2.is() && xE2->hasMoreElements() ) + { + Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW ); + const Sequence< NamedValue > aUserData( xEffectNode->getUserData() ); + const NamedValue* p = aUserData.getConstArray(); + sal_Int32 nLength = aUserData.getLength(); + while( nLength-- ) + { + if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) ) + { + sal_Int16 nNodeType = 0; + p->Value >>= nNodeType; + if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK ) + { + // first effect does not start on click, so correct + // first click nodes begin to 0s + xClickNode->setBegin( makeAny( (double)0.0 ) ); + break; + } + } + p++; + } + } + } + } + } + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR("sd::AnimationImporter::fixMainSequenceTiming(), exception caught!" ); + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) +{ + try + { + Any aBegin( xNode->getBegin() ); + Any aEmpty; + xNode->setBegin( aEmpty ); + + Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW ); + while( xE->hasMoreElements() ) + { + // click node + Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY ); + xClickNode->setBegin( aBegin ); + } + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR("sd::AnimationImporter::fixInteractiveSequenceTiming(), exception caught!" ); + } +} + +// -------------------------------------------------------------------- + +bool AnimationImporter::convertAnimationNode( const Reference< XAnimationNode >& xNode, const Reference< XAnimationNode >& xParent ) +{ + Reference< XAnimate > xAnimate( xNode, UNO_QUERY ); + if( !xAnimate.is() ) + return true; + + if( !xAnimate->getTarget().hasValue() ) + return false; + + const sal_Int16 nNodeType = xNode->getType(); + + if( nNodeType == AnimationNodeType::TRANSITIONFILTER ) + return true; + + OUString aAttributeName( xAnimate->getAttributeName() ); + + if( (nNodeType == AnimationNodeType::SET) && aAttributeName.equalsAscii( "fill.on" ) ) + return false; + + const ImplAttributeNameConversion* p = gImplConversionList; + + MS_AttributeNames eAttribute = MS_UNKNOWN; + + if( (nNodeType == AnimationNodeType::ANIMATEMOTION) || + (nNodeType == AnimationNodeType::ANIMATETRANSFORM) ) + { + OUString aEmpty; + aAttributeName = aEmpty; + } + else + { + while( p->mpMSName ) + { + if( aAttributeName.compareToAscii( p->mpMSName ) == 0 ) + break; + + p++; + } + + DBG_ASSERT( p->mpMSName || (aAttributeName.getLength() == 0), "sd::AnimationImporter::convertAnimationNode(), unknown attribute!" ); +#ifdef DBG_ANIM_LOG + if( p->mpMSName == 0 ) dump( "<error text=\"sd::AnimationImporter::convertAnimationNode(), unknown attribute!\"/>\n" ); +#endif + + eAttribute = p->meAttribute; + + if( p->mpAPIName ) + aAttributeName = OUString::createFromAscii( p->mpAPIName ); + } + + xAnimate->setAttributeName( aAttributeName ); + + if( eAttribute != MS_UNKNOWN ) + { + Any aAny( xAnimate->getFrom() ); + if( aAny.hasValue() ) + { + if( convertAnimationValue( eAttribute, aAny ) ) + xAnimate->setFrom( aAny ); + } + + aAny = xAnimate->getBy(); + if( aAny.hasValue() ) + { + if( convertAnimationValue( eAttribute, aAny ) ) + xAnimate->setBy( aAny ); + } + + aAny = xAnimate->getTo(); + if( aAny.hasValue() ) + { + if( convertAnimationValue( eAttribute, aAny ) ) + xAnimate->setTo( aAny ); + } + + Sequence< Any > aValues( xAnimate->getValues() ); + sal_Int32 nValues = aValues.getLength(); + if( nValues ) + { + Any* p2 = aValues.getArray(); + while( nValues-- ) + convertAnimationValue( eAttribute, *p2++ ); + + xAnimate->setValues( aValues ); + } + + OUString aFormula( xAnimate->getFormula() ); + if( aFormula.getLength() ) + { + if( convertMeasure( aFormula ) ) + xAnimate->setFormula( aFormula ); + } + } + + // check for after-affect + Sequence< NamedValue > aUserData( xNode->getUserData() ); + NamedValue* pValue = aUserData.getArray(); + NamedValue* pLastValue = pValue; + sal_Int32 nLength = aUserData.getLength(), nRemoved = 0; + + sal_Bool bAfterEffect = false; + sal_Int32 nMasterRel = 0; + for( ; nLength--; pValue++ ) + { + if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("after-effect") ) ) + { + pValue->Value >>= bAfterEffect; + nRemoved++; + } + else if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("master-rel") ) ) + { + pValue->Value >>= nMasterRel; + nRemoved++; + } + else + { + if( nRemoved ) + *pLastValue = *pValue; + pLastValue++; + } + } + + if( nRemoved ) + { + aUserData.realloc( aUserData.getLength() - nRemoved ); + xNode->setUserData( aUserData ); + } + + // if its an after effect node, add it to the list for + // later processing + // after effect nodes are not inserted at their import + // position, so return false in this case + if( bAfterEffect ) + { + if( nMasterRel != 2 ) + { + Event aEvent; + + aEvent.Source <<= xParent; + aEvent.Trigger = EventTrigger::END_EVENT; + aEvent.Repeat = 0; + + xNode->setBegin( makeAny( aEvent ) ); + } + + // add to after effect nodes for later processing + sd::AfterEffectNode aNode( xNode, xParent, nMasterRel == 2 ); + maAfterEffectNodes.push_back( aNode ); + return false; + } + + return true; +} + +static int lcl_gethex( int nChar ) +{ + if( nChar >= '0' && nChar <= '9' ) + return nChar - '0'; + else if( nChar >= 'a' && nChar <= 'f' ) + return nChar - 'a' + 10; + else if( nChar >= 'A' && nChar <= 'F' ) + return nChar - 'A' + 10; + else + return 0; +} + +bool AnimationImporter::convertAnimationValue( MS_AttributeNames eAttribute, Any& rValue ) +{ + bool bRet = false; + switch( eAttribute ) + { + case MS_PPT_X: + case MS_PPT_Y: + case MS_PPT_W: + case MS_PPT_H: + { + OUString aString; + + if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) ) + { + ValuePair aValuePair; + if( rValue >>= aValuePair ) + { + if( aValuePair.First >>= aString ) + { + if( convertMeasure( aString ) ) + { + aValuePair.First <<= aString; + bRet = true; + } + } + + if( aValuePair.Second >>= aString ) + { + if( convertMeasure( aString ) ) + { + aValuePair.Second <<= aString; + bRet = true; + } + } + } + } + else if( rValue.getValueType() == ::getCppuType((const OUString*)0) ) + { + if( rValue >>= aString ) + { + bRet = convertMeasure( aString ); + + if( bRet ) + rValue <<= aString; + } + } + } + break; + + case MS_XSHEAR: + case MS_R: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.toDouble(); + bRet = true; + } + } + break; + + case MS_STYLEROTATION: + { + if( rValue.getValueType() == ::getCppuType((const OUString*)0) ) + { + OUString aString; + rValue >>= aString; + rValue <<= (sal_Int16)aString.toDouble(); + bRet = true; + } + else if( rValue.getValueType() == ::getCppuType((const double*)0) ) + { + double fValue = 0.0; + rValue >>= fValue; + rValue <<= (sal_Int16)fValue; + bRet = true; + } + } + break; + + case MS_FILLCOLOR: + case MS_STROKECOLOR: + case MS_STYLECOLOR: + case MS_PPT_C: + { + OUString aString; + if( rValue >>= aString ) + { + if( aString.getLength() >= 7 && aString[0] == '#' ) + { + Color aColor; + aColor.SetRed( (UINT8)(lcl_gethex( aString[1] ) * 16 + lcl_gethex( aString[2] )) ); + aColor.SetGreen( (UINT8)(lcl_gethex( aString[3] ) * 16 + lcl_gethex( aString[4] )) ); + aColor.SetBlue( (UINT8)(lcl_gethex( aString[5] ) * 16 + lcl_gethex( aString[6] )) ); + rValue <<= (sal_Int32)aColor.GetColor(); + bRet = true; + } + else if( aString.matchAsciiL( "rgb(", 4, 0 ) ) + { + aString = aString.copy( 4, aString.getLength() - 5 ); + Color aColor; + sal_Int32 index = 0; + aColor.SetRed( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); + aColor.SetGreen( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); + aColor.SetRed( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); + rValue <<= (sal_Int32)aColor.GetColor(); + bRet = true; + } + else if( aString.matchAsciiL( "hsl(", 4, 0 ) ) + { + sal_Int32 index = 0; + sal_Int32 nA = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); + sal_Int32 nB = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); + sal_Int32 nC = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); + dump( "hsl(%ld", nA ); + dump( ",%ld", nB ); + dump( ",%ld)", nC ); + Sequence< double > aHSL( 3 ); + aHSL[0] = nA * 360.0/255.0; + aHSL[1] = nB / 255.0; + aHSL[2] = nC / 255.0; + rValue <<= aHSL; + bRet = true; + } + } + } + break; + + case MS_FILLTYPE: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "solid" ) ? FillStyle_SOLID : FillStyle_NONE; + bRet = true; + } + } + break; + + case MS_STROKEON: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "true" ) ? ::com::sun::star::drawing::LineStyle_SOLID : ::com::sun::star::drawing::LineStyle_NONE; + bRet = true; + } + } + break; + + case MS_FONTWEIGHT: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "bold" ) ? com::sun::star::awt::FontWeight::BOLD : com::sun::star::awt::FontWeight::NORMAL; + bRet = true; + } + } + break; + + case MS_STYLEFONTSTYLE: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "italic" ) ? com::sun::star::awt::FontSlant_ITALIC : com::sun::star::awt::FontSlant_NONE; + bRet = true; + } + } + break; + + case MS_STYLEUNDERLINE: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "true" ) ? com::sun::star::awt::FontUnderline::SINGLE : com::sun::star::awt::FontUnderline::NONE; + bRet = true; + } + } + break; + + case MS_STYLEOPACITY: + case MS_STYLEFONTSIZE: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= (float)aString.toDouble(); + bRet = true; + } + } + break; + + case MS_STYLEVISIBILITY: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "visible" ) ? sal_True : sal_False; + bRet = true; + } + } + break; + default: + break; + } + + return bRet; +} + +// -------------------------------------------------------------------- + +static OUString getConvertedSubType( sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType ) +{ + const sal_Char* pStr = 0; + + if( (nPresetClass == EffectPresetClass::ENTRANCE) || (nPresetClass == EffectPresetClass::EXIT) ) + { + // skip wheel effect + if( nPresetId != 21 ) + { + if( nPresetId == 5 ) + { + // checkerboard + switch( nPresetSubType ) + { + case 5: pStr = "downward"; break; + case 10: pStr = "across"; break; + } + } + else if( nPresetId == 17 ) + { + // stretch + if( nPresetSubType == 10 ) + pStr = "across"; + } + else if( nPresetId == 18 ) + { + // strips + switch( nPresetSubType ) + { + case 3: pStr = "right-to-top"; break; + case 6: pStr = "right-to-bottom"; break; + case 9: pStr = "left-to-top"; break; + case 12: pStr = "left-to-bottom"; break; + } + } + + if( pStr == 0 ) + { + const convert_subtype* p = gConvertArray; + + while( p->mpStrSubType ) + { + if( p->mnID == nPresetSubType ) + { + pStr = p->mpStrSubType; + break; + } + p++; + } + } + } + } + + if( pStr ) + return OUString::createFromAscii( pStr ); + else + return OUString::valueOf( nPresetSubType ); +} + +// -------------------------------------------------------------------- + +void AnimationImporter::fillNode( Reference< XAnimationNode >& xNode, const AnimationNode& rNode, const PropertySet& rSet ) +{ + sal_Bool bAfterEffect = false; + + // attribute Restart + if( rNode.mnRestart ) + { + sal_Int16 nRestart = AnimationRestart::DEFAULT; + switch( rNode.mnRestart ) + { + case 1: nRestart = AnimationRestart::ALWAYS; break; + case 2: nRestart = AnimationRestart::WHEN_NOT_ACTIVE; break; + case 3: nRestart = AnimationRestart::NEVER; break; + } + xNode->setRestart( nRestart ); + } + + // attribute Fill + if( rNode.mnFill ) + { + sal_Int16 nFill = AnimationFill::DEFAULT; + switch( rNode.mnFill ) + { + case 1: nFill = AnimationFill::REMOVE; break; + case 2: nFill = AnimationFill::FREEZE; break; + case 3: nFill = AnimationFill::HOLD; break; + case 4: nFill = AnimationFill::TRANSITION; break; + } + xNode->setFill( nFill ); + } + + // attribute Duration + if( rNode.mnDuration ) + { + Any aDuration; + if( rNode.mnDuration > 0 ) + { + aDuration <<= (double)(rNode.mnDuration / 1000.0); + } + else if( rNode.mnDuration < 0 ) + { + aDuration <<= Timing_INDEFINITE; + } + xNode->setDuration( aDuration ); + } + + // TODO: DFF_ANIM_PATH_EDIT_MODE + if( rSet.hasProperty( DFF_ANIM_PATH_EDIT_MODE ) ) + { + sal_Int32 nPathEditMode ; + if( rSet.getProperty( DFF_ANIM_PATH_EDIT_MODE ) >>= nPathEditMode ) + { + } + } + + // set user data + Sequence< NamedValue > aUserData; + + // attribute Type + if( rSet.hasProperty( DFF_ANIM_NODE_TYPE ) ) + { + sal_Int32 nPPTNodeType = 0; + if( rSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType ) + { + sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT; + switch( nPPTNodeType ) + { + case DFF_ANIM_NODE_TYPE_ON_CLICK: nNodeType = ::com::sun::star::presentation::EffectNodeType::ON_CLICK; break; + case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS; break; + case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS; break; + case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: nNodeType = ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE; break; + case DFF_ANIM_NODE_TYPE_TIMING_ROOT: nNodeType = ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT; break; + case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:nNodeType = ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE; break; + } + + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) ); + aUserData[nSize].Value <<= nNodeType; + } + } + + if( rSet.hasProperty( DFF_ANIM_GROUP_ID ) ) + { + sal_Int32 nGroupId; + if( rSet.getProperty( DFF_ANIM_GROUP_ID ) >>= nGroupId ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "group-id" ) ); + aUserData[nSize].Value <<= nGroupId; + } + } + + sal_Int16 nEffectPresetClass = EffectPresetClass::CUSTOM; + sal_Int32 nPresetId = 0; + + if( rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) ) + { + sal_Int32 nPresetClass = 0; + if ( rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass ) + { + switch( nPresetClass ) + { + case DFF_ANIM_PRESS_CLASS_ENTRANCE: nEffectPresetClass = EffectPresetClass::ENTRANCE; break; + case DFF_ANIM_PRESS_CLASS_EXIT: nEffectPresetClass = EffectPresetClass::EXIT; break; + case DFF_ANIM_PRESS_CLASS_EMPHASIS: nEffectPresetClass = EffectPresetClass::EMPHASIS; break; + case DFF_ANIM_PRESS_CLASS_MOTIONPATH: nEffectPresetClass = EffectPresetClass::MOTIONPATH; break; + case DFF_ANIM_PRESS_CLASS_OLE_ACTION: nEffectPresetClass = EffectPresetClass::OLEACTION; break; + case DFF_ANIM_PRESS_CLASS_MEDIACALL: nEffectPresetClass = EffectPresetClass::MEDIACALL; break; + } + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-class" ) ); + aUserData[nSize].Value <<= nEffectPresetClass; + } + } + + if( rSet.hasProperty( DFF_ANIM_PRESET_ID ) ) + { + if( rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-id" ) ); + + const preset_maping* p = gPresetMaping; + while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) ) + p++; + + if( p->mpStrPresetId ) + { + aUserData[nSize].Value <<= OUString::createFromAscii( p->mpStrPresetId ); + } + else + { + OUStringBuffer sBuffer; + sBuffer.appendAscii( "ppt_" ); + switch( nEffectPresetClass ) + { + case EffectPresetClass::ENTRANCE: sBuffer.appendAscii( "entrance_" ); break; + case EffectPresetClass::EXIT: sBuffer.appendAscii( "exit_" ); break; + case EffectPresetClass::EMPHASIS: sBuffer.appendAscii( "emphasis_" ); break; + case EffectPresetClass::MOTIONPATH: sBuffer.appendAscii( "motionpath_" ); break; + case EffectPresetClass::OLEACTION: sBuffer.appendAscii( "oleaction_" ); break; + case EffectPresetClass::MEDIACALL: sBuffer.appendAscii( "mediacall_" ); break; + } + sBuffer.append( nPresetId ); + + aUserData[nSize].Value <<= sBuffer.makeStringAndClear(); + } + } + } + + if( rSet.hasProperty( DFF_ANIM_PRESET_SUB_TYPE ) ) + { + sal_Int32 nPresetSubType = 0; + if( (rSet.getProperty( DFF_ANIM_PRESET_SUB_TYPE ) >>= nPresetSubType) ) + { + if( nPresetSubType ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-sub-type" ) ); + aUserData[nSize].Value <<= getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType ); + } + } + } + + if( rSet.hasProperty( DFF_ANIM_AFTEREFFECT ) ) + { + if( rSet.getProperty( DFF_ANIM_AFTEREFFECT ) >>= bAfterEffect ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "after-effect" ) ); + aUserData[nSize].Value <<= bAfterEffect; + } + } + + if( bAfterEffect && rSet.hasProperty( DFF_ANIM_MASTERREL ) ) + { + sal_Int32 nMasterRel = 2; + if( rSet.getProperty( DFF_ANIM_MASTERREL ) >>= nMasterRel ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "master-rel" ) ); + aUserData[nSize].Value <<= nMasterRel; + } + } + + xNode->setUserData( aUserData ); + + // TODO: DFF_ANIM_ID + if( rSet.hasProperty( DFF_ANIM_ID ) ) + { + rtl::OUString aString; + rSet.getProperty( DFF_ANIM_ID ) >>= aString; + if( aString.getLength() ) + { + } + } + + // TODO: DFF_ANIM_EVENT_FILTER + if( rSet.hasProperty( DFF_ANIM_EVENT_FILTER ) ) + { + rtl::OUString aString; + rSet.getProperty( DFF_ANIM_EVENT_FILTER ) >>= aString; + if( aString.getLength() ) + { + } + } + + // DFF_ANIM_TIMEFILTER + if( rSet.hasProperty( DFF_ANIM_TIMEFILTER ) ) + { + Reference< XAnimate > xAnim( xNode, UNO_QUERY ); + if( xAnim.is() ) + { + rtl::OUString aString; + rSet.getProperty( DFF_ANIM_TIMEFILTER ) >>= aString; + if( aString.getLength() ) + { + sal_Int32 nElements = 1; // a non empty string has at least one value + + sal_Int32 fromIndex = 0; + while(true) + { + fromIndex = aString.indexOf( (sal_Unicode)';', fromIndex ); + if( fromIndex == -1 ) + break; + + fromIndex++; + nElements++; + } + + Sequence< TimeFilterPair > aTimeFilter( nElements ); + + TimeFilterPair* pValues = aTimeFilter.getArray(); + sal_Int32 nIndex = 0; + while( (nElements--) && (nIndex >= 0) ) + { + const OUString aToken( aString.getToken( 0, ';', nIndex ) ); + + sal_Int32 nPos = aToken.indexOf( ',' ); + if( nPos >= 0 ) + { + pValues->Time = aToken.copy( 0, nPos ).toDouble(); + pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble(); + } + pValues++; + } + + xAnim->setTimeFilter( aTimeFilter ); + } + } + } + +/* todo + Reference< XAudio > xAudio( xNode, UNO_QUERY ); + if( xAudio.is() ) + { + if( rSet.hasProperty( DFF_ANIM_ENDAFTERSLIDE ) ) + { + sal_Int16 nEndAfterSlide = 0; + if( rSet.getProperty( DFF_ANIM_ENDAFTERSLIDE ) >>= nEndAfterSlide ) + xAudio->setEndAfterSlide( nEndAfterSlide ); + } + + if( rSet.hasProperty( DFF_ANIM_VOLUME ) ) + { + double fVolume = 1.0; + rSet.getProperty( DFF_ANIM_VOLUME ) >>= fVolume; + xAudio->setVolume( fVolume ); + } + } +*/ + Reference< XAnimateColor > xColor( xNode, UNO_QUERY ); + if( xColor.is() ) + { + if( rSet.hasProperty( DFF_ANIM_DIRECTION ) ) + { + sal_Bool bDirection = sal_False; + if( rSet.getProperty( DFF_ANIM_DIRECTION ) >>= bDirection ) + xColor->setDirection( (sal_Bool)!bDirection ); + } + + if( rSet.hasProperty( DFF_ANIM_COLORSPACE ) ) + { + sal_Int32 nColorSpace = 0; + rSet.getProperty( DFF_ANIM_COLORSPACE ) >>= nColorSpace; + xColor->setColorInterpolation( (nColorSpace == 0) ? AnimationColorSpace::RGB : AnimationColorSpace::HSL ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importTimeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!"); + if( pAtom && xNode.is() ) + { + importAnimationEvents( pAtom, xNode ); + importAnimationValues( pAtom, xNode ); + importAnimationActions( pAtom, xNode ); + + dump(">\n"); + + // import sub containers + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimNode: + case DFF_msofbtAnimEvent: + case DFF_msofbtAnimValue: + case DFF_msofbtAnimAction: + case DFF_msofbtAnimPropertySet: + break; + + case DFF_msofbtAnimSubGoup : + { + if( pChildAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) + { + const OUString aServiceName( OUString::createFromAscii("com.sun.star.animations.Command") ); + Reference< XAnimationNode > xChildNode( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY ); + importAnimationNodeContainer( pChildAtom, xChildNode ); + Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY ); + if( xParentContainer.is() && xChildNode.is() ) + xParentContainer->appendChild( xChildNode ); + } + else + { + importAnimationContainer( pChildAtom, xNode ); + } + } + break; + case DFF_msofbtAnimGroup : + { + importAnimationContainer( pChildAtom, xNode ); + } + break; + case DFF_msofbtAnimIteration: + { + if( pChildAtom->seekToContent() ) + { + float fInterval; + sal_Int32 nTextUnitEffect, nU1, nU2, nU3; + + mrStCtrl >> fInterval >> nTextUnitEffect >> nU1 >> nU2 >> nU3; + + Reference< XIterateContainer > xIter( xNode, UNO_QUERY ); + if( xIter.is() ) + { + sal_Int16 nIterateType = TextAnimationType::BY_PARAGRAPH; + switch( nTextUnitEffect ) + { + case 1: nIterateType = TextAnimationType::BY_WORD; break; + case 2: nIterateType = TextAnimationType::BY_LETTER; break; + } + xIter->setIterateType( nIterateType ); + xIter->setIterateInterval( (double)fInterval ); + } + + dump( "<iterate" ); + dump( " iterateType=\"%s\"", (nTextUnitEffect == 0) ? "byElement" : (nTextUnitEffect == 1) ? "byWord" : "byLetter" ); + dump( " iterateInterval=\"%g\"", fInterval ); + dump( " u1=\"%ld\"", nU1 ); + dump( " u2=\"%ld\"", nU2 ); + dump( " u3=\"%ld\"/>\n", nU3 ); + } + } + break; + + case 0xf136: + { +#ifdef DBG_ANIM_LOG + sal_uInt32 nU1, nU2; + mrStCtrl >> nU1 >> nU2; + + fprintf( mpFile, "<unknown_0xf136 nU1=\"%ld\" nU2=\"%ld\"/>\n", nU1, nU2 ); +#endif + } + break; + + default: + { + dump_atom_header( pChildAtom, true, false ); + dump_atom( pChildAtom ); + dump_atom_header( pChildAtom, false, false ); + } + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +/* todo: for now we dump sub containers into its parent container, what else to do with it? */ +void AnimationImporter::importAnimationSubContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!"); + if( pAtom && xNode.is() ) + { + // import sub containers + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimNode: + case DFF_msofbtAnimEvent: + case DFF_msofbtAnimValue: + case DFF_msofbtAnimAction: + case DFF_msofbtAnimPropertySet: + break; + case DFF_msofbtAnimCommand: + { + const OUString aServiceName( OUString::createFromAscii("com.sun.star.animations.Command") ); + Reference< XAnimationNode > xChildNode( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY ); + importAnimationNodeContainer( pChildAtom, xChildNode ); + Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY ); + if( xParentContainer.is() && xChildNode.is() ) + xParentContainer->appendChild( xChildNode ); + } + break; + + default: + { + dump_atom_header( pChildAtom, true, false ); + dump_atom( pChildAtom ); + dump_atom_header( pChildAtom, false, false ); + } + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimationNodeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationNodeContainer()!"); + if( pAtom && xNode.is() ) + { + importAnimationEvents( pAtom, xNode ); + importAnimationValues( pAtom, xNode ); + importAnimationActions( pAtom, xNode ); + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimNode: + case DFF_msofbtAnimEvent: + case DFF_msofbtAnimValue: + case DFF_msofbtAnimAction: + case DFF_msofbtAnimPropertySet: + break; + + case DFF_msofbtAnimateFilter: + importAnimateFilterContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateSet: + importAnimateSetContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimate: + importAnimateContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateScale: + importAnimateScaleContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateColor: + importAnimateColorContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateRotation: + importAnimateRotationContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateMotion: + importAnimateMotionContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimCommand: + importCommandContainer( pChildAtom, xNode ); + break; + + default: + { + dump_atom_header( pChildAtom, true, false ); + dump_atom( pChildAtom ); + dump_atom_header( pChildAtom, false, false ); + } + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateFilterContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateFilter && xFilter.is(), "invalid call to ppt::AnimationImporter::importAnimateFilterContainer()!"); + if( pAtom && xFilter.is() ) + { + sal_uInt32 nBits = 0; + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateFilterData: + { + sal_uInt32 transition; + mrStCtrl >> nBits; + mrStCtrl >> transition; + + if( nBits & 1 ) + xFilter->setMode( transition == 0 ); + + dump( " transition=\"%s\"", (transition == 0) ? "in" : "out" ); + } + break; + + case DFF_msofbtAnimAttributeValue: + { + if( (nBits & 2 ) && ( pChildAtom->getInstance() == 1 ) ) + { + Any aAny; + if ( importAttributeValue( pChildAtom, aAny ) ) + { + rtl::OUString filter; + aAny >>= filter; + + dump( " filter=\"%s\"", filter ); + + const transition* pTransition = transition::find( filter ); + if( pTransition ) + { + xFilter->setTransition( pTransition->mnType ); + xFilter->setSubtype( pTransition->mnSubType ); + xFilter->setDirection( pTransition->mbDirection ); + } + else + { + DBG_ERROR( "unknown transition!" ); + } + } + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateAttributeTargetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateTarget, "invalid call to ppt::AnimationImporter::importAnimateAttributeTargetContainer()!"); + + Any aTarget; + + Reference< XAnimate > xAnimate( xNode, UNO_QUERY ); + + bool bWrongContext = false; + + if( pAtom ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimPropertySet: + { + PropertySet aSet; + importPropertySetContainer( pChildAtom, aSet ); + if( aSet.hasProperty( DFF_ANIM_RUNTIMECONTEXT ) ) + { + OUString aContext; + if( aSet.getProperty( DFF_ANIM_RUNTIMECONTEXT ) >>= aContext ) + { + if( !aContext.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("PPT") ) ) + bWrongContext = true; + } + } + + dump( aSet ); + } + break; + + case DFF_msofbtAnimateTargetSettings: + { + if( xAnimate.is() ) + { + sal_uInt32 nBits; + sal_uInt32 nAdditive; + sal_uInt32 nAccumulate; + sal_uInt32 nTransformType; + + mrStCtrl >> nBits >> nAdditive >> nAccumulate >> nTransformType; + + // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype + // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none + // nAccumulate 0 = none, 1 = always + // nTransformType 0: "property" else "image" + + if( nBits & 3 ) + { + if( xAnimate.is() ) + { + if( nBits & 1 ) + { + sal_Int16 nTemp = AnimationAdditiveMode::BASE; + switch( nAdditive ) + { + case 1: nTemp = AnimationAdditiveMode::SUM; break; + case 2: nTemp = AnimationAdditiveMode::REPLACE; break; + case 3: nTemp = AnimationAdditiveMode::MULTIPLY; break; + case 4: nTemp = AnimationAdditiveMode::NONE; break; + } + xAnimate->setAdditive( nTemp ); + } + + if( nBits & 2 ) + { + xAnimate->setAccumulate( (nAccumulate == 0) ? sal_True : sal_False ); + } + } + } +#ifdef DBG_ANIM_LOG + if( nBits & 1 ) + fprintf( mpFile, " additive=\"%s\"", (nAdditive == 0) ? "base" : (nAdditive == 2) ? "replace" : (nAdditive == 1) ? "sum" : (nAdditive == 3 ) ? "multiply" : (nAdditive == 4) ? "none" : "unknown" ); + + if( nBits & 2 ) + fprintf( mpFile, " accumulate=\"%s\"", (nAccumulate == 0) ? "none" : "always" ); + + if( nBits & 8 ) + fprintf( mpFile, " transformType=\"%s\"", (nTransformType == 0) ? "property" : "image" ); +#endif + } + } + break; + + case DFF_msofbtAnimateAttributeNames: + { + if( xAnimate.is() ) + { + OUString aAttributeName; + importAttributeNamesContainer( pChildAtom, aAttributeName ); + if( xAnimate.is() ) + xAnimate->setAttributeName( aAttributeName ); + dump( " attributeName=\"%s\"", aAttributeName ); + } + } + break; + + case DFF_msofbtAnimateTargetElement: + { + sal_Int16 nSubType; + importTargetElementContainer( pChildAtom, aTarget, nSubType ); + if( xAnimate.is() ) + xAnimate->setSubItem( nSubType ); + + dump( " target=\"" ); + dump_target( aTarget ); + dump( "\"" ); + } + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } + + if( bWrongContext ) + aTarget.clear(); + + if( xAnimate.is() ) + xAnimate->setTarget( aTarget ); + else + { + Reference< XCommand > xCommand( xNode, UNO_QUERY ); + if( xCommand.is() ) + xCommand->setTarget( aTarget ); + } +} + +// -------------------------------------------------------------------- + +sal_Int16 AnimationImporter::implGetColorSpace( sal_Int32 nMode, sal_Int32 /*nA*/, sal_Int32 /*nB*/, sal_Int32 /*nC*/ ) +{ + switch( nMode ) + { + case 2: // index + // FALLTHROUGH intended + default: + // FALLTHROUGH intended + case 0: // rgb + return AnimationColorSpace::RGB; + + case 1: // hsl + return AnimationColorSpace::HSL; + } +} + +// -------------------------------------------------------------------- + +Any AnimationImporter::implGetColorAny( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC ) +{ + switch( nMode ) + { + case 0: // rgb + { + dump( "rgb(%ld", nA ); + dump( ",%ld", nB ); + dump( ",%ld)", nC ); + Color aColor( (UINT8)nA, (UINT8)nB, (UINT8)nC ); + return makeAny( (sal_Int32)aColor.GetRGBColor() ); + } + case 1: // hsl + { + dump( "hsl(%ld", nA ); + dump( ",%ld", nB ); + dump( ",%ld)", nC ); + Sequence< double > aHSL( 3 ); + aHSL[0] = nA * 360.0/255.0; + aHSL[1] = nB / 255.0; + aHSL[2] = nC / 255.0; + return makeAny( aHSL ); + } + + case 2: // index + { + Color aColor; + mpPPTImport->GetColorFromPalette((USHORT)nA, aColor ); + dump( "index(%ld", nA ); + dump( " [%ld", (sal_Int32)aColor.GetRed() ); + dump( ",%ld", (sal_Int32)aColor.GetGreen() ); + dump( ",%ld])", (sal_Int32)aColor.GetBlue() ); + return makeAny( (sal_Int32)aColor.GetRGBColor() ); + } + + default: + { + dump( "unknown_%ld(", nMode ); + dump( "%ld", nA ); + dump( ",%ld", nB ); + dump( ",%ld)", nC ); + DBG_ERROR( "ppt::implGetColorAny(), unhandled color type" ); + + Any aAny; + return aAny; + } + } +} + +void AnimationImporter::importAnimateColorContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateColor > xColor( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateColor && xColor.is(), "invalid call to ppt::AnimationImporter::importAnimateColorContainer()!"); + if( pAtom && xColor.is() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateColorData: + { + sal_uInt32 nBits; + sal_Int32 nByMode, nByA, nByB, nByC; + sal_Int32 nFromMode, nFromA, nFromB, nFromC; + sal_Int32 nToMode, nToA, nToB, nToC; + mrStCtrl >> nBits; + mrStCtrl >> nByMode >> nByA >> nByB >> nByC; + mrStCtrl >> nFromMode >> nFromA >> nFromB >> nFromC; + mrStCtrl >> nToMode >> nToA >> nToB >> nToC; + + if( nBits & 1 ) + { + dump( " by=\"" ); + xColor->setBy( implGetColorAny( nByMode, nByA, nByB, nByC ) ); + xColor->setColorInterpolation( implGetColorSpace( nByMode, nByA, nByB, nByC ) ); + dump( "\""); + } + + if( nBits & 2 ) + { + dump( " from=\"" ); + xColor->setFrom( implGetColorAny( nFromMode, nFromA, nFromB, nFromC ) ); + xColor->setColorInterpolation( implGetColorSpace( nFromMode, nFromA, nFromB, nFromC ) ); + dump( "\""); + } + + if( nBits & 4 ) + { + dump( " to=\"" ); + xColor->setTo( implGetColorAny( nToMode, nToA, nToB, nToC ) ); + xColor->setColorInterpolation( implGetColorSpace( nToMode, nToA, nToB, nToC ) ); + dump( "\""); + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateSetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateSet > xSet( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateSet && xSet.is(), "invalid call to ppt::AnimationImporter::importAnimateSetContainer()!"); + if( pAtom && xSet.is() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateSetData: + { + sal_Int32 nU1, nU2; + mrStCtrl >> nU1 >> nU2; + + dump( " set_1=\"%ld\"", nU1 ), + dump( " set_2=\"%ld\"", nU2 ); + } + break; + + case DFF_msofbtAnimAttributeValue: + { + Any aTo; + if ( importAttributeValue( pChildAtom, aTo ) ) + { + xSet->setTo( aTo ); + + dump( " value=\"" ); + dump( aTo ); + dump( "\"" ); + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimate > xAnim( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimate && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateContainer()!"); + if( pAtom && xAnim.is() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateData: + { + sal_uInt32 nCalcmode, nBits, nValueType; + mrStCtrl >> nCalcmode >> nBits >> nValueType; + + if( nBits & 0x08 ) + { + sal_Int16 n = (nCalcmode == 1) ? AnimationCalcMode::LINEAR : /* (nCalcmode == 2) ? AnimationCalcMode::FORMULA : */ AnimationCalcMode::DISCRETE; + xAnim->setCalcMode( n ); + dump( " calcmode=\"%s\"", (nCalcmode == 0) ? "discrete" : (nCalcmode == 1) ? "linear" : (nCalcmode == 2) ? "formula" : "unknown" ); + } + + if( nBits & 0x30 ) + { + sal_Int16 n = (nValueType == 1) ? AnimationValueType::NUMBER : (nValueType == 2 ) ? AnimationValueType::COLOR : AnimationValueType::STRING; + xAnim->setValueType( n ); + dump( " valueType=\"%s\"", (nValueType == 0) ? "string" : (nValueType == 1) ? "number" : (nValueType == 2) ? "color" : "unknown" ); + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimKeyPoints: + importAnimateKeyPoints( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimAttributeValue: + { + Any a; + if ( importAttributeValue( pChildAtom, a ) ) + { + switch( pChildAtom->getInstance() ) + { + case 1: xAnim->setBy( a ); dump( " by=\"" ); break; + case 2: xAnim->setFrom( a ); dump( " from=\"" ); break; + case 3: xAnim->setTo( a ); dump( " to=\"" ); break; + default: + dump( " unknown_value=\"" ); + } + + dump( a ); + dump( "\"" ); + } + } + break; + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateMotionContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateMotion && xMotion.is(), "invalid call to ppt::AnimationImporter::importAnimateMotionContainer()!"); + if( pAtom && xMotion.is() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateMotionData: + { + sal_uInt32 nBits, nOrigin; + float fByX, fByY, fFromX, fFromY, fToX, fToY; + + mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nOrigin; + +#ifdef DBG_ANIM_LOG + if( nBits & 1 ) + fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY ); + + if( nBits & 2 ) + fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY ); + + if( nBits & 4 ) + fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY ); + + if( nBits & 8 ) + fprintf( mpFile, " origin=\"%s\"", (nOrigin == 1) ? "parent" : (nOrigin == 2) ? "layout" : "unknown" ); + +#endif + } + break; + + case DFF_msofbtAnimAttributeValue: + { + Any aPath; + if ( importAttributeValue( pChildAtom, aPath ) ) + { + rtl::OUString aStr; + if ( aPath >>= aStr ) + { + aStr = aStr.replace( 'E', ' ' ); + aStr = aStr.trim(); + aPath <<= aStr; + xMotion->setPath( aPath ); + dump( " path=\"" ); + dump( aPath ); + dump( "\"" ); + } + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importCommandContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XCommand > xCommand( xNode, UNO_QUERY ); + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimCommand && xCommand.is(), "invalid call to ppt::AnimationImporter::importCommandContainer()!"); + if( pAtom && xCommand.is() ) + { + sal_Int32 nBits = 0, nType = 0; + Any aValue; + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtCommandData: + { + sal_Int32 nCommandType; + // looks like U1 is a bitset, bit 1 enables the type and bit 2 enables + // a propertyvalue that follows + mrStCtrl >> nBits; + mrStCtrl >> nCommandType; + + if( nBits && 1 ) + { + dump( " type=\"%s\"", (nCommandType == 0) ? "event" : ( nCommandType == 1) ? "call" : "verb" ); + } + } + break; + + case DFF_msofbtAnimAttributeValue: + { + if ( importAttributeValue( pChildAtom, aValue ) ) + { + if( nBits && 2 ) + { + dump( " cmd=\"" ); + dump( aValue ); + dump( "\"" ); + } + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + + if( nBits & 3 ) + { + OUString aParam; + aValue >>= aParam; + + sal_Int16 nCommand = EffectCommands::CUSTOM; + + NamedValue aParamValue; + + switch( nType ) + { + case 0: // event + case 1: // call + if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "onstopaudio" ) ) ) + { + nCommand = EffectCommands::STOPAUDIO; + } + else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("play") ) ) + { + nCommand = EffectCommands::PLAY; + } + else if( aParam.compareToAscii( RTL_CONSTASCII_STRINGPARAM("playFrom") ) == 0 ) + { + const OUString aMediaTime( aParam.copy( 9, aParam.getLength() - 10 ) ); + rtl_math_ConversionStatus eStatus; + double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL ); + if( eStatus == rtl_math_ConversionStatus_Ok ) + { + aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("MediaTime")); + aParamValue.Value <<= fMediaTime; + } + nCommand = EffectCommands::PLAY; + } + else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("togglePause") ) ) + { + nCommand = EffectCommands::TOGGLEPAUSE; + } + else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("stop") ) ) + { + nCommand = EffectCommands::STOP; + } + break; + case 2: // verb + { + aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Verb")); + aParamValue.Value <<= aParam.toInt32(); + + nCommand = EffectCommands::VERB; + } + break; + } + + xCommand->setCommand( nCommand ); + if( nCommand == EffectCommands::CUSTOM ) + { + DBG_ERROR("sd::AnimationImporter::importCommandContainer(), unknown command!"); + aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefined")); + aParamValue.Value <<= aParam; + } + + if( aParamValue.Value.hasValue() ) + { + Sequence< NamedValue > aParamSeq( &aParamValue, 1 ); + xCommand->setParameter( makeAny( aParamSeq ) ); + } + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAudioContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAudio > xAudio( xNode, UNO_QUERY ); + DBG_ASSERT( pAtom && xAudio.is() && + ( (pAtom->getType() == DFF_msofbtAnimGroup) || + (pAtom->getType() == DFF_msofbtAnimSubGoup) ), "invalid call to ppt::AnimationImporter::importAudioContainer()!"); + if( pAtom && xAudio.is() ) + { + importAnimationEvents( pAtom, xNode ); + importAnimationValues( pAtom, xNode ); + importAnimationActions( pAtom, xNode ); + + dump(">\n"); + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimNode: + case DFF_msofbtAnimEvent: + case DFF_msofbtAnimValue: + case DFF_msofbtAnimAction: + case DFF_msofbtAnimPropertySet: + break; + + case DFF_msofbtAnimAttributeValue: + { + Any aValue; + if ( importAttributeValue( pChildAtom, aValue ) ) + { + dump( " value=\"" ); + dump( aValue ); + dump( "\"" ); + } + } + break; + + case DFF_msofbtAnimateTargetElement: + { + sal_Int16 nSubType; + Any aSource; + importTargetElementContainer( pChildAtom, aSource, nSubType ); + if( xAudio.is() ) + xAudio->setSource( aSource ); + } + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + + // TODO: What to do with them? + Any aEmpty; + xAudio->setBegin( aEmpty ); + xAudio->setEnd( aEmpty ); + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateScaleContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateScale && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateScaleContainer()!"); + if( pAtom && xTransform.is() ) + { + xTransform->setTransformType( AnimationTransformType::SCALE ); + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateScaleData: + { + sal_uInt32 nBits, nZoomContents; + float fByX, fByY, fFromX, fFromY, fToX, fToY; + + // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool) + mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nZoomContents; + + ValuePair aPair; + // 'from' value + if( nBits & 2 ) + { + aPair.First <<= (double)fFromX / 100.0; + aPair.Second <<= (double)fFromY / 100.0; + xTransform->setFrom( makeAny( aPair ) ); + } + + // 'to' value + if( nBits & 4 ) + { + aPair.First <<= (double)fToX / 100.0; + aPair.Second <<= (double)fToY / 100.0; + xTransform->setTo( makeAny( aPair ) ); + } + + // 'by' value + if( nBits & 1 ) + { + aPair.First <<= (double)fByX / 100.0; + aPair.Second <<= (double)fByY / 100.0; + + if( nBits & 2 ) + { + // 'from' value given, import normally + xTransform->setBy( makeAny( aPair ) ); + } + else + { + // mapping 'by' to 'to', if no 'from' is + // given. This is due to a non-conformity in + // PPT, which exports animateScale effects + // with a sole 'by' value, but with the + // semantics of a sole 'to' animation + xTransform->setTo( makeAny( aPair ) ); + } + } + + +#ifdef DBG_ANIM_LOG + if( nBits & 1 ) + fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY ); + + if( nBits & 2 ) + fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY ); + + if( nBits & 4 ) + fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY ); + + if( nBits & 8 ) + fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" ); +#endif + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateRotationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateRotation && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateRotationContainer()!"); + if( pAtom && xTransform.is() ) + { + xTransform->setTransformType( AnimationTransformType::ROTATE ); + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateRotationData: + { + sal_uInt32 nBits, nU1; + float fBy, fFrom, fTo; + + // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool) + mrStCtrl >> nBits >> fBy >> fFrom >> fTo >> nU1; + + if( nBits & 1 ) + xTransform->setBy( makeAny( (double) fBy ) ); + + if( nBits & 2 ) + xTransform->setFrom( makeAny( (double) fFrom ) ); + + if( nBits & 4 ) + xTransform->setTo( makeAny( (double) fTo ) ); + +#ifdef DBG_ANIM_LOG + if( nBits & 1 ) + fprintf( mpFile, " by=\"%g\"", (double)fBy ); + + if( nBits & 2 ) + fprintf( mpFile, " from=\"%g\"", (double)fFrom ); + + if( nBits & 4 ) + fprintf( mpFile, " to=\"%g\"", (double)fTo ); + + if( nU1 ) + fprintf( mpFile, " rotation_1=\"%ld\"", nU1 ); +#endif + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} +// -------------------------------------------------------------------- + +bool AnimationImporter::importAttributeNamesContainer( const Atom* pAtom, OUString& rAttributeNames ) +{ + OUStringBuffer aNames; + + DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateAttributeNames), "invalid call to ppt::AnimationImporter::importAttributeName()!" ); + if( pAtom ) + { + const Atom* pAttributeValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAttributeValue ); + + while( pAttributeValueAtom ) + { + Any aAny; + if ( importAttributeValue( pAttributeValueAtom, aAny ) ) + { + OUString aName; + if( aAny >>= aName ) + { + if( aNames.getLength() ) + aNames.append( (sal_Unicode)';' ); + + aNames.append( aName ); + } + } + else + { + DBG_ERROR( "error during ppt::AnimationImporter::importAttributeName()!" ); + } + + pAttributeValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimAttributeValue, pAttributeValueAtom ); + } + } + + rAttributeNames = aNames.makeStringAndClear(); + return true; +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimationValues( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom, "invalid call to ppt::AnimationImporter::importAnimationValues()!" ); + + if( pAtom ) + { + const Atom* pValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimValue ); + + while( pValueAtom && pValueAtom->seekToContent() ) + { + sal_uInt32 nType; + mrStCtrl >> nType; + switch( nType ) + { + case 0: + { + float fRepeat; + mrStCtrl >> fRepeat; + xNode->setRepeatCount( (fRepeat < ((float)3.40282346638528860e+38)) ? makeAny( (double)fRepeat ) : makeAny( Timing_INDEFINITE ) ); + +#ifdef DBG_ANIM_LOG + if( (fRepeat < ((float)3.40282346638528860e+38)) ) + { + dump( " repeat=\"%g\"", (double)fRepeat ); + } + else + { + dump( " repeat=\"indefinite\"" ); + } +#endif + } + break; + + case 3: + { + float faccelerate; + mrStCtrl >> faccelerate; + xNode->setAcceleration( faccelerate ); + dump( " accelerate=\"%g\"", (double)faccelerate ); + } + break; + + case 4: + { + float fdecelerate; + mrStCtrl >> fdecelerate; + xNode->setDecelerate( fdecelerate ); + dump( " decelerate=\"%g\"", (double)fdecelerate ); + } + break; + + case 5: + { + sal_Int32 nAutoreverse; + mrStCtrl >> nAutoreverse; + xNode->setAutoReverse( nAutoreverse != 0 ); + dump( " autoreverse=\"%#lx\"", nAutoreverse ); + } + break; + + default: + { + sal_uInt32 nUnknown; + mrStCtrl >> nUnknown; +#ifdef DBG_ANIM_LOG + fprintf(mpFile, " attribute_%d=\"%#lx\"", nType, nUnknown ); +#endif + } + break; + } + + pValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimValue, pValueAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateKeyPoints( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimate > xAnim( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimKeyPoints && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateKeyPoints()!" ); + + if( pAtom && xAnim.is() ) + { + // first count keytimes + const Atom* pIter = NULL; + int nKeyTimes = 0; + + while( (pIter = pAtom->findNextChildAtom( DFF_msofbtAnimKeyTime, pIter )) != 0 ) + nKeyTimes++; + + Sequence< double > aKeyTimes( nKeyTimes ); + Sequence< Any > aValues( nKeyTimes ); + OUString aFormula; + + pIter = pAtom->findFirstChildAtom(DFF_msofbtAnimKeyTime); + int nKeyTime; + sal_Int32 nTemp; + for( nKeyTime = 0; (nKeyTime < nKeyTimes) && pIter; nKeyTime++ ) + { + if( pIter->seekToContent() ) + { + mrStCtrl >> nTemp; + double fTemp = (double)nTemp / 1000.0; + aKeyTimes[nKeyTime] = fTemp; + + const Atom* pValue = pAtom->findNextChildAtom(pIter); + if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue ) + { + Any aValue1, aValue2; + if( importAttributeValue( pValue, aValue1 ) ) + { + pValue = pAtom->findNextChildAtom(pValue); + if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue ) + importAttributeValue( pValue, aValue2 ); + + bool bCouldBeFormula = false; + bool bHasValue = aValue2.hasValue(); + if( bHasValue ) + { + if( aValue2.getValueType() == ::getCppuType((const OUString*)0) ) + { + OUString aTest; + aValue2 >>= aTest; + bHasValue = aTest.getLength() != 0; + bCouldBeFormula = true; + } + } + + if( bHasValue && bCouldBeFormula && (aValue1.getValueType() == ::getCppuType((const double*)0)) ) + { + aValue2 >>= aFormula; + bHasValue = false; + } + + if( bHasValue ) + { + aValues[nKeyTime] = makeAny( ValuePair( aValue1, aValue2 ) ); + } + else + { + aValues[nKeyTime] = aValue1; + } + } + } + } + pIter = pAtom->findNextChildAtom(DFF_msofbtAnimKeyTime, pIter); + } + +#ifdef DBG_ANIM_LOG + dump( " keyTimes=\"" ); + for( int i=0; i<nKeyTimes; ++i ) + dump( "%f;", aKeyTimes[i] ); + + if( aFormula.getLength() ) + { + dump( "formula=\"%s", aFormula ); + } + + dump( "\" values=\"" ); + double nVal; + OUString aStr; + for( int i=0; i<nKeyTimes; ++i ) + { + if( i != 0 ) + dump( ";" ); + + if( aValues[i] >>= aStr ) + dump( "%s", + ::rtl::OUStringToOString( aStr, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + else if( aValues[i] >>= nVal ) + dump( "%f", nVal ); + else + { + ValuePair aValuePair; + + if( aValues[i] >>= aValuePair ) + { + if( aValuePair.First >>= aStr ) + dump( "%s", + ::rtl::OUStringToOString( aStr, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + else if( aValuePair.First >>= nVal ) + dump( "%f", nVal ); + else + dump( "%X", (sal_Int32)&aValuePair.First ); + + if( aValuePair.Second >>= aStr ) + dump( ",%s", + ::rtl::OUStringToOString( aStr, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + else if( aValuePair.Second >>= nVal ) + dump( ",%f", nVal ); + else + dump( ",%X", (sal_Int32)&aValuePair.Second ); + } + } + } + dump( "\"" ); +#endif + + xAnim->setKeyTimes( aKeyTimes ); + xAnim->setValues( aValues ); + xAnim->setFormula( aFormula ); + } +} + +// -------------------------------------------------------------------- + +bool AnimationImporter::importAttributeValue( const Atom* pAtom, Any& rAny ) +{ + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimAttributeValue, "invalid call to ppt::AnimationImporter::importAttributeValue()!" ); + + bool bOk = false; + + if( pAtom && pAtom->seekToContent() ) + { + sal_uInt32 nRecLen = pAtom->getLength(); + if ( nRecLen >= 1 ) + { + sal_Int8 nType; + mrStCtrl >> nType; + switch( nType ) + { + case DFF_ANIM_PROP_TYPE_BYTE : + { + if ( nRecLen == 2 ) + { + sal_uInt8 nByte; + mrStCtrl >> nByte; + rAny <<= nByte; + + bOk = true; + } + } + break; + + case DFF_ANIM_PROP_TYPE_INT32 : + { + if ( nRecLen == 5 ) + { + sal_uInt32 nInt32; + mrStCtrl >> nInt32; + rAny <<= nInt32; + + bOk = true; + } + } + break; + + case DFF_ANIM_PROP_TYPE_FLOAT: + { + if( nRecLen == 5 ) + { + float fFloat; + mrStCtrl >> fFloat; + rAny <<= (double)fFloat; + + bOk = true; + } + } + break; + + case DFF_ANIM_PROP_TYPE_UNISTRING : + { + if ( ( nRecLen & 1 ) && ( nRecLen > 1 ) ) + { + String aString; + mpPPTImport->MSDFFReadZString( mrStCtrl, aString, nRecLen - 1, sal_True ); + rtl::OUString aOUString( aString ); + rAny <<= aOUString; + + bOk = true; + } + } + break; + } + } + } + + DBG_ASSERT( bOk, "invalid value inside ppt::AnimationImporter::importAttributeValue()!" ); + return bOk; +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimationEvents( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( xNode.is() && pAtom, "invalid call to ppt::AnimationImporter::importAnimationEvents()!" ); + + Any aBegin, aEnd, aNext, aPrev; + + const Atom* pEventAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimEvent ); + while( pEventAtom ) + { + Any* pEvents = NULL; + + switch( pEventAtom->getInstance() ) + { + case 1: pEvents = &aBegin; break; + case 2: pEvents = &aEnd; break; + case 3: pEvents = &aNext; break; + case 4: pEvents = &aPrev; break; + } + + if( pEvents ) + { + Event aEvent; + aEvent.Trigger = EventTrigger::NONE; + aEvent.Repeat = 0; + + const Atom* pChildAtom = pEventAtom->findFirstChildAtom(); + + while( pChildAtom && pChildAtom->seekToContent() ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimTrigger: + { + sal_Int32 nU1, nTrigger, nU3, nBegin; + mrStCtrl >> nU1; + mrStCtrl >> nTrigger; + mrStCtrl >> nU3; + mrStCtrl >> nBegin; + + switch( nTrigger ) + { + case 0: aEvent.Trigger = EventTrigger::NONE; break; + case 1: aEvent.Trigger = EventTrigger::ON_BEGIN; break; + case 2: aEvent.Trigger = EventTrigger::ON_END; break; + case 3: aEvent.Trigger = EventTrigger::BEGIN_EVENT; break; + case 4: aEvent.Trigger = EventTrigger::END_EVENT; break; + case 5: aEvent.Trigger = EventTrigger::ON_CLICK; break; + case 6: aEvent.Trigger = EventTrigger::ON_DBL_CLICK; break; + case 7: aEvent.Trigger = EventTrigger::ON_MOUSE_ENTER; break; + case 8: aEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE; break; + case 9: aEvent.Trigger = EventTrigger::ON_NEXT; break; + case 10: aEvent.Trigger = EventTrigger::ON_PREV; break; + case 11: aEvent.Trigger = EventTrigger::ON_STOP_AUDIO; break; + } + + if( (nBegin != 0) || (aEvent.Trigger == EventTrigger::NONE) ) + aEvent.Offset = (nBegin == -1) ? makeAny( Timing_INDEFINITE ) : makeAny( (double)(nBegin / 1000.0) ); + } + break; + case DFF_msofbtAnimateTargetElement: + { + sal_Int16 nSubType; + importTargetElementContainer( pChildAtom, aEvent.Source, nSubType ); + } + break; + default: + { + DBG_ERROR("unknown atom inside ppt::AnimationImporter::importAnimationEvents()!"); + } + } + + pChildAtom = pEventAtom->findNextChildAtom( pChildAtom ); + } + + *pEvents = addToSequence( *pEvents, (aEvent.Trigger == EventTrigger::NONE) ? aEvent.Offset : makeAny( aEvent ) ); + } + + pEventAtom = pAtom->findNextChildAtom( DFF_msofbtAnimEvent, pEventAtom ); + } + + xNode->setBegin( aBegin ); + xNode->setEnd( aEnd ); + // TODO: xNode->setNext( aNext ); + // TODO: xNode->setPrev( aNext ); + +#ifdef DBG_ANIM_LOG + if( aBegin.hasValue() ) + { + dump( " begin=\"" ); + dump( aBegin ); + dump( "\"" ); + } + + if( aEnd.hasValue() ) + { + dump( " end=\"" ); + dump( aEnd ); + dump( "\"" ); + } + + if( aNext.hasValue() ) + { + dump( " next=\"" ); + dump( aNext ); + dump( "\"" ); + } + + if( aPrev.hasValue() ) + { + dump( " prev=\"" ); + dump( aPrev ); + dump( "\"" ); + } +#endif +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimationActions( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationActions()!"); + + if( pAtom ) + { + const Atom* pActionAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAction ); + + if( pActionAtom && pActionAtom->seekToContent() ) + { + sal_Int32 nConcurrent, nNextAction, nEndSync, nU4, nU5; + mrStCtrl >> nConcurrent; + mrStCtrl >> nNextAction; + mrStCtrl >> nEndSync; + mrStCtrl >> nU4; + mrStCtrl >> nU5; + + if( nEndSync == 1 ) + xNode->setEndSync( makeAny( AnimationEndSync::ALL ) ); + + #ifdef DBG_ANIM_LOG + dump( " concurrent=\"%s\"", nConcurrent == 0 ? "disabled" : (nConcurrent == 1 ? "enabled" : "unknown") ); + + dump( " nextAction=\"%s\"", nNextAction == 0 ? "none" : (nNextAction == 1 ? "seek" : "unknown") ); + + if( nEndSync != 0 ) + { + dump( " endSync=\"%s\"", nEndSync == 1 ? "all" : "unknown" ); + } + + dump( " action_4=\"%#lx\"", nU4 ); + dump( " action_5=\"%#lx\"", nU5 ); + #endif + } + } +} + +// -------------------------------------------------------------------- + +sal_Int32 AnimationImporter::importTargetElementContainer( const Atom* pAtom, Any& rTarget, sal_Int16& rSubType ) +{ + rSubType = ShapeAnimationSubType::AS_WHOLE; + sal_Int32 nRefMode = -1; + + DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateTargetElement), "invalid call to ppt::AnimationImporter::importTargetElementContainer()!" ); + if( pAtom ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + while( pChildAtom && pChildAtom->seekToContent() ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimReference: + { + sal_Int32 nRefType,nRefId; + sal_Int32 begin,end; + mrStCtrl >> nRefMode; + mrStCtrl >> nRefType; + mrStCtrl >> nRefId; + mrStCtrl >> begin; + mrStCtrl >> end; + + switch( nRefType ) + { + case 1: // shape + { + SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId ); + if( pSdrObject == NULL ) + break; + + rTarget <<= pSdrObject->getUnoShape(); + + switch( nRefMode ) + { +// default case 0: rSubType = ShapeAnimationSubType::AS_WHOLE; break; + case 6: rSubType = ShapeAnimationSubType::ONLY_BACKGROUND; break; + case 8: rSubType = ShapeAnimationSubType::ONLY_TEXT; break; + case 2: // one paragraph + { + if( ((begin == -1) && (end == -1)) || !pSdrObject->ISA( SdrTextObj ) ) + break; + + SdrTextObj* pTextObj = static_cast< SdrTextObj* >( pSdrObject ); + + const OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject(); + if( pOPO == NULL ) + break; + + const EditTextObject& rEditTextObject = pOPO->GetTextObject(); + + const USHORT nParaCount = rEditTextObject.GetParagraphCount(); + + USHORT nPara = 0; + + while( (nPara < nParaCount) && (begin > 0) ) + { + sal_Int32 nParaLength = rEditTextObject.GetText( nPara ).Len() + 1; + begin -= nParaLength; + end -= nParaLength; + nPara++; + } + + if( nPara < nParaCount ) + { + ParagraphTarget aParaTarget; + rTarget >>= aParaTarget.Shape; + aParaTarget.Paragraph = nPara; + rTarget = makeAny( aParaTarget ); + + rSubType = ShapeAnimationSubType::ONLY_TEXT; + dump( " paragraph %d,", (sal_Int32)nPara); + dump( " %d characters", (sal_Int32)end ); + } + } + } + } + break; + + case 2: // sound + { + OUString aSoundURL( ((ImplSdPPTImport*)mpPPTImport)->ReadSound( nRefId ) ); + rTarget <<= aSoundURL; + dump( " srcRef=\"%s\"", aSoundURL ); + } + break; + case 3: // audio object + case 4: // video object + { + SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId ); + if( pSdrObject == NULL ) + break; + + rTarget <<= pSdrObject->getUnoShape(); + } + break; + default: + DBG_ERROR("unknown reference type"); + } + + +// dump( " ref=\"%s\"", nRefMode == 3 ? "source" : ( nRefMode == 0 ? "target" : "unknown" ) ); +// dump( " type=\"%s\"", nRefType == 1 ? "shape" : ( nRefType == 2 ? "sound": "unknown" ) ); +// dump( " id=\"%lu\"", (sal_Int32)nRefId ); +#ifdef DBG_ANIM_LOG + if((begin != -1) || (end != -1) ) + { +// dump( " text_begin=\"%ld\"", begin ); +// dump( " text_end=\"%ld\"", end ); + } +#endif + } + break; + case 0x2b01: + { + sal_Int32 nU1; + mrStCtrl >> nU1; + + // HINT: nU1 == 1 : target document. ? +// dump( " unknown_0x2b01=\"%#lx\"", nU1 ); + } + break; + default: + DBG_ERROR("unknwon atom inside ppt::AnimationImporter::importTargetElementContainer()!"); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + + } + } + + return nRefMode; +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importPropertySetContainer( const Atom* pAtom, PropertySet& rSet ) +{ + DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimPropertySet), "invalid call to ppt::AnimationImporter::importPropertySetContainer()!" ); + + if( pAtom ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + while( pChildAtom ) + { + if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue ) + { + Any aAny; + importAttributeValue( pChildAtom, aAny ); + rSet.maProperties[ pChildAtom->getInstance() ] = aAny; + } + else + { + DBG_ERROR("unknwon atom inside ppt::AnimationImporter::importPropertySetContainer()!"); + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// ==================================================================== + +#ifdef DBG_ANIM_LOG +void AnimationImporter::dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend ) +{ + if( pAtom ) + { + const char* pTitle; + + bool bUnknown = false; + + switch( pAtom->getType() ) + { + case DFF_msofbtAnimEvent: pTitle = "AnimEvent"; break; + case DFF_msofbtAnimTrigger: pTitle = "AnimTrigger"; break; + case DFF_msofbtAnimateMotion: pTitle = "AnimateMotion"; break; + case DFF_msofbtAnimPropertySet: pTitle = "AnimPropertySet"; break; + case DFF_msofbtAnimateAttributeNames: pTitle = "AnimAttributeName"; break; + case DFF_msofbtAnimAttributeValue: pTitle = "AnimAttributeValue"; break; + case DFF_msofbtAnimGroup: pTitle = "AnimGroup"; break; + case DFF_msofbtAnimNode: pTitle = "AnimNode"; break; + case DFF_msofbtAnimValue: pTitle = "AnimValue"; break; + case DFF_msofbtAnimateFilter: pTitle = "animateFilter"; break; + case DFF_msofbtAnimate: pTitle = "animate"; break; + case DFF_msofbtAnimateSet: pTitle = "set"; break; + case DFF_msofbtAnimKeyTime: pTitle = "AnimKeyTime"; break; + case DFF_msofbtAnimKeyPoints: pTitle = "AnimKeyPoints"; break; + case DFF_msofbtAnimReference: pTitle = "AnimReference"; break; + case DFF_msofbtAnimateTargetElement: pTitle = "AnimTargetElementContainer"; break; + case DFF_msofbtAnimAction: pTitle = "AnimAction"; break; + case DFF_msofbtAnimCommand: pTitle = "AnimCommand"; break; + case DFF_msofbtAnimateTarget: pTitle = "TransformationTarget"; break; + case DFF_msofbtAnimateTargetSettings: pTitle = "TransformationTargetSettings"; break; + case DFF_msofbtAnimIteration: pTitle = "iterate"; break; + case DFF_msofbtAnimateColorData: pTitle = "colorData"; break; + case DFF_msofbtAnimateScaleData: pTitle = "scaleData"; break; + case DFF_msofbtAnimateSetData: pTitle = "setData"; break; + + default: + { + static char buffer[128]; + sprintf( buffer, "unknown_%#x", pAtom->getType() ); + pTitle = buffer; + } + } + + if( bOpen ) + { + fprintf(mpFile, "<%s", pTitle ); + + fprintf(mpFile, " instance=\"%hu\"%s", + pAtom->getInstance(), + bAppend ? "" : ">\n"); + } + else + { + if( bAppend ) + fprintf(mpFile,"/>\n"); + else + fprintf(mpFile, "</%s>\n", pTitle ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::dump( UINT32 nLen, bool bNewLine ) +{ + char * faul = "0123456789abcdef"; + + UINT32 i = 0; + int b = 0; + sal_Int8 nData; + + for( i = 0; i < nLen; i++ ) + { + mrStCtrl >> nData; + + fprintf( mpFile, "%c%c ", faul[ (nData >> 4) & 0x0f ], faul[ nData & 0x0f ] ); + + b++; + if( bNewLine && (b == 32) ) + { + fprintf(mpFile,"\n"); + b = 0; + } + } + if( (b != 0) && bNewLine ) + fprintf(mpFile,"\n"); +} + +// -------------------------------------------------------------------- + +void AnimationImporter::dump_atom( const Atom* pAtom, bool bNewLine ) +{ + if( pAtom ) + { + if( pAtom->isContainer() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + while( pChildAtom ) + { + if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue ) + { + fprintf(mpFile, "<attributeValue instance=\"%hu\"", pChildAtom->getInstance() ); + + Any aValue; + if( importAttributeValue( pChildAtom, aValue ) ) + { + sal_Int32 nInt; + rtl::OUString aString; + double fDouble; + + if( aValue >>= nInt ) + { + fprintf(mpFile, " value=\"%ld\"", nInt ); + } + else if( aValue >>= aString ) + { + UniString aTmp( aString ); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf(mpFile, " value=\"%s\"", aStr.GetBuffer() ); + } + else if( aValue >>= fDouble ) + { + fprintf(mpFile, " value=\"%g\"", fDouble ); + } + } + else + { + if( pChildAtom->seekToContent() ) + { + fprintf(mpFile, " value=\"" ); + dump_atom( pChildAtom, false ); + fprintf(mpFile, "\""); + } + } + + fprintf(mpFile, "/>\n" ); + } + else + { + dump_atom_header( pChildAtom, true, pChildAtom->getType() == DFF_msofbtAnimAttributeValue ); + dump_atom( pChildAtom ); + dump_atom_header( pChildAtom, false, pChildAtom->getType() == DFF_msofbtAnimAttributeValue ); + } + + pChildAtom = pAtom->findNextChildAtom(pChildAtom); + } + } + else if( pAtom->seekToContent() ) + { + dump( pAtom->getLength(), bNewLine ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen ) +{ + fprintf( mpFile, bOpen ? "<" : "</" ); + + switch( rNode.mnGroupType ) + { + case mso_Anim_GroupType_PAR: + fprintf( mpFile, "par" ); + break; + case mso_Anim_GroupType_SEQ: + fprintf( mpFile, "seq" ); + break; + case mso_Anim_GroupType_NODE: + switch( rNode.mnNodeType ) + { + case mso_Anim_Behaviour_FILTER: + fprintf( mpFile, "animateFilter" ); + break; + case mso_Anim_Behaviour_ANIMATION: + if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) ) + fprintf( mpFile, "set" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) ) + fprintf( mpFile, "animateColor" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) ) + fprintf( mpFile, "animateScale" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) ) + fprintf( mpFile, "animateRotation" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) ) + fprintf( mpFile, "animateMotion" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) + fprintf( mpFile, "command" ); + else + fprintf( mpFile, "animation" ); + break; + default: + { + fprintf( mpFile, "unknown_node_%#lx", rNode.mnNodeType ); + } + break; + } + break; + case mso_Anim_GroupType_MEDIA: + fprintf( mpFile, "media" ); + break; + default: + fprintf( mpFile, "unknown_group_%#lx", rNode.mnGroupType ); + break; + } + + if( bOpen ) + { + dump( rNode ); + dump( rSet ); + } + + fprintf(mpFile,">\n"); +} + +void AnimationImporter::dump( const AnimationNode& rNode ) +{ + // dump animation node + if( rNode.mnRestart != 0 ) + { + fprintf(mpFile," restart=\"%s\"", + rNode.mnRestart == 1 ? "always" : (rNode.mnRestart == 2 ? "whenOff" : (rNode.mnRestart == 3 ? "never" : "unknown")) ); + } + + if( rNode.mnFill ) + { + fprintf(mpFile," fill=\"%s\"", + rNode.mnFill == 1 ? "remove" : (rNode.mnFill == 3 ? "hold" : (rNode.mnFill == 2 ? "freeze" : "unknown")) ); + } + + if( rNode.mnDuration > 0 ) + { + double fSeconds = rNode.mnDuration; + fSeconds /= 1000.0; + fprintf(mpFile, " dur=\"%g\"", fSeconds); + } + else if( rNode.mnDuration < 0 ) + { + fprintf(mpFile, " dur=\"indefinite\"" ); + } + + if( rNode.mnU1 ) fprintf(mpFile," u1=\"%#lx\"", rNode.mnU1); + if( rNode.mnU3 ) fprintf(mpFile," u3=\"%#lx\"", rNode.mnU3); + if( rNode.mnU4 ) fprintf(mpFile," u4=\"%#lx\"", rNode.mnU4); +} + +void AnimationImporter::dump( Any& rAny ) +{ + Sequence< Any > aSeq; + sal_Int32 nInt; + double fDouble; + OUString aString; + sal_Bool bBool; + Event aEvent; + Timing aTiming; + + if( rAny >>= aSeq ) + { + const sal_Int32 nSize = aSeq.getLength(); + sal_Int32 nIndex = 0; + while( nIndex < nSize ) + { + dump( aSeq[nIndex++] ); + if(nIndex < nSize) + fprintf( mpFile, "," ); + } + } + else if( rAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, "%s", aStr.GetBuffer() ); + } + else if( rAny >>= nInt ) + { + fprintf( mpFile, "%ld", nInt ); + } + else if( rAny >>= bBool ) + { + fprintf( mpFile, "%s", bBool ? "true" : "false" ); + } + else if( rAny >>= fDouble ) + { + fprintf( mpFile, "%g", fDouble ); + } + else if( rAny >>= aTiming ) + { + fprintf( mpFile, "%s", aTiming == (Timing_INDEFINITE) ? "indefinite" : "media" ); + } + else if( rAny >>= aEvent ) + { + static const char* triggers[] = + { + "none","onbegin","onend","begin", + "end","onclick","ondoubleclick","onmouseenter", + "onmouseleave","onpptnext","onpptprev","onstopaudio" + }; + + if( aEvent.Trigger != EventTrigger::NONE ) + { + if( aEvent.Source.hasValue() ) + { + dump_target( aEvent.Source ); + dump( "." ); + } + + dump( triggers[ aEvent.Trigger ] ); + } + + if( aEvent.Offset.hasValue() ) + { + double fOffset; + if( aEvent.Offset >>= fOffset ) + fprintf( mpFile, "%g", fOffset ); + else + dump( "indefinite" ); + } + } +} + +void AnimationImporter::dump( const PropertySet& rSet ) +{ + // dump property set + + map< sal_Int32, Any >::const_iterator aIter( rSet.maProperties.begin() ); + const map< sal_Int32, Any >::const_iterator aEnd( rSet.maProperties.end() ); + while( aIter != aEnd ) + { + bool bKnown = false; + + const sal_Int32 nInstance = (*aIter).first; + Any aAny( (*aIter).second ); + + switch ( nInstance ) + { + case DFF_ANIM_COLORSPACE: + { + sal_Int32 nColorSpace; + if( aAny >>= nColorSpace ) + { + fprintf( mpFile, " colorSpace=\"%s\"", (nColorSpace == 0) ? "rgb" : (nColorSpace == 1) ? "hsl" : "unknown" ); + bKnown = true; + } + } + break; + + case DFF_ANIM_DIRECTION: +// case DFF_ANIM_MASTERREL: + { + sal_Bool bDirection; + if( aAny >>= bDirection ) + { + fprintf( mpFile, " direction=\"%s\"", bDirection ? "cclockwise" : "clockwise" ); + bKnown = true; + } + else + { + sal_Int32 nMasterRel; + if( aAny >>= nMasterRel ) + { + fprintf( mpFile, " direction=\"%s\"", nMasterRel == 0 ? "sameClick" : ( nMasterRel == 2 ? "nextClick" : "lastClick" ) ); + bKnown = true; + } + } + } + break; + + case DFF_ANIM_OVERRIDE: // TODO + { + sal_Int32 nOverride; + if( aAny >>= nOverride ) + { + fprintf( mpFile, " override=\"%s\"", (nOverride == 1) ? "childStyle" : (nOverride == 0) ? "normal" : "unknown" ); + bKnown = true; + } + } + break; + + case DFF_ANIM_PATH_EDIT_MODE: + { + sal_Bool bPathEditMode; + if( aAny >>= bPathEditMode ) + { + fprintf( mpFile, " pptPathEditMode=\"%s\"", bPathEditMode ? "relative" : "fixed" ); + bKnown = true; + } + } + break; + + case DFF_ANIM_PRESET_ID : + { + sal_Int32 nPresetId ; + if( aAny >>= nPresetId ) + { + fprintf(mpFile, " presetid=\"%ld\"", nPresetId ); + bKnown = true; + } + } + break; + + case DFF_ANIM_PRESET_SUB_TYPE : + { + sal_Int32 nPointsType ; + if( aAny >>= nPointsType ) + { + fprintf(mpFile, " presetSubType=\"%ld\"", nPointsType ); + bKnown = true; + } + } + break; + + case DFF_ANIM_PRESET_CLASS : + { + sal_Int32 nPresetClass; + if ( aAny >>= nPresetClass ) + { + const char* pMode; + switch( nPresetClass ) + { + case DFF_ANIM_PRESS_CLASS_USER_DEFINED: pMode = "userdefined"; break; + case DFF_ANIM_PRESS_CLASS_ENTRANCE: pMode = "entrance"; break; + case DFF_ANIM_PRESS_CLASS_EXIT: pMode = "exit"; break; + case DFF_ANIM_PRESS_CLASS_EMPHASIS: pMode = "emphasis"; break; + case DFF_ANIM_PRESS_CLASS_MOTIONPATH: pMode = "motionpath"; break; + case DFF_ANIM_PRESS_CLASS_OLE_ACTION: pMode = "oleaction"; break; + case DFF_ANIM_PRESS_CLASS_MEDIACALL: pMode = "mediacall"; break; + default: + { + static char buffer[128]; + sprintf( buffer, "%ld", nPresetClass ); + pMode = buffer; + } + break; + } + + fprintf(mpFile, " class=\"%s\"", pMode); + bKnown = true; + } + } + break; + + case DFF_ANIM_NODE_TYPE : + { + sal_Int32 nNodeType; + if ( aAny >>= nNodeType ) + { + const char* pNode; + switch( nNodeType ) + { + case DFF_ANIM_NODE_TYPE_ON_CLICK: pNode = "onclick"; break; + case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: pNode = "withprevious"; break; + case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: pNode = "afterprevious"; break; + case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: pNode = "mainsequence"; break; + case DFF_ANIM_NODE_TYPE_TIMING_ROOT: pNode = "timingroot"; break; + case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:pNode = "interactivesequence"; break; + default : + { + static char buffer[128]; + sprintf( buffer, "%ld", nNodeType ); + pNode = buffer; + } + break; + } + + fprintf(mpFile, " nodeType=\"%s\"", pNode); + bKnown = true; + } + } + break; + + case DFF_ANIM_GROUP_ID: + { + sal_Int32 nGroupId; + if ( aAny >>= nGroupId ) + { + fprintf( mpFile, " groupId=\"%ld\"", nGroupId ); + bKnown = true; + } + } + break; + + case DFF_ANIM_ID: + { + rtl::OUString aString; + if( aAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, " id=\"%s\"", aStr.GetBuffer() ); + bKnown = true; + } + } + break; + + case DFF_ANIM_EVENT_FILTER: + { + rtl::OUString aString; + if( aAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, " eventFilter=\"%s\"", aStr.GetBuffer() ); + bKnown = true; + } + } + break; + + case DFF_ANIM_ENDAFTERSLIDE: + { + sal_Int32 nEndAfterSlide; + if( aAny >>= nEndAfterSlide ) + { + fprintf(mpFile, " endAfterSlide=\"%ld\"", nEndAfterSlide ); + bKnown = true; + } + } + + case DFF_ANIM_TIMEFILTER: + { + rtl::OUString aString; + if( aAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, " timeFilter=\"%s\"", aStr.GetBuffer() ); + bKnown = true; + } + } + break; + + case DFF_ANIM_RUNTIMECONTEXT: + { + rtl::OUString aString; + if( aAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, " runtimeContext=\"%s\"", aStr.GetBuffer() ); + bKnown = true; + } + } + break; + + case DFF_ANIM_VOLUME: + { + double fVolume; + if( aAny >>= fVolume ) + { + fprintf( mpFile, " volume=\"%g%%\"", (double)(fVolume * 100.0) ); + bKnown = true; + } + } + break; + + case DFF_ANIM_AFTEREFFECT: + { + sal_Bool bAfterEffect; + if( aAny >>= bAfterEffect ) + { + fprintf( mpFile, "afterEffect=\"%s\"", bAfterEffect ? "true" : "false" ); + bKnown = true; + } + } + break; + + } + + + if( !bKnown ) + { + fprintf( mpFile, " unknown_%lu=\"", nInstance ); + dump( aAny ); + fprintf( mpFile, "\"" ); + } + + aIter++; + } +} + +void AnimationImporter::dump_target( Any& rAny ) +{ + Any aSource, aSourceData; + Sequence< Any > aSeq; + if( rAny >>= aSeq ) + { + if( aSeq.getLength() >= 1 ) aSource = aSeq[0]; + if( aSeq.getLength() >= 2 ) aSourceData = aSeq[1]; + } + else + { + aSource = rAny; + } + + Reference< XShape > xShape; + aSource >>= xShape; + if( xShape.is() ) + { + OUString aStr( xShape->getShapeType() ); + dump( aStr ); + + if( aSourceData.hasValue() ) + { + dump( "(" ); + dump( aSourceData ); + dump( ")" ); + } + } +} + +void AnimationImporter::dump( const char * pText ) +{ + fprintf( mpFile, "%s", pText ); +} + +void AnimationImporter::dump( const rtl::OUString& rString ) +{ + UniString aTmp( rString ); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, aStr.GetBuffer() ); +} + +void AnimationImporter::dump( const char * pText, sal_Int32 nInt ) +{ + fprintf( mpFile, pText, nInt ); +} + +void AnimationImporter::dump( const char * pText, double fDouble ) +{ + fprintf( mpFile, pText, fDouble ); +} + +void AnimationImporter::dump( const char * pText, const char * pText2 ) +{ + fprintf( mpFile, pText, pText2 ); +} + +void AnimationImporter::dump( const char * pText, const OUString& rString ) +{ + UniString aTmp( rString ); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, pText, aStr.GetBuffer() ); +} + +#else + +void AnimationImporter::dump_atom_header( const Atom* , bool , bool ) +{ +} + +void AnimationImporter::dump_atom( const Atom* , bool ) +{ +} + +void AnimationImporter::dump( sal_uInt32 , bool ) +{ +} + +void AnimationImporter::dump_anim_group( const Atom* , const AnimationNode& , const PropertySet& , bool ) +{ +} + +void AnimationImporter::dump_target( ::com::sun::star::uno::Any& ) +{ +} + +void AnimationImporter::dump( ::com::sun::star::uno::Any& ) +{ +} + +void AnimationImporter::dump( const PropertySet& ) +{ +} + +void AnimationImporter::dump( const AnimationNode& ) +{ +} + +void AnimationImporter::dump( const char * ) +{ +} + +void AnimationImporter::dump( const rtl::OUString& ) +{ +} + +void AnimationImporter::dump( const char * , sal_Int32 ) +{ +} + +void AnimationImporter::dump( const char * , double ) +{ +} + +void AnimationImporter::dump( const char * , const char * ) +{ +} + +void AnimationImporter::dump( const char * , const rtl::OUString& ) +{ +} + +#endif + +} // namespace ppt; + diff --git a/sd/source/filter/ppt/pptinanimations.hxx b/sd/source/filter/ppt/pptinanimations.hxx new file mode 100644 index 000000000000..d29449361861 --- /dev/null +++ b/sd/source/filter/ppt/pptinanimations.hxx @@ -0,0 +1,132 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPT_INANIMATIONS_HXX +#define _SD_PPT_INANIMATIONS_HXX + +#include <com/sun/star/animations/XTimeContainer.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> + +#include "pptanimations.hxx" +#include <animations.hxx> + +#ifdef DBG_ANIM_LOG +#include <stdio.h> +#endif +#include <filter/msfilter/svdfppt.hxx> + +#include <list> + +class DffRecordHeader; +class SdPage; +class SvStream; +class ImplSdPPTImport; + +namespace ppt +{ +class PropertySet; +class Atom; + +class AnimationImporter +{ +public: + AnimationImporter( ImplSdPPTImport* pPPTImport, SvStream& rStCtrl ); + + void import( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd ); + +private: + void importAnimationContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xParent ); + void importTimeContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimationNodeContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimationSubContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + void importAnimateSetContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateFilterContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateScaleContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateColorContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateRotationContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateMotionContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importCommandContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAudioContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + void importAnimationEvents( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimationValues( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimationActions( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateAttributeTargetContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + void importAnimateKeyPoints( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importPropertySetContainer( const Atom* pAtom,PropertySet& rSet ); + bool importAttributeValue( const Atom* pAtom, com::sun::star::uno::Any& rAny ); + bool importAttributeNamesContainer( const Atom* pAtom, rtl::OUString& rAttributeNames ); + sal_Int32 importTargetElementContainer( const Atom* pAtom, ::com::sun::star::uno::Any& rTarget, sal_Int16& nSubType ); + + void fillNode( ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xTiming, const AnimationNode& rNode, const PropertySet& rSet ); + ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > createNode( const Atom* pAtom, const AnimationNode& rNode ); + + bool convertAnimationNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xParent ); + bool convertAnimationValue( MS_AttributeNames eAttribute, com::sun::star::uno::Any& rValue ); + + void fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + void processAfterEffectNodes(); + + ::com::sun::star::uno::Any implGetColorAny( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC ); + sal_Int16 implGetColorSpace( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC ); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > mxRootNode; + + ImplSdPPTImport* mpPPTImport; + SvStream& mrStCtrl; + + sd::AfterEffectNodeList maAfterEffectNodes; + +#ifdef DBG_ANIM_LOG + FILE * mpFile; +#endif + + void dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend ); + void dump_atom( const Atom* pAtom, bool bNewLine = true ); + void dump( sal_uInt32 nLen, bool bNewLine = true ); + void dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen ); + void dump_target( ::com::sun::star::uno::Any& rAny ); + void dump( ::com::sun::star::uno::Any& rAny ); + void dump( const PropertySet& rSet ); + void dump( const AnimationNode& rNode ); + void dump( const char * pText ); + void dump( const rtl::OUString& rString ); + void dump( const char * pText, sal_Int32 nInt ); + void dump( const char * pText, double fDouble ); + void dump( const char * pText, const char * pText2 ); + void dump( const char * pText, const rtl::OUString& rString ); +}; + +} // namespace ppt + +#endif diff --git a/sd/source/filter/ppt/propread.cxx b/sd/source/filter/ppt/propread.cxx new file mode 100644 index 000000000000..54acab192cb5 --- /dev/null +++ b/sd/source/filter/ppt/propread.cxx @@ -0,0 +1,695 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <propread.hxx> +#include <tools/bigint.hxx> +#include "rtl/tencinfo.h" +#include "rtl/textenc.h" + +// ------------------------------------------------------------------------ + +struct PropEntry +{ + sal_uInt32 mnId; + sal_uInt32 mnSize; + sal_uInt16 mnTextEnc; + sal_uInt8* mpBuf; + + PropEntry( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize, sal_uInt16 nTextEnc ); + PropEntry( const PropEntry& rProp ); + ~PropEntry() { delete[] mpBuf; } ; + + const PropEntry& operator=(const PropEntry& rPropEntry); +}; + +PropEntry::PropEntry( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize, sal_uInt16 nTextEnc ) : + mnId ( nId ), + mnSize ( nBufSize ), + mnTextEnc ( nTextEnc ), + mpBuf ( new sal_uInt8[ nBufSize ] ) +{ + memcpy( (void*)mpBuf, (void*)pBuf, nBufSize ); +}; + +PropEntry::PropEntry( const PropEntry& rProp ) : + mnId ( rProp.mnId ), + mnSize ( rProp.mnSize ), + mnTextEnc ( rProp.mnTextEnc ), + mpBuf ( new sal_uInt8[ mnSize ] ) +{ + memcpy( (void*)mpBuf, (void*)rProp.mpBuf, mnSize ); +}; + +const PropEntry& PropEntry::operator=(const PropEntry& rPropEntry) +{ + if ( this != &rPropEntry ) + { + delete[] mpBuf; + mnId = rPropEntry.mnId; + mnSize = rPropEntry.mnSize; + mnTextEnc = rPropEntry.mnTextEnc; + mpBuf = new sal_uInt8[ mnSize ]; + memcpy( (void*)mpBuf, (void*)rPropEntry.mpBuf, mnSize ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +void PropItem::Clear() +{ + Seek( STREAM_SEEK_TO_BEGIN ); + delete[] (sal_uInt8*)SwitchBuffer(); +} + +// ----------------------------------------------------------------------- + +BOOL PropItem::Read( String& rString, sal_uInt32 nStringType, sal_Bool bAlign ) +{ + sal_uInt32 i, nItemSize, nType, nItemPos; + sal_Bool bRetValue = sal_False; + + nItemPos = Tell(); + + if ( nStringType == VT_EMPTY ) + *this >> nType; + else + nType = nStringType & VT_TYPEMASK; + + *this >> nItemSize; + + switch( nType ) + { + case VT_LPSTR : + { + if ( (sal_uInt16)nItemSize ) + { + sal_Char* pString = new sal_Char[ (sal_uInt16)nItemSize ]; + if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) + { + nItemSize >>= 1; + if ( (sal_uInt16)nItemSize > 1 ) + { + sal_Unicode* pWString = (sal_Unicode*)pString; + for ( i = 0; i < (sal_uInt16)nItemSize; i++ ) + *this >> pWString[ i ]; + rString = String( pWString, (sal_uInt16)nItemSize - 1 ); + } + else + rString = String(); + bRetValue = sal_True; + } + else + { + SvMemoryStream::Read( pString, (sal_uInt16)nItemSize ); + if ( pString[ (sal_uInt16)nItemSize - 1 ] == 0 ) + { + if ( (sal_uInt16)nItemSize > 1 ) + rString = String( ByteString( pString ), mnTextEnc ); + else + rString = String(); + bRetValue = sal_True; + } + } + delete[] pString; + } + if ( bAlign ) + SeekRel( ( 4 - ( nItemSize & 3 ) ) & 3 ); // dword align + } + break; + + case VT_LPWSTR : + { + if ( nItemSize ) + { + sal_Unicode* pString = new sal_Unicode[ (sal_uInt16)nItemSize ]; + for ( i = 0; i < (sal_uInt16)nItemSize; i++ ) + *this >> pString[ i ]; + if ( pString[ i - 1 ] == 0 ) + { + if ( (sal_uInt16)nItemSize > 1 ) + rString = String( pString, (sal_uInt16)nItemSize - 1 ); + else + rString = String(); + bRetValue = sal_True; + } + delete[] pString; + } + if ( bAlign && ( nItemSize & 1 ) ) + SeekRel( 2 ); // dword align + } + break; + } + if ( !bRetValue ) + Seek( nItemPos ); + return bRetValue; +} + +// ----------------------------------------------------------------------- + +PropItem& PropItem::operator=( PropItem& rPropItem ) +{ + if ( this != &rPropItem ) + { + Seek( STREAM_SEEK_TO_BEGIN ); + delete[] (sal_uInt8*)SwitchBuffer(); + + mnTextEnc = rPropItem.mnTextEnc; + sal_uInt32 nItemPos = rPropItem.Tell(); + rPropItem.Seek( STREAM_SEEK_TO_END ); + SvMemoryStream::Write( rPropItem.GetData(), rPropItem.Tell() ); + rPropItem.Seek( nItemPos ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +struct Dict +{ + sal_uInt32 mnId; + String aString; + + Dict( sal_uInt32 nId, String rString ) { mnId = nId; aString = rString; }; +}; + +// ----------------------------------------------------------------------- + +Dictionary::~Dictionary() +{ + for ( void* pPtr = First(); pPtr; pPtr = Next() ) + delete (Dict*)pPtr; +} + +// ----------------------------------------------------------------------- + +void Dictionary::AddProperty( sal_uInt32 nId, const String& rString ) +{ + if ( rString.Len() ) // eindeutige namen bei properties + { + // pruefen, ob es die Propertybeschreibung in der Dictionary schon gibt + for ( Dict* pDict = (Dict*)First(); pDict; pDict = (Dict*)Next() ) + { + if ( pDict->mnId == nId ) + { + pDict->aString = rString; + return; + } + } + Insert( new Dict( nId, rString ), LIST_APPEND ); + } +} + +// ----------------------------------------------------------------------- + +UINT32 Dictionary::GetProperty( const String& rString ) +{ + for ( Dict* pDict = (Dict*)First(); pDict; pDict = (Dict*)Next() ) + { + if ( pDict->aString == rString ) + return pDict->mnId; + } + return 0; +} + +// ----------------------------------------------------------------------- + +Dictionary& Dictionary::operator=( Dictionary& rDictionary ) +{ + void* pPtr; + + if ( this != &rDictionary ) + { + for ( pPtr = First(); pPtr; pPtr = Next() ) + delete (Dict*)pPtr; + + for ( pPtr = rDictionary.First(); pPtr; pPtr = rDictionary.Next() ) + Insert( new Dict( ((Dict*)pPtr)->mnId, ((Dict*)pPtr)->aString ), LIST_APPEND ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +Section::Section( Section& rSection ) +: List() +{ + mnTextEnc = rSection.mnTextEnc; + for ( int i = 0; i < 16; i++ ) + aFMTID[ i ] = rSection.aFMTID[ i ]; + for ( PropEntry* pProp = (PropEntry*)rSection.First(); pProp; pProp = (PropEntry*)rSection.Next() ) + Insert( new PropEntry( *pProp ), LIST_APPEND ); +} + +// ----------------------------------------------------------------------- + +Section::Section( const sal_uInt8* pFMTID ) +{ + mnTextEnc = RTL_TEXTENCODING_MS_1252; + for ( int i = 0; i < 16; i++ ) + aFMTID[ i ] = pFMTID[ i ]; +} + +// ----------------------------------------------------------------------- + +sal_Bool Section::GetProperty( sal_uInt32 nId, PropItem& rPropItem ) +{ + PropEntry* pProp; + if ( nId ) + { + for ( pProp = (PropEntry*)First(); pProp; pProp = (PropEntry*)Next() ) + { + if ( pProp->mnId == nId ) + break; + } + if ( pProp ) + { + rPropItem.Clear(); + rPropItem.SetTextEncoding( mnTextEnc ); + rPropItem.Write( pProp->mpBuf, pProp->mnSize ); + rPropItem.Seek( STREAM_SEEK_TO_BEGIN ); + return sal_True; + } + } + return sal_False; +} + +// ----------------------------------------------------------------------- + +void Section::AddProperty( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize ) +{ + // kleiner id check + + if ( !nId ) + return; + if ( nId == 0xffffffff ) + nId = 0; + + // keine doppelten PropId's zulassen, sortieren + for ( sal_uInt32 i = 0; i < Count(); i++ ) + { + PropEntry* pPropEntry = (PropEntry*)GetObject( i ); + if ( pPropEntry->mnId == nId ) + delete (PropEntry*)Replace( new PropEntry( nId, pBuf, nBufSize, mnTextEnc ), i ); + else if ( pPropEntry->mnId > nId ) + Insert( new PropEntry( nId, pBuf, nBufSize, mnTextEnc ), i ); + else + continue; + return; + } + Insert( new PropEntry( nId, pBuf, nBufSize, mnTextEnc ), LIST_APPEND ); +} + +// ----------------------------------------------------------------------- + +sal_Bool Section::GetDictionary( Dictionary& rDict ) +{ + sal_Bool bRetValue = sal_False; + + Dictionary aDict; + PropEntry* pProp; + + for ( pProp = (PropEntry*)First(); pProp; pProp = (PropEntry*)Next() ) + { + if ( pProp->mnId == 0 ) + break; + } + if ( pProp ) + { + sal_uInt32 nDictCount, nId, nSize, nPos; + SvMemoryStream aStream( (sal_Int8*)pProp->mpBuf, pProp->mnSize, STREAM_READ ); + aStream.Seek( STREAM_SEEK_TO_BEGIN ); + aStream >> nDictCount; + for ( sal_uInt32 i = 0; i < nDictCount; i++ ) + { + aStream >> nId >> nSize; + if ( (sal_uInt16)nSize ) + { + String aString; + nPos = aStream.Tell(); + sal_Char* pString = new sal_Char[ (sal_uInt16)nSize ]; + aStream.Read( pString, (sal_uInt16)nSize ); + if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) + { + nSize >>= 1; + aStream.Seek( nPos ); + sal_Unicode* pWString = (sal_Unicode*)pString; + for ( i = 0; i < (sal_uInt16)nSize; i++ ) + aStream >> pWString[ i ]; + aString = String( pWString, (sal_uInt16)nSize - 1 ); + } + else + aString = String( ByteString( pString, (sal_uInt16)nSize - 1 ), mnTextEnc ); + delete[] pString; + if ( !aString.Len() ) + break; + aDict.AddProperty( nId, aString ); + } + bRetValue = sal_True; + } + } + rDict = aDict; + return bRetValue; +} + +// ----------------------------------------------------------------------- + +Section::~Section() +{ + for ( PropEntry* pProp = (PropEntry*)First(); pProp; pProp = (PropEntry*)Next() ) + delete pProp; +} + +// ----------------------------------------------------------------------- + +void Section::Read( SvStorageStream *pStrm ) +{ + sal_uInt32 i, nSecOfs, nSecSize, nPropCount, nPropId, nPropOfs, nPropType, nPropSize, nCurrent, nVectorCount, nTemp, nStrmSize; + nSecOfs = pStrm->Tell(); + + pStrm->Seek( STREAM_SEEK_TO_END ); + nStrmSize = pStrm->Tell(); + pStrm->Seek( nSecOfs ); + + mnTextEnc = RTL_TEXTENCODING_MS_1252; + *pStrm >> nSecSize >> nPropCount; + while( nPropCount-- && ( pStrm->GetError() == ERRCODE_NONE ) ) + { + *pStrm >> nPropId >> nPropOfs; + nCurrent = pStrm->Tell(); + pStrm->Seek( nPropOfs + nSecOfs ); + if ( nPropId ) // dictionary wird nicht eingelesen + { + + *pStrm >> nPropType; + + nPropSize = 4; + + if ( nPropType & VT_VECTOR ) + { + *pStrm >> nVectorCount; + nPropType &=~VT_VECTOR; + nPropSize += 4; + } + else + nVectorCount = 1; + + + sal_Bool bVariant = ( nPropType == VT_VARIANT ); + + for ( i = 0; nPropSize && ( i < nVectorCount ); i++ ) + { + if ( bVariant ) + { + *pStrm >> nPropType; + nPropSize += 4; + } + switch( nPropType ) + { + case VT_UI1 : + nPropSize++; + break; + + case VT_I2 : + case VT_UI2 : + case VT_BOOL : + nPropSize += 2; + break; + + case VT_I4 : + case VT_R4 : + case VT_UI4 : + case VT_ERROR : + nPropSize += 4; + break; + + case VT_I8 : + case VT_R8 : + case VT_CY : + case VT_UI8 : + case VT_DATE : + case VT_FILETIME : + nPropSize += 8; + break; + + case VT_BSTR : + *pStrm >> nTemp; + nPropSize += ( nTemp + 4 ); + break; + + case VT_LPSTR : + *pStrm >> nTemp; + nPropSize += ( nTemp + 4 ); + break; + + case VT_LPWSTR : + *pStrm >> nTemp; + nPropSize += ( nTemp << 1 ) + 4; + break; + + case VT_BLOB_OBJECT : + case VT_BLOB : + case VT_CF : + *pStrm >> nTemp; + nPropSize += ( nTemp + 4 ); + break; + + case VT_CLSID : + case VT_STREAM : + case VT_STORAGE : + case VT_STREAMED_OBJECT : + case VT_STORED_OBJECT : + case VT_VARIANT : + case VT_VECTOR : + default : + nPropSize = 0; + } + if ( nPropSize ) + { + if ( ( nVectorCount - i ) > 1 ) + pStrm->Seek( nPropOfs + nSecOfs + nPropSize ); + } + else + break; + } + if ( nPropSize ) + { + pStrm->Seek( nPropOfs + nSecOfs ); + sal_uInt8* pBuf = new sal_uInt8[ nPropSize ]; + pStrm->Read( pBuf, nPropSize ); + AddProperty( nPropId, pBuf, nPropSize ); + delete[] pBuf; + } + if ( nPropId == 1 ) + { + PropItem aPropItem; + if ( GetProperty( 1, aPropItem ) ) + { + sal_uInt16 nCodePage; + aPropItem >> nPropType; + if ( nPropType == VT_I2 ) + { + aPropItem >> nCodePage; + + if ( nCodePage == 1200 ) + { + mnTextEnc = RTL_TEXTENCODING_UCS2; + } + else + { + mnTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage ); + if ( mnTextEnc == RTL_TEXTENCODING_DONTKNOW ) + mnTextEnc = RTL_TEXTENCODING_MS_1252; + } + } + else + { + mnTextEnc = RTL_TEXTENCODING_MS_1252; + } + } + } + } + else + { + sal_uInt32 nDictCount, nSize; + *pStrm >> nDictCount; + for ( i = 0; i < nDictCount; i++ ) + { + *pStrm >> nSize >> nSize; + pStrm->SeekRel( nSize ); + } + nSize = pStrm->Tell(); + pStrm->Seek( nPropOfs + nSecOfs ); + nSize -= pStrm->Tell(); + if ( nSize > nStrmSize ) + { + nPropCount = 0; + break; + } + sal_uInt8* pBuf = new sal_uInt8[ nSize ]; + pStrm->Read( pBuf, nSize ); + AddProperty( 0xffffffff, pBuf, nSize ); + delete[] pBuf; + } + pStrm->Seek( nCurrent ); + } + pStrm->Seek( nSecOfs + nSecSize ); +} + +// ----------------------------------------------------------------------- + +Section& Section::operator=( Section& rSection ) +{ + PropEntry* pProp; + + if ( this != &rSection ) + { + memcpy( (void*)aFMTID, (void*)rSection.aFMTID, 16 ); + for ( pProp = (PropEntry*)First(); pProp; pProp = (PropEntry*)Next() ) + delete pProp; + Clear(); + for ( pProp = (PropEntry*)rSection.First(); pProp; pProp = (PropEntry*)rSection.Next() ) + Insert( new PropEntry( *pProp ), LIST_APPEND ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +PropRead::PropRead( SvStorage& rStorage, const String& rName ) : + mbStatus ( sal_False ), + mnByteOrder ( 0xfffe ), + mnFormat ( 0 ), + mnVersionLo ( 4 ), + mnVersionHi ( 2 ) +{ + if ( rStorage.IsStream( rName ) ) + { + mpSvStream = rStorage.OpenSotStream( rName, STREAM_STD_READ ); + if ( mpSvStream ) + { + mpSvStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); + memset( mApplicationCLSID, 0, 16 ); + mbStatus = sal_True; + } + } +} + +// ----------------------------------------------------------------------- + +void PropRead::AddSection( Section& rSection ) +{ + Insert( new Section( rSection ), LIST_APPEND ); +} + +// ----------------------------------------------------------------------- + +const Section* PropRead::GetSection( const sal_uInt8* pFMTID ) +{ + Section* pSection; + + for ( pSection = (Section*)First(); pSection; pSection = (Section*)Next() ) + { + if ( memcmp( pSection->GetFMTID(), pFMTID, 16 ) == 0 ) + break; + } + return pSection; +} + +// ----------------------------------------------------------------------- + +PropRead::~PropRead() +{ + for ( Section* pSection = (Section*)First(); pSection; pSection = (Section*)Next() ) + delete pSection; +} + +// ----------------------------------------------------------------------- + +void PropRead::Read() +{ + for ( Section* pSection = (Section*)First(); pSection; pSection = (Section*)Next() ) + delete pSection; + Clear(); + if ( mbStatus ) + { + sal_uInt32 nSections; + sal_uInt32 nSectionOfs; + sal_uInt32 nCurrent; + *mpSvStream >> mnByteOrder >> mnFormat >> mnVersionLo >> mnVersionHi; + if ( mnByteOrder == 0xfffe ) + { + sal_uInt8* pSectCLSID = new sal_uInt8[ 16 ]; + mpSvStream->Read( mApplicationCLSID, 16 ); + *mpSvStream >> nSections; + if ( nSections > 2 ) // sj: PowerPoint documents are containing max 2 sections + { + mbStatus = sal_False; + } + else for ( sal_uInt32 i = 0; i < nSections; i++ ) + { + mpSvStream->Read( pSectCLSID, 16 ); + *mpSvStream >> nSectionOfs; + nCurrent = mpSvStream->Tell(); + mpSvStream->Seek( nSectionOfs ); + Section aSection( pSectCLSID ); + aSection.Read( mpSvStream ); + AddSection( aSection ); + mpSvStream->Seek( nCurrent ); + } + delete[] pSectCLSID; + } + } +} + +// ----------------------------------------------------------------------- + +PropRead& PropRead::operator=( PropRead& rPropRead ) +{ + Section* pSection; + + if ( this != &rPropRead ) + { + mbStatus = rPropRead.mbStatus; + mpSvStream = rPropRead.mpSvStream; + + mnByteOrder = rPropRead.mnByteOrder; + mnFormat = rPropRead.mnFormat; + mnVersionLo = rPropRead.mnVersionLo; + mnVersionHi = rPropRead.mnVersionHi; + memcpy( mApplicationCLSID, rPropRead.mApplicationCLSID, 16 ); + + for ( pSection = (Section*)First(); pSection; pSection = (Section*)Next() ) + delete pSection; + Clear(); + for ( pSection = (Section*)rPropRead.First(); pSection; pSection = (Section*)rPropRead.Next() ) + Insert( new Section( *pSection ), LIST_APPEND ); + } + return *this; +} diff --git a/sd/source/filter/ppt/propread.hxx b/sd/source/filter/ppt/propread.hxx new file mode 100644 index 000000000000..cbb81b8cad1c --- /dev/null +++ b/sd/source/filter/ppt/propread.hxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PROPREAD_HXX_ +#define _PROPREAD_HXX_ + +#include <tools/solar.h> +#include <sot/storage.hxx> +#include <tools/gen.hxx> +#include <tools/list.hxx> +#include <tools/stream.hxx> +#include <tools/datetime.hxx> + +#include <tools/string.hxx> + +// SummaryInformation +#define PID_TITLE 0x02 +#define PID_SUBJECT 0x03 +#define PID_AUTHOR 0x04 +#define PID_KEYWORDS 0x05 +#define PID_COMMENTS 0x06 +#define PID_TEMPLATE 0x07 +#define PID_LASTAUTHOR 0x08 +#define PID_REVNUMBER 0x09 +#define PID_EDITTIME 0x0a +#define PID_LASTPRINTED_DTM 0x0b +#define PID_CREATE_DTM 0x0c +#define PID_LASTSAVED_DTM 0x0d + +// DocumentSummaryInformation +#define PID_CATEGORY 0x02 +#define PID_PRESFORMAT 0x03 +#define PID_BYTECOUNT 0x04 +#define PID_LINECOUNT 0x05 +#define PID_PARACOUNT 0x06 +#define PID_SLIDECOUNT 0x07 +#define PID_NOTECOUNT 0x08 +#define PID_HIDDENCOUNT 0x09 +#define PID_MMCLIPCOUNT 0x0a +#define PID_SCALE 0x0b +#define PID_HEADINGPAIR 0x0c +#define PID_DOCPARTS 0x0d +#define PID_MANAGER 0x0e +#define PID_COMPANY 0x0f +#define PID_LINKSDIRTY 0x10 + +#define VT_EMPTY 0 +#define VT_NULL 1 +#define VT_I2 2 +#define VT_I4 3 +#define VT_R4 4 +#define VT_R8 5 +#define VT_CY 6 +#define VT_DATE 7 +#define VT_BSTR 8 +#define VT_UI4 9 +#define VT_ERROR 10 +#define VT_BOOL 11 +#define VT_VARIANT 12 +#define VT_DECIMAL 14 +#define VT_I1 16 +#define VT_UI1 17 +#define VT_UI2 18 +#define VT_I8 20 +#define VT_UI8 21 +#define VT_INT 22 +#define VT_UINT 23 +#define VT_LPSTR 30 +#define VT_LPWSTR 31 +#define VT_FILETIME 64 +#define VT_BLOB 65 +#define VT_STREAM 66 +#define VT_STORAGE 67 +#define VT_STREAMED_OBJECT 68 +#define VT_STORED_OBJECT 69 +#define VT_BLOB_OBJECT 70 +#define VT_CF 71 +#define VT_CLSID 72 +#define VT_VECTOR 0x1000 +#define VT_ARRAY 0x2000 +#define VT_BYREF 0x4000 +#define VT_TYPEMASK 0xFFF + +// ------------------------------------------------------------------------ + +class PropItem : public SvMemoryStream +{ + sal_uInt16 mnTextEnc; + + public : + PropItem(){}; + void Clear(); + + void SetTextEncoding( sal_uInt16 nTextEnc ){ mnTextEnc = nTextEnc; }; + sal_Bool Read( String& rString, sal_uInt32 nType = VT_EMPTY, sal_Bool bDwordAlign = sal_True ); + PropItem& operator=( PropItem& rPropItem ); + + using SvStream::Read; +}; + +// ------------------------------------------------------------------------ + +class Dictionary : protected List +{ + friend class Section; + + void AddProperty( UINT32 nId, const String& rString ); + + public : + Dictionary(){}; + ~Dictionary(); + Dictionary& operator=( Dictionary& rDictionary ); + UINT32 GetProperty( const String& rPropName ); +}; + +// ------------------------------------------------------------------------ + +class Section : private List +{ + sal_uInt16 mnTextEnc; + + protected: + + BYTE aFMTID[ 16 ]; + + void AddProperty( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize ); + + public: + Section( const sal_uInt8* pFMTID ); + Section( Section& rSection ); + ~Section(); + + Section& operator=( Section& rSection ); + sal_Bool GetProperty( sal_uInt32 nId, PropItem& rPropItem ); + sal_Bool GetDictionary( Dictionary& rDict ); + const sal_uInt8* GetFMTID() const { return aFMTID; }; + void Read( SvStorageStream* pStrm ); +}; + +// ------------------------------------------------------------------------ + +class PropRead : private List +{ + sal_Bool mbStatus; + SvStorageStream* mpSvStream; + + sal_uInt16 mnByteOrder; + sal_uInt16 mnFormat; + sal_uInt16 mnVersionLo; + sal_uInt16 mnVersionHi; + sal_uInt8 mApplicationCLSID[ 16 ]; + + void AddSection( Section& rSection ); + + public: + PropRead( SvStorage& rSvStorage, const String& rName ); + ~PropRead(); + + PropRead& operator=( PropRead& rPropRead ); + const Section* GetSection( const BYTE* pFMTID ); + sal_Bool IsValid() const { return mbStatus; }; + void Read(); +}; + + +#endif + |