/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * 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 "fuoaprms.hxx"

#include "sdattr.hxx"
#include <svx/svdpagv.hxx>
#include <editeng/colritem.hxx>
#include <svx/svdundo.hxx>
#include <vcl/group.hxx>
#include <vcl/fixed.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/request.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/msgbox.hxx>
#include <svl/aeitem.hxx>
#include "svx/xtable.hxx"

#include "strings.hrc"
#include "glob.hrc"
#include "drawdoc.hxx"
#include "ViewShell.hxx"
#include "anminfo.hxx"
#include "unoaprms.hxx"                 // Undo-Action
#include "sdundogr.hxx"                 // Undo Gruppe
#include "View.hxx"
#include "sdabstdlg.hxx"
#include "sdresid.hxx"
#include <vcl/salbtype.hxx>		// FRound
#include <basegfx/polygon/b2dpolygon.hxx>

using namespace ::com::sun::star;

namespace sd {

TYPEINIT1( FuObjectAnimationParameters, FuPoor );

#define ATTR_MISSING    0       // Attribut nicht verfuegbar
#define ATTR_MIXED      1       // Attribut uneindeutig (bei Mehrfachselektion)
#define ATTR_SET        2       // Attribut eindeutig

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuObjectAnimationParameters::FuObjectAnimationParameters (
    ViewShell*	 pViewSh,
    ::sd::Window*		 pWin,
    ::sd::View*		 pView,
    SdDrawDocument* pDoc,
    SfxRequest&	 rReq)
    : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
{
}

FunctionReference FuObjectAnimationParameters::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
{
    FunctionReference xFunc( new FuObjectAnimationParameters( pViewSh, pWin, pView, pDoc, rReq ) );
    xFunc->DoExecute(rReq);
    return xFunc;
}

void FuObjectAnimationParameters::DoExecute( SfxRequest& rReq )
{
    SfxUndoManager* pUndoMgr = mpViewShell->GetViewFrame()->GetObjectShell()->GetUndoManager();

    const SdrMarkList& rMarkList  = mpView->GetMarkedObjectList();
    ULONG		 nCount 	= rMarkList.GetMarkCount();
    ULONG		 nObject	= 0;

    short nAnimationSet     = ATTR_MISSING;
    short nEffectSet        = ATTR_MISSING;
    short nTextEffectSet    = ATTR_MISSING;
    short nSpeedSet         = ATTR_MISSING;
    short nFadeColorSet     = ATTR_MISSING;
    short nFadeOutSet       = ATTR_MISSING;
    short nInvisibleSet     = ATTR_MISSING;
    short nSoundOnSet       = ATTR_MISSING;
    short nSoundFileSet     = ATTR_MISSING;
    short nPlayFullSet      = ATTR_MISSING;
    short nClickActionSet   = ATTR_MISSING;
    short nBookmarkSet      = ATTR_MISSING;

    short nSecondEffectSet      = ATTR_MISSING;
    short nSecondSpeedSet       = ATTR_MISSING;
    short nSecondSoundOnSet     = ATTR_MISSING;
    short nSecondPlayFullSet    = ATTR_MISSING;



//    BOOL bDontKnow   = FALSE;

                                    // defaulten (fuer Undo-Aktion)
    presentation::AnimationEffect eEffect         = presentation::AnimationEffect_NONE;
    presentation::AnimationEffect eTextEffect     = presentation::AnimationEffect_NONE;
    presentation::AnimationSpeed  eSpeed          = presentation::AnimationSpeed_MEDIUM;
    BOOL            bActive         = FALSE;
    BOOL            bFadeOut        = FALSE;
    Color           aFadeColor      = COL_LIGHTGRAY;
    BOOL            bInvisible      = FALSE;
    BOOL            bSoundOn        = FALSE;
    String          aSound;
    BOOL            bPlayFull       = FALSE;
    presentation::ClickAction     eClickAction    = presentation::ClickAction_NONE;
    String          aBookmark;

    presentation::AnimationEffect eSecondEffect   = presentation::AnimationEffect_NONE;
    presentation::AnimationSpeed  eSecondSpeed    = presentation::AnimationSpeed_MEDIUM;
    BOOL            bSecondSoundOn  = FALSE;
    BOOL            bSecondPlayFull = FALSE;


    SdAnimationInfo* pInfo;
    SdrMark* pMark;

    // das erste Objekt untersuchen
    pMark = rMarkList.GetMark(0);
    pInfo = mpDoc->GetAnimationInfo(pMark->GetMarkedSdrObj());
    if( pInfo )
    {
        bActive             = pInfo->mbActive;
        nAnimationSet       = ATTR_SET;

        eEffect             = pInfo->meEffect;
        nEffectSet          = ATTR_SET;

        eTextEffect         = pInfo->meTextEffect;
        nTextEffectSet      = ATTR_SET;

        eSpeed              = pInfo->meSpeed;
        nSpeedSet           = ATTR_SET;

        bFadeOut            = pInfo->mbDimPrevious;
        nFadeOutSet         = ATTR_SET;

        aFadeColor          = pInfo->maDimColor;
        nFadeColorSet       = ATTR_SET;

        bInvisible          = pInfo->mbDimHide;
        nInvisibleSet       = ATTR_SET;

        bSoundOn            = pInfo->mbSoundOn;
        nSoundOnSet         = ATTR_SET;

        aSound              = pInfo->maSoundFile;
        nSoundFileSet       = ATTR_SET;

        bPlayFull           = pInfo->mbPlayFull;
        nPlayFullSet        = ATTR_SET;

        eClickAction        = pInfo->meClickAction;
        nClickActionSet     = ATTR_SET;

        aBookmark           = pInfo->GetBookmark();
        nBookmarkSet        = ATTR_SET;

        eSecondEffect       = pInfo->meSecondEffect;
        nSecondEffectSet    = ATTR_SET;

        eSecondSpeed        = pInfo->meSecondSpeed;
        nSecondSpeedSet     = ATTR_SET;

        bSecondSoundOn      = pInfo->mbSecondSoundOn;
        nSecondSoundOnSet   = ATTR_SET;

        bSecondPlayFull     = pInfo->mbSecondPlayFull;
        nSecondPlayFullSet  = ATTR_SET;
    }

    // ggfs. weitere Objekte untersuchen
    for( nObject = 1; nObject < nCount; nObject++ )
    {
        pMark = rMarkList.GetMark( nObject );
        SdrObject* pObject = pMark->GetMarkedSdrObj();
        pInfo = mpDoc->GetAnimationInfo(pObject);
        if( pInfo )
        {
            if( bActive != pInfo->mbActive )
                nAnimationSet = ATTR_MIXED;

            if( eEffect != pInfo->meEffect )
                nEffectSet = ATTR_MIXED;

            if( eTextEffect != pInfo->meTextEffect )
                nTextEffectSet = ATTR_MIXED;

            if( eSpeed != pInfo->meSpeed )
                nSpeedSet = ATTR_MIXED;

            if( bFadeOut != pInfo->mbDimPrevious )
                nFadeOutSet = ATTR_MIXED;

            if( aFadeColor != pInfo->maDimColor )
                nFadeColorSet = ATTR_MIXED;

            if( bInvisible != pInfo->mbDimHide )
                nInvisibleSet = ATTR_MIXED;

            if( bSoundOn != pInfo->mbSoundOn )
                nSoundOnSet = ATTR_MIXED;

            if( aSound != pInfo->maSoundFile )
                nSoundFileSet = ATTR_MIXED;

            if( bPlayFull != pInfo->mbPlayFull )
                nPlayFullSet = ATTR_MIXED;

            if( eClickAction != pInfo->meClickAction )
                nClickActionSet = ATTR_MIXED;

            if( aBookmark != pInfo->GetBookmark() )
                nBookmarkSet = ATTR_MIXED;

            if( eSecondEffect != pInfo->meSecondEffect )
                nSecondEffectSet = ATTR_MIXED;

            if( eSecondSpeed != pInfo->meSecondSpeed )
                nSecondSpeedSet = ATTR_MIXED;

            if( bSecondSoundOn != pInfo->mbSecondSoundOn )
                nSecondSoundOnSet = ATTR_MIXED;

            if( bSecondPlayFull != pInfo->mbSecondPlayFull )
                nSecondPlayFullSet = ATTR_MIXED;
        }
        else
        {
            if (nAnimationSet == ATTR_SET && bActive == TRUE)
                nAnimationSet = ATTR_MIXED;

            if (nEffectSet == ATTR_SET && eEffect != presentation::AnimationEffect_NONE)
                nEffectSet = ATTR_MIXED;

            if (nTextEffectSet == ATTR_SET && eTextEffect != presentation::AnimationEffect_NONE)
                nTextEffectSet = ATTR_MIXED;

            if (nSpeedSet == ATTR_SET)
                nSpeedSet = ATTR_MIXED;

            if (nFadeOutSet == ATTR_SET && bFadeOut == TRUE)
                nFadeOutSet = ATTR_MIXED;

            if (nFadeColorSet == ATTR_SET)
                nFadeColorSet = ATTR_MIXED;

            if (nInvisibleSet == ATTR_SET && bInvisible == TRUE)
                nInvisibleSet = ATTR_MIXED;

            if (nSoundOnSet == ATTR_SET && bSoundOn == TRUE)
                nSoundOnSet = ATTR_MIXED;

            if (nSoundFileSet == ATTR_SET)
                nSoundFileSet = ATTR_MIXED;

            if (nPlayFullSet == ATTR_SET && bPlayFull == TRUE)
                nPlayFullSet = ATTR_MIXED;

            if (nClickActionSet == ATTR_SET && eClickAction != presentation::ClickAction_NONE)
                nClickActionSet = ATTR_MIXED;

            if (nBookmarkSet == ATTR_SET)
                nBookmarkSet = ATTR_MIXED;

            if (nSecondEffectSet == ATTR_SET && eSecondEffect != presentation::AnimationEffect_NONE)
                nSecondEffectSet = ATTR_MIXED;

            if (nSecondSpeedSet == ATTR_SET)
                nSecondSpeedSet = ATTR_MIXED;

            if (nSecondSoundOnSet == ATTR_SET && bSecondSoundOn == TRUE)
                nSecondSoundOnSet = ATTR_MIXED;

            if (nSecondPlayFullSet == ATTR_SET && bSecondPlayFull == TRUE)
                nSecondPlayFullSet = ATTR_MIXED;
        }
    }

    // Genau zwei Objekte mit Pfadeffekt? Dann gilt nur die Animationsinfo
    // am bewegten Objekt.
    if (nCount == 2)
    {
        SdrObject* pObject1 = rMarkList.GetMark(0)->GetMarkedSdrObj();
        SdrObject* pObject2 = rMarkList.GetMark(1)->GetMarkedSdrObj();
        SdrObjKind eKind1   = (SdrObjKind)pObject1->GetObjIdentifier();
        SdrObjKind eKind2   = (SdrObjKind)pObject2->GetObjIdentifier();
        SdAnimationInfo* pInfo1 = mpDoc->GetAnimationInfo(pObject1);
        SdAnimationInfo* pInfo2 = mpDoc->GetAnimationInfo(pObject2);
        pInfo  = NULL;

        if (pObject1->GetObjInventor() == SdrInventor &&
            ((eKind1 == OBJ_LINE) ||                        // 2-Punkt-Linie
             (eKind1 == OBJ_PLIN) ||                        // Polygon
             (eKind1 == OBJ_PATHLINE))                &&    // Bezier-Kurve
             (pInfo2 && pInfo2->meEffect == presentation::AnimationEffect_PATH))
        {
            pInfo = pInfo2;
        }

        if (pObject2->GetObjInventor() == SdrInventor &&
            ((eKind2 == OBJ_LINE) ||                        // 2-Punkt-Linie
             (eKind2 == OBJ_PLIN) ||                        // Polygon
             (eKind2 == OBJ_PATHLINE))                &&    // Bezier-Kurve
            (pInfo1 && pInfo1->meEffect == presentation::AnimationEffect_PATH))
        {
            pInfo = pInfo1;
        }

        if (pInfo)
        {
            bActive         = pInfo->mbActive;          nAnimationSet       = ATTR_SET;
            eEffect         = pInfo->meEffect;          nEffectSet          = ATTR_SET;
            eTextEffect     = pInfo->meTextEffect;      nTextEffectSet      = ATTR_SET;
            eSpeed          = pInfo->meSpeed;           nSpeedSet           = ATTR_SET;
            bFadeOut        = pInfo->mbDimPrevious;     nFadeOutSet         = ATTR_SET;
            aFadeColor      = pInfo->maDimColor;        nFadeColorSet       = ATTR_SET;
            bInvisible      = pInfo->mbDimHide;         nInvisibleSet       = ATTR_SET;
            bSoundOn        = pInfo->mbSoundOn;         nSoundOnSet         = ATTR_SET;
            aSound          = pInfo->maSoundFile;       nSoundFileSet       = ATTR_SET;
            bPlayFull       = pInfo->mbPlayFull;        nPlayFullSet        = ATTR_SET;
            eClickAction    = pInfo->meClickAction;     nClickActionSet     = ATTR_SET;
            aBookmark       = pInfo->GetBookmark();     nBookmarkSet        = ATTR_SET;
            eSecondEffect   = pInfo->meSecondEffect;    nSecondEffectSet    = ATTR_SET;
            eSecondSpeed    = pInfo->meSecondSpeed;     nSecondSpeedSet     = ATTR_SET;
            bSecondSoundOn  = pInfo->mbSecondSoundOn;   nSecondSoundOnSet   = ATTR_SET;
            bSecondPlayFull = pInfo->mbSecondPlayFull;  nSecondPlayFullSet  = ATTR_SET;
        }
    }

    const SfxItemSet* pArgs = rReq.GetArgs();

    if(!pArgs)
    {
        // ItemSet fuer Dialog fuellen
        SfxItemSet aSet(mpDoc->GetPool(), ATTR_ANIMATION_START, ATTR_ACTION_END);

        // das Set besetzen
        if (nAnimationSet == ATTR_SET)
            aSet.Put( SfxBoolItem( ATTR_ANIMATION_ACTIVE, bActive));
        else if (nAnimationSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ANIMATION_ACTIVE);
        else
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_ACTIVE, FALSE));

        if (nEffectSet == ATTR_SET)
            aSet.Put(SfxAllEnumItem(ATTR_ANIMATION_EFFECT, (USHORT)eEffect));
        else if (nEffectSet == ATTR_MIXED)
            aSet.InvalidateItem( ATTR_ANIMATION_EFFECT );
        else
            aSet.Put(SfxAllEnumItem(ATTR_ANIMATION_EFFECT, presentation::AnimationEffect_NONE));

        if (nTextEffectSet == ATTR_SET)
            aSet.Put(SfxAllEnumItem(ATTR_ANIMATION_TEXTEFFECT, (USHORT)eTextEffect));
        else if (nTextEffectSet == ATTR_MIXED)
            aSet.InvalidateItem( ATTR_ANIMATION_TEXTEFFECT );
        else
            aSet.Put(SfxAllEnumItem(ATTR_ANIMATION_TEXTEFFECT, presentation::AnimationEffect_NONE));

        if (nSpeedSet == ATTR_SET)
            aSet.Put(SfxAllEnumItem(ATTR_ANIMATION_SPEED, (USHORT)eSpeed));
        else
            aSet.InvalidateItem(ATTR_ANIMATION_SPEED);

        if (nFadeOutSet == ATTR_SET)
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_FADEOUT, bFadeOut));
        else if (nFadeOutSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ANIMATION_FADEOUT);
        else
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_FADEOUT, FALSE));

        if (nFadeColorSet == ATTR_SET)
            aSet.Put(SvxColorItem(aFadeColor, ATTR_ANIMATION_COLOR));
        else if (nFadeColorSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ANIMATION_COLOR);
        else
            aSet.Put(SvxColorItem(RGB_Color(COL_LIGHTGRAY), ATTR_ANIMATION_COLOR));

        if (nInvisibleSet == ATTR_SET)
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_INVISIBLE, bInvisible));
        else if (nInvisibleSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ANIMATION_INVISIBLE);
        else
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_INVISIBLE, FALSE));

        if (nSoundOnSet == ATTR_SET)
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_SOUNDON, bSoundOn));
        else if (nSoundOnSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ANIMATION_SOUNDON);
        else
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_SOUNDON, FALSE));

        if (nSoundFileSet == ATTR_SET)
            aSet.Put(SfxStringItem(ATTR_ANIMATION_SOUNDFILE, aSound));
        else
            aSet.InvalidateItem(ATTR_ANIMATION_SOUNDFILE);

        if (nPlayFullSet == ATTR_SET)
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_PLAYFULL, bPlayFull));
        else if (nPlayFullSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ANIMATION_PLAYFULL);
        else
            aSet.Put(SfxBoolItem(ATTR_ANIMATION_PLAYFULL, FALSE));

        if (nClickActionSet == ATTR_SET)
            aSet.Put(SfxAllEnumItem(ATTR_ACTION, (USHORT)eClickAction));
        else if (nClickActionSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ACTION);
        else
            aSet.Put(SfxAllEnumItem(ATTR_ACTION, presentation::ClickAction_NONE));

        if (nBookmarkSet == ATTR_SET)
            aSet.Put(SfxStringItem(ATTR_ACTION_FILENAME, aBookmark));
        else
            aSet.InvalidateItem(ATTR_ACTION_FILENAME);

        if (nSecondEffectSet == ATTR_SET)
            aSet.Put(SfxAllEnumItem(ATTR_ACTION_EFFECT, (USHORT)eSecondEffect));
        else if (nSecondEffectSet == ATTR_MIXED)
            aSet.InvalidateItem( ATTR_ACTION_EFFECT );
        else
            aSet.Put(SfxAllEnumItem(ATTR_ACTION_EFFECT, presentation::AnimationEffect_NONE));

        if (nSecondSpeedSet == ATTR_SET)
            aSet.Put(SfxAllEnumItem(ATTR_ACTION_EFFECTSPEED, (USHORT)eSecondSpeed));
        else
            aSet.InvalidateItem(ATTR_ACTION_EFFECTSPEED);

        if (nSecondSoundOnSet == ATTR_SET)
            aSet.Put(SfxBoolItem(ATTR_ACTION_SOUNDON, bSecondSoundOn));
        else if (nSecondSoundOnSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ACTION_SOUNDON);
        else
            aSet.Put(SfxBoolItem(ATTR_ACTION_SOUNDON, FALSE));

        if (nSecondPlayFullSet == ATTR_SET)
            aSet.Put(SfxBoolItem(ATTR_ACTION_PLAYFULL, bSecondPlayFull));
        else if (nPlayFullSet == ATTR_MIXED)
            aSet.InvalidateItem(ATTR_ACTION_PLAYFULL);
        else
            aSet.Put(SfxBoolItem(ATTR_ACTION_PLAYFULL, FALSE));

        SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
        SfxAbstractDialog* pDlg = pFact ? pFact->CreatSdActionDialog( NULL, &aSet, mpView ) : 0;

        USHORT nResult = pDlg ? pDlg->Execute() : RET_CANCEL;

        if( nResult == RET_OK )
        {
            rReq.Done( *( pDlg->GetOutputItemSet() ) );
            pArgs = rReq.GetArgs();
        }

        delete pDlg;

        if( nResult != RET_OK )
            return;
    }

    // Auswertung des ItemSets
    if (pArgs->GetItemState(ATTR_ANIMATION_ACTIVE) == SFX_ITEM_SET)
    {
        bActive = ((SfxBoolItem&)pArgs->Get(ATTR_ANIMATION_ACTIVE)).GetValue();
        nAnimationSet = ATTR_SET;
    }
    else
        nAnimationSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_EFFECT) == SFX_ITEM_SET)
    {
        eEffect = (presentation::AnimationEffect)((SfxAllEnumItem&) pArgs->
                    Get(ATTR_ANIMATION_EFFECT)).GetValue();
        nEffectSet = ATTR_SET;
    }
    else
        nEffectSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_TEXTEFFECT) == SFX_ITEM_SET)
    {
        eTextEffect = (presentation::AnimationEffect)((SfxAllEnumItem&) pArgs->
                        Get(ATTR_ANIMATION_TEXTEFFECT)).GetValue();
        nTextEffectSet = ATTR_SET;
    }
    else
        nTextEffectSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_SPEED) == SFX_ITEM_SET)
    {
        eSpeed  = (presentation::AnimationSpeed)((SfxAllEnumItem&) pArgs->
                    Get(ATTR_ANIMATION_SPEED)).GetValue();
        nSpeedSet = ATTR_SET;
    }
    else
        nSpeedSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_FADEOUT) == SFX_ITEM_SET)
    {
        bFadeOut = ((SfxBoolItem&)pArgs->Get(ATTR_ANIMATION_FADEOUT)).GetValue();
        nFadeOutSet = ATTR_SET;
    }
    else
        nFadeOutSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_INVISIBLE) == SFX_ITEM_SET)
    {
        bInvisible = ((SfxBoolItem&)pArgs->Get(ATTR_ANIMATION_INVISIBLE)).GetValue();
        nInvisibleSet = ATTR_SET;
    }
    else
        nInvisibleSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_SOUNDON) == SFX_ITEM_SET)
    {
        bSoundOn = ((SfxBoolItem&)pArgs->Get(ATTR_ANIMATION_SOUNDON)).GetValue();
        nSoundOnSet = ATTR_SET;
    }
    else
        nSoundOnSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_SOUNDFILE) == SFX_ITEM_SET)
    {
        aSound =  ((SfxStringItem&)pArgs->Get(ATTR_ANIMATION_SOUNDFILE)).GetValue();
        nSoundFileSet = ATTR_SET;
    }
    else
        nSoundFileSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_COLOR) == SFX_ITEM_SET)
    {
        aFadeColor = ((SvxColorItem&)pArgs->Get(ATTR_ANIMATION_COLOR)).GetValue();
        nFadeColorSet = ATTR_SET;
    }
    else
        nFadeColorSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ANIMATION_PLAYFULL) == SFX_ITEM_SET)
    {
        bPlayFull = ((SfxBoolItem&)pArgs->Get(ATTR_ANIMATION_PLAYFULL)).GetValue();
        nPlayFullSet = ATTR_SET;
    }
    else
        nPlayFullSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ACTION) == SFX_ITEM_SET)
    {
        eClickAction = (presentation::ClickAction)((SfxAllEnumItem&)pArgs->
                    Get(ATTR_ACTION)).GetValue();
        nClickActionSet = ATTR_SET;
    }
    else
        nClickActionSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ACTION_FILENAME) == SFX_ITEM_SET)
    {
        aBookmark = ((SfxStringItem&)pArgs->
                        Get(ATTR_ACTION_FILENAME)).GetValue();
        nBookmarkSet = ATTR_SET;
    }
    else
        nBookmarkSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ACTION_EFFECT) == SFX_ITEM_SET)
    {
        eSecondEffect = (presentation::AnimationEffect)((SfxAllEnumItem&) pArgs->
                    Get(ATTR_ACTION_EFFECT)).GetValue();
        nSecondEffectSet = ATTR_SET;
    }
    else
        nSecondEffectSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ACTION_EFFECTSPEED) == SFX_ITEM_SET)
    {
        eSecondSpeed  = (presentation::AnimationSpeed)((SfxAllEnumItem&) pArgs->
                    Get(ATTR_ACTION_EFFECTSPEED)).GetValue();
        nSecondSpeedSet = ATTR_SET;
    }
    else
        nSecondSpeedSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ACTION_SOUNDON) == SFX_ITEM_SET)
    {
        bSecondSoundOn = ((SfxBoolItem&)pArgs->Get(ATTR_ACTION_SOUNDON)).GetValue();
        nSecondSoundOnSet = ATTR_SET;
    }
    else
        nSecondSoundOnSet = ATTR_MISSING;

    if (pArgs->GetItemState(ATTR_ACTION_PLAYFULL) == SFX_ITEM_SET)
    {
        bSecondPlayFull = ((SfxBoolItem&)pArgs->Get(ATTR_ACTION_PLAYFULL)).GetValue();
        nSecondPlayFullSet = ATTR_SET;
    }
    else
        nSecondPlayFullSet = ATTR_MISSING;

    // Wenn irgendwelche Attribute ausgewaehlt wurden
    if (nEffectSet         == ATTR_SET  ||
        nTextEffectSet     == ATTR_SET  ||
        nSpeedSet          == ATTR_SET  ||
        nAnimationSet      == ATTR_SET  ||
        nFadeOutSet        == ATTR_SET  ||
        nFadeColorSet      == ATTR_SET  ||
        nInvisibleSet      == ATTR_SET  ||
        nSoundOnSet        == ATTR_SET  ||
        nSoundFileSet      == ATTR_SET  ||
        nPlayFullSet       == ATTR_SET  ||
        nClickActionSet    == ATTR_SET  ||
        nBookmarkSet       == ATTR_SET  ||
        nSecondEffectSet   == ATTR_SET  ||
        nSecondSpeedSet    == ATTR_SET  ||
        nSecondSoundOnSet  == ATTR_SET  ||
        nSecondPlayFullSet == ATTR_SET)
    {
        // String fuer Undo-Group und List-Action
        String aComment(SdResId(STR_UNDO_ANIMATION));

        // bei 'an Kurve entlang' gibt's noch eine extra UndoAction, darum
        // hier klammern
        pUndoMgr->EnterListAction(aComment, aComment);

        // Undo Gruppe erzeugen
        SdUndoGroup* pUndoGroup = new SdUndoGroup(mpDoc);
        pUndoGroup->SetComment(aComment);


        // fuer den Pfad-Effekt einige Dinge merken
        SdrObject*  pRunningObj = NULL;
        SdrPathObj* pPath       = NULL;
        if (eEffect == presentation::AnimationEffect_PATH && nEffectSet == ATTR_SET)
        {
            DBG_ASSERT(nCount == 2, "dieser Effekt braucht genau 2 selektierte Objekte");
            SdrObject* pObject1 = rMarkList.GetMark(0)->GetMarkedSdrObj();
            SdrObject* pObject2 = rMarkList.GetMark(1)->GetMarkedSdrObj();
            SdrObjKind eKind1   = (SdrObjKind)pObject1->GetObjIdentifier();
            SdrObjKind eKind2   = (SdrObjKind)pObject2->GetObjIdentifier();

            if (pObject1->GetObjInventor() == SdrInventor &&
                ((eKind1 == OBJ_LINE) ||        // 2-Punkt-Linie
                 (eKind1 == OBJ_PLIN) ||        // Polygon
                 (eKind1 == OBJ_PATHLINE)))     // Bezier-Kurve
            {
                pPath = (SdrPathObj*)pObject1;
                pRunningObj = pObject2;
            }

            if (pObject2->GetObjInventor() == SdrInventor &&
                ((eKind2 == OBJ_LINE) ||        // 2-Punkt-Linie
                 (eKind2 == OBJ_PLIN) ||        // Polygon
                 (eKind2 == OBJ_PATHLINE)))     // Bezier-Kurve
            {
                pPath = (SdrPathObj*)pObject2;
                pRunningObj = pObject1;
            }

            DBG_ASSERT(pPath, "keine Kurve gefunden");


            // das laufende Objekt auf das Kurvenende schieben
            Rectangle aCurRect(pRunningObj->GetLogicRect());
            Point     aCurCenter(aCurRect.Center());
            const ::basegfx::B2DPolyPolygon& rPolyPolygon = pPath->GetPathPoly();
            sal_uInt32 nNoOfPolygons(rPolyPolygon.count());
            const ::basegfx::B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(nNoOfPolygons - 1L));
            sal_uInt32 nPoints(aPolygon.count());
            const ::basegfx::B2DPoint aNewB2DCenter(aPolygon.getB2DPoint(nPoints - 1L));
            const Point aNewCenter(FRound(aNewB2DCenter.getX()), FRound(aNewB2DCenter.getY()));
            Size aDistance(aNewCenter.X() - aCurCenter.X(), aNewCenter.Y() - aCurCenter.Y());
            pRunningObj->Move(aDistance);

            pUndoMgr->AddUndoAction(mpDoc->GetSdrUndoFactory().CreateUndoMoveObject( *pRunningObj, aDistance));
        }

        for (nObject = 0; nObject < nCount; nObject++)
        {
            SdrObject* pObject = rMarkList.GetMark(nObject)->GetMarkedSdrObj();

            pInfo = mpDoc->GetAnimationInfo(pObject);

            BOOL bCreated = FALSE;
            if( !pInfo )
            {
                pInfo = SdDrawDocument::GetShapeUserData(*pObject,true);
                bCreated = TRUE;
            }

            // das Pfadobjekt fuer 'an Kurve entlang'?
            if (eEffect == presentation::AnimationEffect_PATH && pObject == pPath)
            {
                SdAnimationPrmsUndoAction* pAction = new SdAnimationPrmsUndoAction
                                                (mpDoc, pObject, bCreated);
                pAction->SetActive(pInfo->mbActive, pInfo->mbActive);
                pAction->SetEffect(pInfo->meEffect, pInfo->meEffect);
                pAction->SetTextEffect(pInfo->meTextEffect, pInfo->meTextEffect);
                pAction->SetSpeed(pInfo->meSpeed, pInfo->meSpeed);
                pAction->SetDim(pInfo->mbDimPrevious, pInfo->mbDimPrevious);
                pAction->SetDimColor(pInfo->maDimColor, pInfo->maDimColor);
                pAction->SetDimHide(pInfo->mbDimHide, pInfo->mbDimHide);
                pAction->SetSoundOn(pInfo->mbSoundOn, pInfo->mbSoundOn);
                pAction->SetSound(pInfo->maSoundFile, pInfo->maSoundFile);
                pAction->SetPlayFull(pInfo->mbPlayFull, pInfo->mbPlayFull);
//				pAction->SetPathObj(pInfo->mpPathObj, pInfo->mpPathObj);
                pAction->SetClickAction(pInfo->meClickAction, pInfo->meClickAction);
                pAction->SetBookmark(pInfo->GetBookmark(), pInfo->GetBookmark());
//				pAction->SetInvisibleInPres(pInfo->mbInvisibleInPresentation, TRUE);
                pAction->SetVerb(pInfo->mnVerb, pInfo->mnVerb);
                pAction->SetSecondEffect(pInfo->meSecondEffect, pInfo->meSecondEffect);
                pAction->SetSecondSpeed(pInfo->meSecondSpeed, pInfo->meSecondSpeed);
                pAction->SetSecondSoundOn(pInfo->mbSecondSoundOn, pInfo->mbSecondSoundOn);
                pAction->SetSecondPlayFull(pInfo->mbSecondPlayFull, pInfo->mbSecondPlayFull);
                pUndoGroup->AddAction(pAction);

//				pInfo->mbInvisibleInPresentation = TRUE;
            }
            else
            {

                // Undo-Action mit alten und neuen Groessen erzeugen
                SdAnimationPrmsUndoAction* pAction = new SdAnimationPrmsUndoAction
                                                (mpDoc, pObject, bCreated);
                pAction->SetActive(pInfo->mbActive, bActive);
                pAction->SetEffect(pInfo->meEffect, eEffect);
                pAction->SetTextEffect(pInfo->meTextEffect, eTextEffect);
                pAction->SetSpeed(pInfo->meSpeed, eSpeed);
                pAction->SetDim(pInfo->mbDimPrevious, bFadeOut);
                pAction->SetDimColor(pInfo->maDimColor, aFadeColor);
                pAction->SetDimHide(pInfo->mbDimHide, bInvisible);
                pAction->SetSoundOn(pInfo->mbSoundOn, bSoundOn);
                pAction->SetSound(pInfo->maSoundFile, aSound);
                pAction->SetPlayFull(pInfo->mbPlayFull, bPlayFull);
                pAction->SetPathObj(pInfo->mpPathObj, pPath);
                pAction->SetClickAction(pInfo->meClickAction, eClickAction);
                pAction->SetBookmark(pInfo->GetBookmark(), aBookmark);
//				pAction->SetInvisibleInPres(pInfo->mbInvisibleInPresentation,
//											pInfo->mbInvisibleInPresentation);
                pAction->SetVerb(pInfo->mnVerb, (USHORT)pInfo->GetBookmark().ToInt32() );
                pAction->SetSecondEffect(pInfo->meSecondEffect, eSecondEffect);
                pAction->SetSecondSpeed(pInfo->meSecondSpeed, eSecondSpeed);
                pAction->SetSecondSoundOn(pInfo->mbSecondSoundOn, bSecondSoundOn);
                pAction->SetSecondPlayFull(pInfo->mbSecondPlayFull,bSecondPlayFull);
                pUndoGroup->AddAction(pAction);

                // neue Werte am Infoblock des Objekts eintragen
                if (nAnimationSet == ATTR_SET)
                    pInfo->mbActive = bActive;

                if (nEffectSet == ATTR_SET)
                    pInfo->meEffect = eEffect;

                if (nTextEffectSet == ATTR_SET)
                    pInfo->meTextEffect = eTextEffect;

                if (nSpeedSet == ATTR_SET)
                    pInfo->meSpeed = eSpeed;

                if (nFadeOutSet == ATTR_SET)
                    pInfo->mbDimPrevious = bFadeOut;

                if (nFadeColorSet == ATTR_SET)
                    pInfo->maDimColor = aFadeColor;

                if (nInvisibleSet == ATTR_SET)
                    pInfo->mbDimHide = bInvisible;

                if (nSoundOnSet == ATTR_SET)
                    pInfo->mbSoundOn = bSoundOn;

                if (nSoundFileSet == ATTR_SET)
                    pInfo->maSoundFile = aSound;

                if (nPlayFullSet == ATTR_SET)
                    pInfo->mbPlayFull = bPlayFull;

                if (nClickActionSet == ATTR_SET)
                    pInfo->meClickAction = eClickAction;

                if (nBookmarkSet == ATTR_SET)
                    pInfo->SetBookmark( aBookmark );

                if (nSecondEffectSet == ATTR_SET)
                    pInfo->meSecondEffect = eSecondEffect;

                if (nSecondSpeedSet == ATTR_SET)
                    pInfo->meSecondSpeed = eSecondSpeed;

                if (nSecondSoundOnSet == ATTR_SET)
                    pInfo->mbSecondSoundOn = bSecondSoundOn;

                if (nSecondPlayFullSet == ATTR_SET)
                    pInfo->mbSecondPlayFull = bSecondPlayFull;

                // noch ein paar Spezialitaeten
//				if (eEffect == presentation::AnimationEffect_PATH && nEffectSet == ATTR_SET)
//					pInfo->mSetPath(pPath);

                if (eClickAction == presentation::ClickAction_VERB)
                    pInfo->mnVerb = (USHORT)aBookmark.ToInt32();
            }
        }
        // Undo Gruppe dem Undo Manager uebergeben
        pUndoMgr->AddUndoAction(pUndoGroup);
        pUndoMgr->LeaveListAction();

        // Model geaendert
        mpDoc->SetChanged();
    }
    // sieht man nicht, also muss an den Bindings nicht invalidiert werden
}

} // end of namespace sd

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