/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"
#include <com/sun/star/presentation/EffectNodeType.hpp>
#include <com/sun/star/animations/Timing.hpp>
#include <com/sun/star/animations/Event.hpp>
#include <com/sun/star/animations/EventTrigger.hpp>
#include <com/sun/star/animations/AnimationFill.hpp>
#include <com/sun/star/presentation/TextAnimationType.hpp>
#include <com/sun/star/animations/ValuePair.hpp>
#include <com/sun/star/awt/FontSlant.hpp>
#include <com/sun/star/awt/FontWeight.hpp>
#include <com/sun/star/awt/FontUnderline.hpp>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/media/XManager.hpp>
#include <com/sun/star/media/XPlayer.hpp>

#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#include <boost/shared_ptr.hpp>
#endif

#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
#include <comphelper/processfactory.hxx>
#endif
#include <unotools/pathoptions.hxx>
#include <vcl/tabctrl.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/menubtn.hxx>
#include <vcl/svapp.hxx>
#include <vcl/fixed.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/field.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/decoview.hxx>
#include <vcl/combobox.hxx>
#include <vcl/menu.hxx>
#include <svtools/ctrlbox.hxx>
#include <svtools/ctrltool.hxx>
#include <sfx2/objsh.hxx>

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#include <svx/dialmgr.hxx>
#include <editeng/flstitem.hxx>
#include <svx/drawitem.hxx>

#include <svx/xtable.hxx>
#include <svx/gallery.hxx>

#ifndef _SVX_DIALOGS_HRC
#include <svx/dialogs.hrc>
#endif
#include "sdresid.hxx"

#include "glob.hrc"
#include "CustomAnimationDialog.hxx"
#ifndef _SD_CUSTOMANIMATIONDIALOG_HRC
#include "CustomAnimationDialog.hrc"
#endif
#ifndef _SD_CUSTOMANIMATION_HRC
#include "CustomAnimation.hrc"
#endif
#include "STLPropertySet.hxx"

#include <avmedia/mediawindow.hxx>

#include "filedlg.hxx"
#include "strings.hrc"
#include "helpids.h"

using namespace ::com::sun::star;
using namespace ::com::sun::star::animations;
using namespace ::com::sun::star::presentation;

using ::rtl::OUString;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::makeAny;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::drawing::XShape;
using ::com::sun::star::drawing::XDrawPage;
using ::com::sun::star::beans::XPropertySet;

namespace sd {

extern void fillRepeatComboBox( ComboBox* pBox );
extern void fillDurationComboBox( ComboBox* pBox );
extern OUString getShapeDescription( const Reference< XShape >& xShape, bool bWithText = true );
extern OUString getPropertyName( sal_Int32 nPropertyType );

// ====================================================================

class PresetPropertyBox  : public PropertySubControl
{
public:
	PresetPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const OUString& aPresetId, const Link& rModifyHdl );
	~PresetPropertyBox();

	virtual Any getValue();
	virtual void setValue( const Any& rValue, const OUString& rPresetId );
	virtual Control* getControl();

private:
	std::map< sal_uInt16, rtl::OUString > maPropertyValues;
	ListBox* mpControl;
};

// --------------------------------------------------------------------

PresetPropertyBox::PresetPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const OUString& aPresetId, const Link& rModifyHdl )
: PropertySubControl( nControlType )
{
	mpControl = new ListBox( pParent, WB_BORDER|WB_TABSTOP|WB_DROPDOWN );
	mpControl->SetDropDownLineCount( 10 );
	mpControl->SetSelectHdl( rModifyHdl );
	mpControl->SetHelpId( HID_SD_CUSTOMANIMATIONPANE_PRESETPROPERTYBOX );

	setValue( rValue, aPresetId );

}

void PresetPropertyBox::setValue( const Any& rValue, const OUString& rPresetId )
{
	if( mpControl )
	{
		mpControl->Clear();

		const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
		CustomAnimationPresetPtr pDescriptor = rPresets.getEffectDescriptor( rPresetId );
		if( pDescriptor.get() )
		{

			OUString aPropertyValue;
			rValue >>= aPropertyValue;

			UStringList aSubTypes( pDescriptor->getSubTypes() );
			UStringList::iterator aIter( aSubTypes.begin() );
			const UStringList::iterator aEnd( aSubTypes.end() );

			mpControl->Enable( aIter != aEnd );

			while( aIter != aEnd )
			{
				sal_uInt16 nPos = mpControl->InsertEntry( rPresets.getUINameForProperty( (*aIter) ) );
				if( (*aIter) == aPropertyValue )
					mpControl->SelectEntryPos( nPos );
				maPropertyValues[nPos] = (*aIter++);
			}
		}
		else
		{
			mpControl->Enable( sal_False );
		}
	}
}

// --------------------------------------------------------------------

PresetPropertyBox::~PresetPropertyBox()
{
	delete mpControl;
}

// --------------------------------------------------------------------

Any PresetPropertyBox::getValue()
{
	return makeAny( maPropertyValues[mpControl->GetSelectEntryPos()] );
}

// --------------------------------------------------------------------

Control* PresetPropertyBox::getControl()
{
	return mpControl;
}

// ====================================================================

class ColorPropertyBox  : public PropertySubControl
{
public:
	ColorPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl );
	~ColorPropertyBox();

	virtual Any getValue();
	virtual void setValue( const Any& rValue, const OUString& rPresetId  );
	virtual Control* getControl();

private:
	ColorListBox* mpControl;
};

// --------------------------------------------------------------------

ColorPropertyBox::ColorPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl )
: PropertySubControl( nControlType )
{
	mpControl = new ColorListBox( pParent, WB_BORDER|WB_TABSTOP|WB_DROPDOWN );
	mpControl->SetDropDownLineCount( 10 );
	mpControl->SetSelectHdl( rModifyHdl );
	mpControl->SetHelpId( HID_SD_CUSTOMANIMATIONPANE_COLORPROPERTYBOX );

	SfxObjectShell* pDocSh = SfxObjectShell::Current();
	DBG_ASSERT( pDocSh, "DocShell not found!" );
	XColorListSharedPtr aColorTable;
	const SfxPoolItem* pItem = NULL;

	if ( pDocSh && ( ( pItem = pDocSh->GetItem( SID_COLOR_TABLE ) ) != 0) )
		aColorTable = static_cast< const SvxColorTableItem* >(pItem)->GetColorTable();

	if ( !aColorTable.get() )
	{
		aColorTable = XPropertyListFactory::CreateSharedXColorList(SvtPathOptions().GetPalettePath());
	}

	sal_Int32 nColor = 0;
	rValue >>= nColor;

	for ( long i = 0; i < aColorTable->Count(); i++ )
	{
		XColorEntry* pEntry = aColorTable->GetColor(i);
		sal_uInt16 nPos = mpControl->InsertEntry( pEntry->GetColor(), pEntry->GetName() );
		if( pEntry->GetColor().GetRGBColor() == (sal_uInt32)nColor )
			mpControl->SelectEntryPos( nPos );
	}
}

// --------------------------------------------------------------------

ColorPropertyBox::~ColorPropertyBox()
{
	delete mpControl;
}

// --------------------------------------------------------------------

void ColorPropertyBox::setValue( const Any& rValue, const OUString& )
{
	if( mpControl )
	{
		sal_Int32 nColor = 0;
		rValue >>= nColor;

		mpControl->SetNoSelection();
		mpControl->SelectEntryPos( mpControl->GetEntryPos( (Color)nColor ) );
	}
}

// --------------------------------------------------------------------

Any ColorPropertyBox::getValue()
{
	return makeAny( (sal_Int32)mpControl->GetSelectEntryColor().GetRGBColor() );
}

// --------------------------------------------------------------------

Control* ColorPropertyBox::getControl()
{
	return mpControl;
}

// ====================================================================

class FontPropertyBox : public PropertySubControl
{
public:
	FontPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl );
	virtual ~FontPropertyBox();

	virtual Any getValue();
	virtual void setValue( const Any& rValue, const OUString& rPresetId  );

	virtual Control* getControl();

private:
	FontNameBox* mpControl;
};

// --------------------------------------------------------------------

FontPropertyBox::FontPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl )
: PropertySubControl( nControlType )
{
	mpControl = new FontNameBox( pParent, WB_BORDER|WB_TABSTOP|WB_DROPDOWN );
	mpControl->SetDropDownLineCount( 10 );
	mpControl->SetSelectHdl( rModifyHdl );
	mpControl->SetHelpId( HID_SD_CUSTOMANIMATIONPANE_FONTPROPERTYBOX );

	SfxObjectShell* pDocSh = SfxObjectShell::Current();
	const SfxPoolItem* pItem;

	const FontList* pFontList = 0;
	bool bMustDelete = false;

    if ( pDocSh && ( (pItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST ) ) != 0) )
        pFontList = ( (SvxFontListItem*)pItem )->GetFontList();

	if(!pFontList)
	{
        pFontList = new FontList( Application::GetDefaultDevice(), NULL, sal_False );
		bMustDelete = true;
	}

	mpControl->Fill( pFontList );

	if( bMustDelete )
		delete pFontList;

	OUString aPresetId;
	setValue( rValue, aPresetId );
}

// --------------------------------------------------------------------

void FontPropertyBox::setValue( const Any& rValue, const OUString& )
{
	if( mpControl )
	{
		OUString aFontName;
		rValue >>= aFontName;
		mpControl->SetText( aFontName );
	}
}

// --------------------------------------------------------------------

FontPropertyBox::~FontPropertyBox()
{
	delete mpControl;
}

// --------------------------------------------------------------------

Any FontPropertyBox::getValue()
{
	OUString aFontName( mpControl->GetText() );
	return makeAny( aFontName );
}

// --------------------------------------------------------------------

Control* FontPropertyBox::getControl()
{
	return mpControl;
}

// ====================================================================

class DropdownMenuBox : public Edit
{
public:
	DropdownMenuBox( Window* pParent, Edit* pSubControl, PopupMenu* pMenu );
	~DropdownMenuBox();

	void Resize();
	long PreNotify( NotifyEvent& rNEvt );

	void SetMenuSelectHdl( const Link& rLink ) { mpDropdownButton->SetSelectHdl( rLink ); }

private:
	Edit* mpSubControl;
	MenuButton* mpDropdownButton;
	PopupMenu* mpMenu;
};

// --------------------------------------------------------------------

DropdownMenuBox::DropdownMenuBox( Window* pParent, Edit* pSubControl, PopupMenu* pMenu )
:	Edit( pParent, WB_BORDER|WB_TABSTOP| WB_DIALOGCONTROL ),
	mpSubControl(pSubControl),mpDropdownButton(0),mpMenu(pMenu)
{
	mpDropdownButton = new MenuButton( this, WB_NOLIGHTBORDER | WB_RECTSTYLE | WB_NOTABSTOP);
	mpDropdownButton->SetSymbol(SYMBOL_SPIN_DOWN);
	mpDropdownButton->Show();
	mpDropdownButton->SetPopupMenu( pMenu );

	SetSubEdit( mpSubControl );
	mpSubControl->SetParent( this );
	mpSubControl->Show();
}

// --------------------------------------------------------------------

DropdownMenuBox::~DropdownMenuBox()
{
	SetSubEdit( 0 );
	delete mpSubControl;
	delete mpDropdownButton;
	delete mpMenu;
}

// --------------------------------------------------------------------

void DropdownMenuBox::Resize()
{
	Size aOutSz = GetOutputSizePixel();

	long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
	nSBWidth = CalcZoom( nSBWidth );
	mpSubControl->SetPosSizePixel( 0, 1, aOutSz.Width() - nSBWidth, aOutSz.Height()-2 );
	mpDropdownButton->SetPosSizePixel( aOutSz.Width() - nSBWidth, 0, nSBWidth, aOutSz.Height() );
}

// --------------------------------------------------------------------

long DropdownMenuBox::PreNotify( NotifyEvent& rNEvt )
{
	long nResult=sal_True;

	sal_uInt16 nSwitch=rNEvt.GetType();
	if (nSwitch==EVENT_KEYINPUT)
	{
		const KeyCode& aKeyCode=rNEvt.GetKeyEvent()->GetKeyCode();
		sal_uInt16 nKey=aKeyCode.GetCode();

		if (nKey==KEY_DOWN && aKeyCode.IsMod2())
		{
			mpDropdownButton->KeyInput( *rNEvt.GetKeyEvent() );
		}
		else
		{
			nResult=Edit::PreNotify(rNEvt);
		}
	}
	else
		nResult=Edit::PreNotify(rNEvt);

	return nResult;
}

// --------------------------------------------------------------------

class CharHeightPropertyBox : public PropertySubControl
{
public:
	CharHeightPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl );
	virtual ~CharHeightPropertyBox();

	virtual Any getValue();
	virtual void setValue( const Any& rValue, const OUString& );

	virtual Control* getControl();

	DECL_LINK( implMenuSelectHdl, MenuButton* );

private:
	DropdownMenuBox* mpControl;
	PopupMenu* mpMenu;
	MetricField* mpMetric;
};

// --------------------------------------------------------------------

CharHeightPropertyBox::CharHeightPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl )
: PropertySubControl( nControlType )
{
	mpMetric = new MetricField( pParent, WB_TABSTOP|WB_IGNORETAB| WB_NOBORDER);
	mpMetric->SetUnit( FUNIT_PERCENT );
	mpMetric->SetMin( 0 );
	mpMetric->SetMax( 1000 );

	mpMenu = new PopupMenu(SdResId( RID_CUSTOMANIMATION_FONTSIZE_POPUP ) );
	mpControl = new DropdownMenuBox( pParent, mpMetric, mpMenu );
	mpControl->SetMenuSelectHdl( LINK( this, CharHeightPropertyBox, implMenuSelectHdl ));
	mpControl->SetModifyHdl( rModifyHdl );
	mpControl->SetHelpId( HID_SD_CUSTOMANIMATIONPANE_CHARHEIGHTPROPERTYBOX );

	OUString aPresetId;
	setValue( rValue, aPresetId );
}

// --------------------------------------------------------------------

CharHeightPropertyBox::~CharHeightPropertyBox()
{
	delete mpControl;
}

// --------------------------------------------------------------------

IMPL_LINK( CharHeightPropertyBox, implMenuSelectHdl, MenuButton*, pPb )
{
	long nValue = 100;
	switch( pPb->GetCurItemId() )
	{
	case CM_SIZE_25: nValue = 25; break;
	case CM_SIZE_50: nValue = 50; break;
	case CM_SIZE_150: nValue = 150; break;
	case CM_SIZE_400: nValue = 400; break;
	}
	mpMetric->SetValue( nValue );
	mpMetric->Modify();
	return 0;
}

// --------------------------------------------------------------------

void CharHeightPropertyBox::setValue( const Any& rValue, const OUString& )
{
	if( mpMetric )
	{
		double fValue = 0.0;
		rValue >>= fValue;
		mpMetric->SetValue( (long)(fValue * 100.0) );
	}
}

// --------------------------------------------------------------------

Any CharHeightPropertyBox::getValue()
{
	return makeAny( (double)((double)mpMetric->GetValue() / 100.0) );
}

// --------------------------------------------------------------------

Control* CharHeightPropertyBox::getControl()
{
	return mpControl;
}

// ====================================================================

class TransparencyPropertyBox : public PropertySubControl
{
public:
	TransparencyPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl );
	~TransparencyPropertyBox();

	virtual Any getValue();
	virtual void setValue( const Any& rValue, const OUString& rPresetId  );

	virtual Control* getControl();

	DECL_LINK( implMenuSelectHdl, MenuButton* );
	DECL_LINK( implModifyHdl, Control* );

	void updateMenu();

private:
	DropdownMenuBox* mpControl;
	PopupMenu* mpMenu;
	MetricField* mpMetric;
	Link maModifyHdl;
};

// --------------------------------------------------------------------

TransparencyPropertyBox::TransparencyPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl )
: PropertySubControl( nControlType )
, maModifyHdl( rModifyHdl )
{
	mpMetric = new MetricField( pParent ,WB_TABSTOP|WB_IGNORETAB| WB_NOBORDER);
	mpMetric->SetUnit( FUNIT_PERCENT );
	mpMetric->SetMin( 0 );
	mpMetric->SetMax( 100 );

	mpMenu = new PopupMenu();
	for( sal_uInt16 i = 25; i < 101; i += 25 )
	{
		String aStr( String::CreateFromInt32( i ) );
		aStr += sal_Unicode('%');
		mpMenu->InsertItem( i, aStr );
	}

	mpControl = new DropdownMenuBox( pParent, mpMetric, mpMenu );
	mpControl->SetMenuSelectHdl( LINK( this, TransparencyPropertyBox, implMenuSelectHdl ));
	mpControl->SetHelpId( HID_SD_CUSTOMANIMATIONPANE_TRANSPARENCYPROPERTYBOX );

	Link aLink( LINK( this, TransparencyPropertyBox, implModifyHdl ) );
	mpControl->SetModifyHdl( aLink );

	OUString aPresetId;
	setValue( rValue, aPresetId  );
}

// --------------------------------------------------------------------

TransparencyPropertyBox::~TransparencyPropertyBox()
{
	delete mpControl;
}

// --------------------------------------------------------------------

void TransparencyPropertyBox::updateMenu()
{
	sal_Int64 nValue = mpMetric->GetValue();
	for( sal_uInt16 i = 25; i < 101; i += 25 )
		mpMenu->CheckItem( i, nValue == i );
}

// --------------------------------------------------------------------

IMPL_LINK( TransparencyPropertyBox, implModifyHdl, Control*, EMPTYARG )
{
	updateMenu();
	maModifyHdl.Call(mpMetric);

	return 0;
}

// --------------------------------------------------------------------

IMPL_LINK( TransparencyPropertyBox, implMenuSelectHdl, MenuButton*, pPb )
{
	if( pPb->GetCurItemId() != mpMetric->GetValue() )
	{
		mpMetric->SetValue( pPb->GetCurItemId() );
		mpMetric->Modify();
	}

	return 0;
}

// --------------------------------------------------------------------

void TransparencyPropertyBox::setValue( const Any& rValue, const OUString& )
{
	if( mpMetric )
	{
		double fValue = 0.0;
		rValue >>= fValue;
		long nValue = (long)(fValue * 100);
		mpMetric->SetValue( nValue );
		updateMenu();
	}
}

// --------------------------------------------------------------------

Any TransparencyPropertyBox::getValue()
{
	return makeAny( (double)((double)mpMetric->GetValue()) / 100.0 );
}

// --------------------------------------------------------------------

Control* TransparencyPropertyBox::getControl()
{
	return mpControl;
}

// --------------------------------------------------------------------

class RotationPropertyBox : public PropertySubControl
{
public:
	RotationPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl );
	~RotationPropertyBox();

	virtual Any getValue();
	virtual void setValue( const Any& rValue, const OUString& );

	virtual Control* getControl();

	DECL_LINK( implMenuSelectHdl, MenuButton* );
	DECL_LINK( implModifyHdl, Control* );

	void updateMenu();

private:
	DropdownMenuBox* mpControl;
	PopupMenu* mpMenu;
	MetricField* mpMetric;
	Link maModifyHdl;
};

// --------------------------------------------------------------------

RotationPropertyBox::RotationPropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl )
: PropertySubControl( nControlType )
, maModifyHdl( rModifyHdl )
{
	mpMetric = new MetricField( pParent ,WB_TABSTOP|WB_IGNORETAB| WB_NOBORDER);
	mpMetric->SetUnit( FUNIT_CUSTOM );
	mpMetric->SetCustomUnitText( OUString( sal_Unicode(0xb0)) ); // degree sign
	mpMetric->SetMin( -10000 );
	mpMetric->SetMax( 10000 );

	mpMenu = new PopupMenu(SdResId( RID_CUSTOMANIMATION_ROTATION_POPUP ) );
	mpControl = new DropdownMenuBox( pParent, mpMetric, mpMenu );
	mpControl->SetMenuSelectHdl( LINK( this, RotationPropertyBox, implMenuSelectHdl ));
	mpControl->SetHelpId( HID_SD_CUSTOMANIMATIONPANE_ROTATIONPROPERTYBOX );

	Link aLink( LINK( this, RotationPropertyBox, implModifyHdl ) );
	mpControl->SetModifyHdl( aLink );

	OUString aPresetId;
	setValue( rValue, aPresetId );
}

// --------------------------------------------------------------------

RotationPropertyBox::~RotationPropertyBox()
{
	delete mpControl;
}

// --------------------------------------------------------------------

void RotationPropertyBox::updateMenu()
{
	sal_Int64 nValue = mpMetric->GetValue();
	bool bDirection = nValue >= 0;
	nValue = (nValue < 0 ? -nValue : nValue);

	mpMenu->CheckItem( CM_QUARTER_SPIN, nValue == 90 );
	mpMenu->CheckItem( CM_HALF_SPIN, nValue == 180 );
	mpMenu->CheckItem( CM_FULL_SPIN, nValue == 360 );
	mpMenu->CheckItem( CM_TWO_SPINS, nValue == 720 );

	mpMenu->CheckItem( CM_CLOCKWISE, bDirection );
	mpMenu->CheckItem( CM_COUNTERCLOCKWISE, !bDirection );
}

// --------------------------------------------------------------------

IMPL_LINK( RotationPropertyBox, implModifyHdl, Control*, EMPTYARG )
{
	updateMenu();
	maModifyHdl.Call(mpMetric);

	return 0;
}

IMPL_LINK( RotationPropertyBox, implMenuSelectHdl, MenuButton*, pPb )
{
	sal_Int64 nValue = mpMetric->GetValue();
	bool bDirection = nValue >= 0;
	nValue = (nValue < 0 ? -nValue : nValue);

	switch( pPb->GetCurItemId() )
	{
	case CM_QUARTER_SPIN: nValue = 90; break;
	case CM_HALF_SPIN: nValue = 180; break;
	case CM_FULL_SPIN: nValue = 360; break;
	case CM_TWO_SPINS: nValue = 720; break;

	case CM_CLOCKWISE: bDirection = true; break;
	case CM_COUNTERCLOCKWISE: bDirection = false; break;

	}

	if( !bDirection )
		nValue = -nValue;

	if( nValue != mpMetric->GetValue() )
	{
		mpMetric->SetValue( nValue );
		mpMetric->Modify();
	}

	return 0;
}

// --------------------------------------------------------------------

void RotationPropertyBox::setValue( const Any& rValue, const OUString& )
{
	if( mpMetric )
	{
		double fValue = 0.0;
		rValue >>= fValue;
		long nValue = (long)(fValue);
		mpMetric->SetValue( nValue );
		updateMenu();
	}
}

// --------------------------------------------------------------------

Any RotationPropertyBox::getValue()
{
	return makeAny( (double)((double)mpMetric->GetValue()) );
}

// --------------------------------------------------------------------

Control* RotationPropertyBox::getControl()
{
	return mpControl;
}

// --------------------------------------------------------------------

class ScalePropertyBox : public PropertySubControl
{
public:
	ScalePropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl );
	~ScalePropertyBox();

	virtual Any getValue();
	virtual void setValue( const Any& rValue, const OUString& );

	virtual Control* getControl();

	DECL_LINK( implMenuSelectHdl, MenuButton* );
	DECL_LINK( implModifyHdl, Control* );

	void updateMenu();

private:
	DropdownMenuBox* mpControl;
	PopupMenu* mpMenu;
	MetricField* mpMetric;
	Link maModifyHdl;
	int mnDirection;
};

// --------------------------------------------------------------------

ScalePropertyBox::ScalePropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl )
: PropertySubControl( nControlType )
, maModifyHdl( rModifyHdl )
{
	mpMetric = new MetricField( pParent ,WB_TABSTOP|WB_IGNORETAB| WB_NOBORDER);
	mpMetric->SetUnit( FUNIT_PERCENT );
	mpMetric->SetMin( 0 );
	mpMetric->SetMax( 10000 );

	mpMenu = new PopupMenu(SdResId( RID_CUSTOMANIMATION_SCALE_POPUP ) );
	mpControl = new DropdownMenuBox( pParent, mpMetric, mpMenu );
	mpControl->SetMenuSelectHdl( LINK( this, ScalePropertyBox, implMenuSelectHdl ));
	mpControl->SetHelpId( HID_SD_CUSTOMANIMATIONPANE_SCALEPROPERTYBOX );

	Link aLink( LINK( this, ScalePropertyBox, implModifyHdl ) );
	mpControl->SetModifyHdl( aLink );

	OUString aPresetId;
	setValue( rValue, aPresetId );
}

// --------------------------------------------------------------------

ScalePropertyBox::~ScalePropertyBox()
{
	delete mpControl;
}

// --------------------------------------------------------------------

void ScalePropertyBox::updateMenu()
{
	sal_Int64 nValue = mpMetric->GetValue();

	mpMenu->CheckItem( 25, nValue == 25 );
	mpMenu->CheckItem( 50, nValue == 50 );
	mpMenu->CheckItem( 150, nValue == 150 );
	mpMenu->CheckItem( 400, nValue == 400 );

	mpMenu->CheckItem( CM_HORIZONTAL, mnDirection == 1 );
	mpMenu->CheckItem( CM_VERTICAL, mnDirection == 2 );
	mpMenu->CheckItem( CM_BOTH, mnDirection == 3 );
}

// --------------------------------------------------------------------

IMPL_LINK( ScalePropertyBox, implModifyHdl, Control*, EMPTYARG )
{
	updateMenu();
	maModifyHdl.Call(mpMetric);

	return 0;
}

IMPL_LINK( ScalePropertyBox, implMenuSelectHdl, MenuButton*, pPb )
{
	sal_Int64 nValue = mpMetric->GetValue();

	int nDirection = mnDirection;

	switch( pPb->GetCurItemId() )
	{
	case CM_HORIZONTAL: nDirection = 1; break;
	case CM_VERTICAL: nDirection = 2; break;
	case CM_BOTH: nDirection = 3; break;

	default:
		nValue = pPb->GetCurItemId();
	}

	bool bModified = false;

	if( nDirection != mnDirection )
	{
		mnDirection = nDirection;
		bModified = true;
	}

	if( nValue != mpMetric->GetValue() )
	{
		mpMetric->SetValue( nValue );
		bModified = true;
	}

	if( bModified )
	{
		mpMetric->Modify();
		updateMenu();
	}

	return 0;
}

// --------------------------------------------------------------------

void ScalePropertyBox::setValue( const Any& rValue, const OUString& )
{
	if( mpMetric )
	{
		ValuePair aValues;
		rValue >>= aValues;

		double fValue1 = 0.0;
		double fValue2 = 0.0;

		aValues.First >>= fValue1;
		aValues.Second >>= fValue2;

		if( fValue2 == 0.0 )
			mnDirection = 1;
		else if( fValue1 == 0.0 )
			mnDirection = 2;
		else
			mnDirection = 3;

		long nValue;
		if( fValue1 )
			nValue = (long)(fValue1 * 100.0);
		else
			nValue = (long)(fValue2 * 100.0);
		mpMetric->SetValue( nValue );
		updateMenu();
	}
}

// --------------------------------------------------------------------

Any ScalePropertyBox::getValue()
{
	double fValue1 = (double)((double)mpMetric->GetValue() / 100.0);
	double fValue2 = fValue1;

	if( mnDirection == 1 )
		fValue2 = 0.0;
	else if( mnDirection == 2 )
		fValue1 = 0.0;

	ValuePair aValues;
	aValues.First <<= fValue1;
	aValues.Second <<= fValue2;

	return makeAny( aValues );
}

// --------------------------------------------------------------------

Control* ScalePropertyBox::getControl()
{
	return mpControl;
}

// ====================================================================

class FontStylePropertyBox : public PropertySubControl
{
public:
	FontStylePropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl );
	~FontStylePropertyBox();

	virtual Any getValue();
	virtual void setValue( const Any& rValue, const OUString& );

	virtual Control* getControl();

	DECL_LINK( implMenuSelectHdl, MenuButton* );

	void update();

private:
	DropdownMenuBox* mpControl;
	PopupMenu* mpMenu;
	Edit* mpEdit;
	Link maModifyHdl;

	float mfFontWeight;
	awt::FontSlant meFontSlant;
	sal_Int16 mnFontUnderline;
};

// --------------------------------------------------------------------

FontStylePropertyBox::FontStylePropertyBox( sal_Int32 nControlType, Window* pParent, const Any& rValue, const Link& rModifyHdl )
: PropertySubControl( nControlType )
, maModifyHdl( rModifyHdl )
{
	mpEdit = new Edit( pParent, WB_TABSTOP|WB_IGNORETAB|WB_NOBORDER|WB_READONLY);
	mpEdit->SetText( String( SdResId( STR_CUSTOMANIMATION_SAMPLE ) ) );

	mpMenu = new PopupMenu(SdResId( RID_CUSTOMANIMATION_FONTSTYLE_POPUP ) );
	mpControl = new DropdownMenuBox( pParent, mpEdit, mpMenu );
	mpControl->SetMenuSelectHdl( LINK( this, FontStylePropertyBox, implMenuSelectHdl ));
	mpControl->SetHelpId( HID_SD_CUSTOMANIMATIONPANE_FONTSTYLEPROPERTYBOX );

	OUString aPresetId;
	setValue( rValue, aPresetId );
}

// --------------------------------------------------------------------

FontStylePropertyBox::~FontStylePropertyBox()
{
	delete mpControl;
}

// --------------------------------------------------------------------

void FontStylePropertyBox::update()
{
	// update menu
	mpMenu->CheckItem( CM_BOLD, mfFontWeight == awt::FontWeight::BOLD );
	mpMenu->CheckItem( CM_ITALIC, meFontSlant == awt::FontSlant_ITALIC);
	mpMenu->CheckItem( CM_UNDERLINED, mnFontUnderline != awt::FontUnderline::NONE );

	// update sample edit
	Font aFont( mpEdit->GetFont() );
	aFont.SetWeight( mfFontWeight == awt::FontWeight::BOLD ? WEIGHT_BOLD : WEIGHT_NORMAL );
	aFont.SetItalic( meFontSlant == awt::FontSlant_ITALIC ? ITALIC_NORMAL : ITALIC_NONE  );
	aFont.SetUnderline( mnFontUnderline == awt::FontUnderline::NONE ? UNDERLINE_NONE : UNDERLINE_SINGLE );
	mpEdit->SetFont( aFont );
	mpEdit->Invalidate();
}

// --------------------------------------------------------------------

IMPL_LINK( FontStylePropertyBox, implMenuSelectHdl, MenuButton*, pPb )
{
	switch( pPb->GetCurItemId() )
	{
	case CM_BOLD:
		if( mfFontWeight == awt::FontWeight::BOLD )
			mfFontWeight = awt::FontWeight::NORMAL;
		else
			mfFontWeight = awt::FontWeight::BOLD;
		break;
	case CM_ITALIC:
		if( meFontSlant == awt::FontSlant_ITALIC )
			meFontSlant = awt::FontSlant_NONE;
		else
			meFontSlant = awt::FontSlant_ITALIC;
		break;
	case CM_UNDERLINED:
		if( mnFontUnderline == awt::FontUnderline::SINGLE )
			mnFontUnderline = awt::FontUnderline::NONE;
		else
			mnFontUnderline = awt::FontUnderline::SINGLE;
		break;
	default:
		return 0;
	}

	update();
	maModifyHdl.Call(mpEdit);

	return 0;
}

// --------------------------------------------------------------------

void FontStylePropertyBox::setValue( const Any& rValue, const OUString& )
{
	Sequence<Any> aValues;
	rValue >>= aValues;

	aValues[0] >>= mfFontWeight;
	aValues[1] >>= meFontSlant;
	aValues[2] >>= mnFontUnderline;

	update();
}

// --------------------------------------------------------------------

Any FontStylePropertyBox::getValue()
{
	Sequence<Any> aValues(3);
	aValues[0] <<= mfFontWeight;
	aValues[1] <<= meFontSlant;
	aValues[2] <<= mnFontUnderline;
	return makeAny( aValues );
}

// --------------------------------------------------------------------

Control* FontStylePropertyBox::getControl()
{
	return mpControl;
}

// ====================================================================

class CustomAnimationEffectTabPage : public TabPage
{
public:
	CustomAnimationEffectTabPage( Window* pParent, const ResId& rResId, const STLPropertySet* pSet );
	~CustomAnimationEffectTabPage();

	void update( STLPropertySet* pSet );
	DECL_LINK( implSelectHdl, Control* );

private:
	void updateControlStates();
	void fillSoundListBox();
	void clearSoundListBox();
	sal_Int32 getSoundObject( const String& rStr );
	void openSoundFileDialog();
	void onSoundPreview();

private:
	List maSoundList;
	sal_Bool mbHasText;
	const STLPropertySet* mpSet;

	FixedLine*		mpFLSettings;
	FixedText*		mpFTProperty1;
	PropertyControl* mpLBProperty1;
	FixedText*		mpFTProperty2;
	PropertyControl* mpLBProperty2;
	CheckBox*		mpCBSmoothStart;
	CheckBox*		mpCBSmoothEnd;
	CheckBox*		mpCBAutoRestart;

	FixedLine*		mpFLPlay;
	RadioButton*	mpRBFromStart;
	RadioButton*	mpRBFromLast;
	RadioButton*	mpRBFromTime;
	MetricField*	mpMFStartTime;
	FixedLine*		mpFLStop;
	RadioButton*	mpRBStopOnClick;
	RadioButton*	mpRBStopOnNextSlide;
	RadioButton*	mpRBStopAfterSlides;
	MetricField*	mpMFStopAfterSlides;

	FixedLine*		mpFLEnhancements;
	FixedText*		mpFTSound;
	ListBox*		mpLBSound;
	PushButton*		mpPBSoundPreview;
	FixedText*		mpFTAfterEffect;
	ListBox*		mpLBAfterEffect;
	FixedText*		mpFTDimColor;
	ColorListBox*	mpCLBDimColor;
	FixedText*		mpFTTextAnim;
	ListBox*		mpLBTextAnim;
	MetricField*	mpMFTextDelay;
	FixedText*		mpFTTextDelay;

	::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > mxPlayer;
};


static void move_down( Control* pControl, int nOffsetX, int nOffsetY )
{
	Point aPos( pControl->GetPosPixel() );
	aPos.X() += nOffsetX;
	aPos.Y() += nOffsetY;
	pControl->SetPosPixel( aPos );
}

CustomAnimationEffectTabPage::CustomAnimationEffectTabPage( Window* pParent, const ResId& rResId, const STLPropertySet* pSet )
: TabPage( pParent, rResId ), mbHasText( sal_False ), mpSet(pSet )
{
	mpFLSettings = new FixedLine( this, SdResId( FL_SETTINGS ) );
	mpFTProperty1 = new FixedText( this, SdResId( FT_PROPERTY_1 ) );
	mpLBProperty1 = new PropertyControl( this, SdResId( LB_PROPERTY_1 ) );
	mpFTProperty2 = new FixedText( this, SdResId( FT_PROPERTY_2 ) );
	mpLBProperty2 = new PropertyControl( this, SdResId( LB_PROPERTY_2 ) );
	mpCBSmoothStart = new CheckBox( this, SdResId( CB_SMOOTH_START ) );
	mpCBSmoothEnd = new CheckBox( this, SdResId( CB_SMOOTH_END ) );
	mpCBAutoRestart = new CheckBox( this, SdResId( CB_AUTORESTART ) );
/*
	mpFLPlay = new FixedLine( this, SdResId( FL_PLAY ) );
	mpRBFromStart = new RadioButton( this, SdResId( RB_FROM_START ) );
	mpRBFromLast = new RadioButton( this, SdResId( RB_FROM_LAST ) );
	mpRBFromTime = new RadioButton( this, SdResId( RB_FROM_TIME ) );
	mpMFStartTime = new MetricField( this, SdResId( MF_START_TIME ) );
	mpFLStop = new FixedLine( this, SdResId( FL_STOP ) );
	mpRBStopOnClick = new RadioButton( this, SdResId( RB_STOP_ON_CLICK ) );
	mpRBStopOnNextSlide = new RadioButton( this, SdResId( RB_STOP_ON_NEXT_SLIDE ) );
	mpRBStopAfterSlides = new RadioButton( this, SdResId( RB_STOP_AFTER_N_SLIDES ) );
	mpMFStopAfterSlides = new MetricField( this, SdResId( MF_STOP_AFTER_SLIDES ) );
*/
	mpFLEnhancements = new FixedLine( this, SdResId( FL_ENHANCEMENTS ) );
	mpFTSound = new FixedText( this, SdResId( FT_SOUND ) );
	mpLBSound = new ListBox( this, SdResId( LB_SOUND ) );
	mpPBSoundPreview = new PushButton( this, SdResId( PB_SOUND_PREVIEW ) );
	mpFTAfterEffect = new FixedText( this, SdResId( FT_AFTER_EFFECT ) );
	mpLBAfterEffect = new ListBox( this, SdResId( LB_AFTER_EFFECT ) );
	mpFTDimColor = new FixedText( this, SdResId( FT_DIMCOLOR ) );
	mpCLBDimColor = new ColorListBox( this, SdResId( CLB_DIMCOLOR ) );
	mpFTTextAnim = new FixedText( this, SdResId( FT_TEXT_ANIM ) );
	mpLBTextAnim = new ListBox( this, SdResId( LB_TEXT_ANIM ) );
	mpMFTextDelay = new MetricField( this, SdResId( MF_TEXT_DELAY ) );
	mpFTTextDelay = new FixedText( this, SdResId( FT_TEXT_DELAY ) );

	FreeResource();

	// fill the soundbox
	fillSoundListBox();

	mpLBSound->SetSelectHdl( LINK( this, CustomAnimationEffectTabPage, implSelectHdl ) );

	mpPBSoundPreview->SetClickHdl( LINK( this, CustomAnimationEffectTabPage, implSelectHdl ) );
	mpPBSoundPreview->SetSymbol( SYMBOL_PLAY );

	// fill the color box
	SfxObjectShell* pDocSh = SfxObjectShell::Current();
	DBG_ASSERT( pDocSh, "DocShell not found!" );
	XColorListSharedPtr aColorTable;
	const SfxPoolItem* pItem = NULL;

	if ( pDocSh && ( (pItem = pDocSh->GetItem( SID_COLOR_TABLE ) ) != 0 ) )
		aColorTable = static_cast< const SvxColorTableItem* >(pItem)->GetColorTable();

	if ( !aColorTable.get() )
	{
		aColorTable = XPropertyListFactory::CreateSharedXColorList(SvtPathOptions().GetPalettePath());
	}

    mpCLBDimColor->SetUpdateMode( sal_False );

    for ( long i = 0; i < aColorTable->Count(); i++ )
	{
		XColorEntry* pEntry = aColorTable->GetColor(i);
        mpCLBDimColor->InsertEntry( pEntry->GetColor(), pEntry->GetName() );
	}

    mpCLBDimColor->SetUpdateMode( sal_True );

	//
	// init settings controls
	//

	int nOffsetY = 0;
	int nOffsetX = 0;

	Size aSpace( LogicToPixel( Size( 3, 3 ), MAP_APPFONT ) );

	// only show settings if all selected effects have the same preset-id
	if( pSet->getPropertyState( nHandlePresetId ) != STLPropertyState_AMBIGUOUS )
	{
		OUString aPresetId;
		pSet->getPropertyValue( nHandlePresetId ) >>= aPresetId;

		//
		// property 1
		//

		if( pSet->getPropertyState( nHandleProperty1Type ) != STLPropertyState_AMBIGUOUS )
		{
			sal_Int32 nType = 0;
			pSet->getPropertyValue( nHandleProperty1Type ) >>= nType;

			if( nType != nPropertyTypeNone )
			{
				// set ui name for property at fixed text
				OUString aPropertyName( getPropertyName( nType ) );

				if( aPropertyName.getLength() )
				{
					mpFTProperty1->Show();
					mpLBProperty1->Show();

					nOffsetY += mpLBProperty1->GetSizePixel().Height() + aSpace.Height();

					mpFTProperty1->SetText( aPropertyName );
				}

				// get property value
				const Any aValue( pSet->getPropertyValue( nHandleProperty1Value ) );

				Link aModifyLink;
				// create property sub control
				mpLBProperty1->setSubControl( PropertySubControl::create( nType, this, aValue, aPresetId, aModifyLink ));
			}
		}

		mpFTProperty1->Enable( mpLBProperty1->IsEnabled() );

		//
		// accelerate & deccelerate
		//

		if( pSet->getPropertyState( nHandleAccelerate ) == STLPropertyState_DIRECT )
		{
			mpCBSmoothStart->Show();
			mpCBSmoothEnd->Show();

			move_down( mpCBSmoothStart, nOffsetX, nOffsetY );
			move_down( mpCBSmoothEnd, nOffsetX, nOffsetY );

			nOffsetY += mpCBSmoothStart->GetSizePixel().Height() + aSpace.Height();

			double fTemp = 0.0;
			pSet->getPropertyValue( nHandleAccelerate ) >>= fTemp;
			mpCBSmoothStart->Check( fTemp > 0.0 );

			pSet->getPropertyValue( nHandleDecelerate ) >>= fTemp;
			mpCBSmoothEnd->Check( fTemp > 0.0 );
		}

		//
		// auto reverse
		//


		if( nOffsetY )
		{
			nOffsetY += mpFLSettings->GetSizePixel().Height() + aSpace.Height();
			mpFLSettings->Show();

			mpFLEnhancements->Show();
			move_down( mpFLEnhancements, nOffsetX, nOffsetY );

			nOffsetY += mpFLEnhancements->GetSizePixel().Height() + aSpace.Height();

			nOffsetX = 2* aSpace.Width();
		}
	}

	if( (nOffsetY != 0) || (nOffsetX != 0) )
	{
		move_down( mpFTSound, nOffsetX, nOffsetY );
		move_down( mpLBSound, nOffsetX, nOffsetY );
		move_down( mpPBSoundPreview, nOffsetX, nOffsetY );
		move_down( mpFTAfterEffect, nOffsetX, nOffsetY );
		move_down( mpLBAfterEffect, nOffsetX, nOffsetY );
		move_down( mpFTDimColor, nOffsetX, nOffsetY );
		move_down( mpCLBDimColor, nOffsetX, nOffsetY );
		move_down( mpFTTextAnim, nOffsetX, nOffsetY );
		move_down( mpLBTextAnim, nOffsetX, nOffsetY );
		move_down( mpMFTextDelay, nOffsetX, nOffsetY );
		move_down( mpFTTextDelay, nOffsetX, nOffsetY );
	}

	//
	// init after effect controls
	//

    mpLBAfterEffect->SetSelectHdl( LINK( this, CustomAnimationEffectTabPage, implSelectHdl ) );
    mpLBTextAnim->SetSelectHdl( LINK( this, CustomAnimationEffectTabPage, implSelectHdl ) );

	if( (pSet->getPropertyState( nHandleHasAfterEffect ) != STLPropertyState_AMBIGUOUS) &&
		(pSet->getPropertyState( nHandleAfterEffectOnNextEffect ) != STLPropertyState_AMBIGUOUS) &&
		(pSet->getPropertyState( nHandleDimColor ) != STLPropertyState_AMBIGUOUS))
	{
		sal_Bool bHasAfterEffect = sal_False;
		pSet->getPropertyValue( nHandleHasAfterEffect ) >>= bHasAfterEffect;

		sal_uInt16 nPos = 0;
		if( bHasAfterEffect )
		{
			nPos++;

			sal_Bool bAfterEffectOnNextClick = sal_False;
			pSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bAfterEffectOnNextClick;
			Any aDimColor( pSet->getPropertyValue( nHandleDimColor ) );

			if( aDimColor.hasValue() )
			{
				sal_Int32 nColor = 0;
				aDimColor >>= nColor;
				Color aColor( nColor );
	            sal_uInt16 nColorPos = mpCLBDimColor->GetEntryPos( aColor );
				if ( LISTBOX_ENTRY_NOTFOUND != nColorPos )
					mpCLBDimColor->SelectEntryPos( nColorPos );
				else
                    mpCLBDimColor->SelectEntryPos(
                        mpCLBDimColor->InsertEntry( aColor, String( SVX_RES( RID_SVXSTR_COLOR_USER ) ) ) );
			}
			else
			{
				nPos++;
				if( bAfterEffectOnNextClick )
					nPos++;
			}
		}

		mpLBAfterEffect->SelectEntryPos( nPos );
	}

	if( pSet->getPropertyState( nHandleHasText ) != STLPropertyState_AMBIGUOUS )
		pSet->getPropertyValue( nHandleHasText ) >>= mbHasText;

	if( mbHasText )
	{
		if( pSet->getPropertyState( nHandleIterateType ) != STLPropertyState_AMBIGUOUS)
		{
			sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;

			sal_Int32 nIterateType = 0;
			pSet->getPropertyValue( nHandleIterateType ) >>= nIterateType;
			switch( nIterateType )
			{
			case TextAnimationType::BY_PARAGRAPH:	nPos = 0; break;
			case TextAnimationType::BY_WORD:		nPos = 1; break;
			case TextAnimationType::BY_LETTER:		nPos = 2; break;
			}

			mpLBTextAnim->SelectEntryPos( nPos );
		}

		if( pSet->getPropertyState( nHandleIterateInterval ) )
		{
			double fIterateInterval = 0.0;
			pSet->getPropertyValue( nHandleIterateInterval ) >>= fIterateInterval;
			mpMFTextDelay->SetValue( (long)(fIterateInterval*10) );
		}
	}
	else
	{
		mpFTTextAnim->Enable( sal_False );
		mpLBTextAnim->Enable( sal_False );
		mpMFTextDelay->Enable( sal_False );
		mpFTTextDelay->Enable( sal_False );

	}

	if( pSet->getPropertyState( nHandleSoundURL ) != STLPropertyState_AMBIGUOUS )
	{
		sal_uInt16 nPos = 0;

		const Any aValue( pSet->getPropertyValue( nHandleSoundURL ) );

		if( aValue.getValueType() == ::getCppuType((const sal_Bool*)0) )
		{
			nPos = 1;
		}
		else
		{
			OUString aSoundURL;
			aValue >>= aSoundURL;

			if( aSoundURL.getLength() )
			{
				const String aTmp( aSoundURL );

				sal_uLong i;
				for( i = 0; i < maSoundList.Count(); i++ )
				{
					String* pString = (String*)maSoundList.GetObject( i );
					if( *pString == aTmp )
					{
						nPos = (sal_uInt16)i+2;
						break;
					}
				}

				if( nPos == 0 )
				{
					nPos = (sal_uInt16)maSoundList.Count()+2;
					maSoundList.Insert( new String( aTmp ), LIST_APPEND );
					INetURLObject aURL( aTmp );
					nPos = mpLBSound->InsertEntry( aURL.GetBase(), nPos );
				}
			}
		}

		if( nPos != LISTBOX_ENTRY_NOTFOUND )
			mpLBSound->SelectEntryPos( nPos );
	}

	updateControlStates();

	Size aSize( GetSizePixel() );
	aSize.Height() += mpMFTextDelay->GetPosPixel().X() + GetSizePixel().Height() + aSpace.Height();
	SetSizePixel( aSize );
}

CustomAnimationEffectTabPage::~CustomAnimationEffectTabPage()
{
	clearSoundListBox();

	delete mpFLSettings;
	delete mpFTProperty1;
	delete mpLBProperty1;
	delete mpFTProperty2;
	delete mpLBProperty2;
	delete mpCBSmoothStart;
	delete mpCBSmoothEnd;
	delete mpCBAutoRestart;

	delete mpFLEnhancements;
	delete mpFTSound;
	delete mpLBSound;
	delete mpPBSoundPreview;
	delete mpFTAfterEffect;
	delete mpLBAfterEffect;
	delete mpFTDimColor;
	delete mpCLBDimColor;
	delete mpFTTextAnim;
	delete mpLBTextAnim;
	delete mpMFTextDelay;
	delete mpFTTextDelay;
}

void CustomAnimationEffectTabPage::updateControlStates()
{
	sal_uInt16 nPos = mpLBAfterEffect->GetSelectEntryPos();
	mpCLBDimColor->Enable( nPos == 1 );
	mpFTDimColor->Enable( nPos == 1 );

	if( mbHasText )
	{
		nPos = mpLBTextAnim->GetSelectEntryPos();
		mpMFTextDelay->Enable( nPos != 0 );
		mpFTTextDelay->Enable( nPos != 0 );
	}

	nPos = mpLBSound->GetSelectEntryPos();
	mpPBSoundPreview->Enable( nPos >= 2 );
}

IMPL_LINK( CustomAnimationEffectTabPage, implSelectHdl, Control*, pControl )
{
	if( pControl == mpLBAfterEffect )
	{
		sal_uInt16 nPos = static_cast<ListBox*>( mpLBAfterEffect )->GetSelectEntryPos();
		if( nPos == 1 )
		{
			if( mpCLBDimColor->GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND )
				mpCLBDimColor->SelectEntryPos(0);
		}
	}
	else if( pControl == mpLBTextAnim )
	{
		if( mpMFTextDelay->GetValue() == 0 )
			mpMFTextDelay->SetValue( 100 );
	}
	else if( pControl == mpLBSound )
	{
		sal_uInt16 nPos = mpLBSound->GetSelectEntryPos();
		if( nPos == (mpLBSound->GetEntryCount() - 1) )
		{
			openSoundFileDialog();
		}
	}
	else if( pControl == mpPBSoundPreview )
	{
		onSoundPreview();
	}

	updateControlStates();
	return 0;
}

void CustomAnimationEffectTabPage::update( STLPropertySet* pSet )
{
	if( mpLBProperty1->getSubControl() )
	{
		Any aNewValue( mpLBProperty1->getSubControl()->getValue() );
		Any aOldValue;
		if( mpSet->getPropertyState( nHandleProperty1Value ) != STLPropertyState_AMBIGUOUS)
			aOldValue = mpSet->getPropertyValue( nHandleProperty1Value );

		if( aOldValue != aNewValue )
			pSet->setPropertyValue( nHandleProperty1Value, aNewValue );
	}

	if( mpLBProperty2->getSubControl() )
	{
		Any aNewValue( mpLBProperty2->getSubControl()->getValue() );
		Any aOldValue;
		if( mpSet->getPropertyState( nHandleProperty2Value ) != STLPropertyState_AMBIGUOUS)
			aOldValue = mpSet->getPropertyValue( nHandleProperty2Value );

		if( aOldValue != aNewValue )
			pSet->setPropertyValue( nHandleProperty2Value, aNewValue );
	}

	if( mpCBSmoothStart->IsVisible() )
	{
		// set selected value for accelerate if different then in original set

		double fTemp = mpCBSmoothStart->IsChecked() ? 0.5 : 0.0;

		double fOldTemp = 0.0;
		if(mpSet->getPropertyState( nHandleAccelerate ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleAccelerate ) >>= fOldTemp;
		else
			fOldTemp = -2.0;

		if( fOldTemp != fTemp )
			pSet->setPropertyValue( nHandleAccelerate, makeAny( fTemp ) );

		// set selected value for decelerate if different then in original set
		fTemp = mpCBSmoothEnd->IsChecked() ? 0.5 : 0.0;

		if(mpSet->getPropertyState( nHandleDecelerate ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleDecelerate ) >>= fOldTemp;
		else
			fOldTemp = -2.0;

		if( fOldTemp != fTemp )
			pSet->setPropertyValue( nHandleDecelerate, makeAny( fTemp ) );
	}

	sal_uInt16 nPos = mpLBAfterEffect->GetSelectEntryPos();
	if( nPos != LISTBOX_ENTRY_NOTFOUND )
	{
		sal_Bool bAfterEffect = nPos != 0;

		sal_Bool bOldAfterEffect = sal_False;

		if(mpSet->getPropertyState( nHandleHasAfterEffect ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleHasAfterEffect ) >>= bOldAfterEffect;
		else
			bOldAfterEffect = !bAfterEffect;

		if( bOldAfterEffect != bAfterEffect )
			pSet->setPropertyValue( nHandleHasAfterEffect, makeAny( bAfterEffect ) );

		Any aDimColor;
		if( nPos == 1 )
		{
			Color aSelectedColor;
			if ( mpCLBDimColor->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
				aSelectedColor = mpCLBDimColor->GetSelectEntryColor();

			aDimColor = makeAny( makeAny( (sal_Int32)aSelectedColor.GetRGBColor() ) );
		}

		if( (mpSet->getPropertyState( nHandleDimColor ) == STLPropertyState_AMBIGUOUS) ||
			(mpSet->getPropertyValue( nHandleDimColor ) != aDimColor) )
			pSet->setPropertyValue( nHandleDimColor, makeAny( aDimColor ) );

		sal_Bool bAfterEffectOnNextEffect = nPos != 2 ? sal_True : sal_False;
		sal_Bool bOldAfterEffectOnNextEffect = !bAfterEffectOnNextEffect;

		if( mpSet->getPropertyState( nHandleAfterEffectOnNextEffect ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bOldAfterEffectOnNextEffect;

		if( bAfterEffectOnNextEffect != bOldAfterEffectOnNextEffect )
			pSet->setPropertyValue( nHandleAfterEffectOnNextEffect, makeAny( bAfterEffectOnNextEffect ) );
	}

	// ---

	nPos = mpLBTextAnim->GetSelectEntryPos();
	if( nPos != LISTBOX_ENTRY_NOTFOUND )
	{
		sal_Int16 nIterateType;

		switch( nPos )
		{
		case 1: nIterateType = TextAnimationType::BY_WORD; break;
		case 2: nIterateType = TextAnimationType::BY_LETTER; break;
		default:
			nIterateType = TextAnimationType::BY_PARAGRAPH;
		}

		sal_Int16 nOldIterateType = nIterateType-1;

		if(mpSet->getPropertyState( nHandleIterateType ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleIterateType ) >>= nOldIterateType;

		if( nIterateType != nOldIterateType )
			pSet->setPropertyValue( nHandleIterateType, makeAny( nIterateType ) );
	}

	// ---

	{
		double fIterateInterval = static_cast< double >( mpMFTextDelay->GetValue() ) / 10;
		double fOldIterateInterval = -1.0;

		if( mpSet->getPropertyState( nHandleIterateInterval ) != STLPropertyState_AMBIGUOUS )
			mpSet->getPropertyValue( nHandleIterateInterval ) >>= fOldIterateInterval;

		if( fIterateInterval != fOldIterateInterval )
			pSet->setPropertyValue( nHandleIterateInterval, makeAny( fIterateInterval ) );
	}

	nPos = mpLBSound->GetSelectEntryPos();
	if( nPos != LISTBOX_ENTRY_NOTFOUND )
	{
		Any aNewSoundURL, aOldSoundURL( makeAny( (sal_Int32) 0 ) );

		if( nPos == 0 )
		{
			// 0 means no sound, so leave any empty
		}
		else if( nPos == 1 )
		{
			// this means stop sound
			aNewSoundURL = makeAny( (sal_Bool)sal_True );
		}
		else
		{
			OUString aSoundURL( *(String*)maSoundList.GetObject( nPos-2 ) );
			aNewSoundURL = makeAny( aSoundURL );
		}

		if( mpSet->getPropertyState( nHandleSoundURL ) != STLPropertyState_AMBIGUOUS )
			mpSet->getPropertyValue( nHandleSoundURL  ) >>= aOldSoundURL;

		if( aNewSoundURL != aOldSoundURL )
			pSet->setPropertyValue( nHandleSoundURL, aNewSoundURL );
	}
}

void CustomAnimationEffectTabPage::fillSoundListBox()
{
	GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, maSoundList );
	GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, maSoundList );

	mpLBSound->InsertEntry( String( SdResId( STR_CUSTOMANIMATION_NO_SOUND ) ) );
	mpLBSound->InsertEntry( String( SdResId( STR_CUSTOMANIMATION_STOP_PREVIOUS_SOUND ) ) );
	for( sal_uLong i = 0; i < maSoundList.Count(); i++ )
	{
		String* pString = (String*)maSoundList.GetObject( i );
		INetURLObject aURL( *pString );
		mpLBSound->InsertEntry( aURL.GetBase() );
	}
	mpLBSound->InsertEntry( String( SdResId( STR_CUSTOMANIMATION_BROWSE_SOUND ) ) );
}

void CustomAnimationEffectTabPage::clearSoundListBox()
{
	const sal_uInt32 nCount = maSoundList.Count();
	sal_uInt32 i;
	for( i = 0; i < nCount; i++ )
		delete (String*)maSoundList.GetObject( i );
	maSoundList.Clear();

	mpLBSound->Clear();
}

sal_Int32 CustomAnimationEffectTabPage::getSoundObject( const String& rStr )
{
	String aStrIn( rStr );
	aStrIn.ToLowerAscii();

	sal_uInt32 i;
	const sal_uInt32 nCount = maSoundList.Count();
	for( i = 0; i < nCount; i++ )
	{
		String aTmpStr( *(String*)maSoundList.GetObject( i ) );
		aTmpStr.ToLowerAscii();

		if( aTmpStr == aStrIn )
			return i+2;
	}

	return -1;
}

void CustomAnimationEffectTabPage::openSoundFileDialog()
{
	SdOpenSoundFileDialog	aFileDialog;

	String aFile( SvtPathOptions().GetGraphicPath() );
	aFileDialog.SetPath( aFile );

	bool bValidSoundFile = false;
	bool bQuitLoop = false;
	long nPos = 0;

	while( !bQuitLoop && (aFileDialog.Execute() == ERRCODE_NONE) )
	{
		aFile = aFileDialog.GetPath();
		nPos = getSoundObject( aFile );

		if( nPos < 0 ) // not in Soundliste
		{
			// try to insert in Gallery
			if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile ) )
			{
				clearSoundListBox();
				fillSoundListBox();

				nPos = getSoundObject( aFile );
				DBG_ASSERT( nPos >= 0, "sd::CustomAnimationEffectTabPage::openSoundFileDialog(), Recently inserted sound not in list!" );

				bValidSoundFile=true;
				bQuitLoop=true;
			}
			else
			{
				String aStrWarning(SdResId(STR_WARNING_NOSOUNDFILE));
				String aStr; aStr += sal_Unicode('%');
				aStrWarning.SearchAndReplace( aStr , aFile );
				WarningBox aWarningBox( NULL, WB_3DLOOK | WB_RETRY_CANCEL, aStrWarning );
				aWarningBox.SetModalInputMode (sal_True);
				bQuitLoop = aWarningBox.Execute()==RET_RETRY ? sal_False : sal_True;

				bValidSoundFile=false;
			}
		}
		else
		{
			bValidSoundFile=true;
			bQuitLoop=true;
		}
	}

	if( !bValidSoundFile )
		nPos = 0;

	mpLBSound->SelectEntryPos( (sal_uInt16) nPos );
}

void CustomAnimationEffectTabPage::onSoundPreview()
{
	const sal_uInt16 nPos = mpLBSound->GetSelectEntryPos();

	if( nPos >= 2 ) try
    {
		const OUString aSoundURL( *(String*)maSoundList.GetObject( nPos-2 ) );
                mxPlayer.set( avmedia::MediaWindow::createPlayer( aSoundURL ), uno::UNO_QUERY_THROW );
		mxPlayer->start();
	}
    catch( uno::Exception& e )
    {
		(void)e;
        DBG_ERROR("CustomAnimationEffectTabPage::onSoundPreview(), exception caught!" );
    }
}

class CustomAnimationDurationTabPage : public TabPage
{
public:
	CustomAnimationDurationTabPage( Window* pParent, const ResId& rResId, const STLPropertySet* pSet );
	~CustomAnimationDurationTabPage();

	void update( STLPropertySet* pSet );

	DECL_LINK( implControlHdl, Control* );

private:
	const STLPropertySet* mpSet;

	boost::shared_ptr< FixedText > mpFTStart;
	boost::shared_ptr< ListBox > mpLBStart;
	boost::shared_ptr< FixedText > mpFTStartDelay;
	boost::shared_ptr< MetricField > mpMFStartDelay;
	boost::shared_ptr< FixedText > mpFTDuration;
	boost::shared_ptr< ComboBox > mpCBDuration;
	boost::shared_ptr< FixedText > mpFTRepeat;
	boost::shared_ptr< ComboBox > mpCBRepeat;
	boost::shared_ptr< CheckBox > mpCBXRewind;
	boost::shared_ptr< FixedLine > mpFLTrigger;
	boost::shared_ptr< RadioButton > mpRBClickSequence;
	boost::shared_ptr< RadioButton > mpRBInteractive;
	boost::shared_ptr< ListBox > mpLBTrigger;
};

CustomAnimationDurationTabPage::CustomAnimationDurationTabPage(Window* pParent, const ResId& rResId, const STLPropertySet* pSet)
: TabPage( pParent, rResId ), mpSet( pSet )
{
	mpFTStart.reset( new FixedText( this, SdResId( FT_START ) ) );
	mpLBStart.reset( new ListBox( this, SdResId( LB_START ) ) );
	mpFTStartDelay.reset( new FixedText( this, SdResId( FT_START_DELAY ) ) );
	mpMFStartDelay.reset( new MetricField( this, SdResId( MF_START_DELAY ) ) );
	mpFTDuration.reset( new FixedText( this, SdResId( FT_DURATION ) ) );
	mpCBDuration.reset( new ComboBox( this, SdResId( CB_DURATION ) ) );
	mpFTRepeat.reset( new FixedText( this, SdResId( FT_REPEAT ) ) );
	mpCBRepeat.reset( new ComboBox( this, SdResId( CB_REPEAT ) ) );
	mpCBXRewind.reset( new CheckBox( this, SdResId( CBX_REWIND ) ) );
	mpFLTrigger.reset( new FixedLine( this, SdResId( FL_TRIGGER ) ) );
	mpRBClickSequence.reset( new RadioButton( this, SdResId( RB_CLICKSEQUENCE ) ) );
	mpRBInteractive.reset( new RadioButton( this, SdResId( RB_INTERACTIVE ) ) );
	mpLBTrigger.reset( new ListBox( this, SdResId( LB_TRIGGER ) ) );

	fillRepeatComboBox( mpCBRepeat.get() );
	fillDurationComboBox( mpCBDuration.get() );

	FreeResource();

    mpRBClickSequence->SetClickHdl( LINK( this, CustomAnimationDurationTabPage, implControlHdl ) );
    mpRBClickSequence->SetClickHdl( LINK( this, CustomAnimationDurationTabPage, implControlHdl ) );
    mpLBTrigger->SetSelectHdl( LINK( this, CustomAnimationDurationTabPage, implControlHdl ) );

	if( pSet->getPropertyState( nHandleStart ) != STLPropertyState_AMBIGUOUS )
	{
		sal_Int16 nStart = 0;
		pSet->getPropertyValue( nHandleStart ) >>= nStart;
		sal_uInt16 nPos = 0;
		switch( nStart )
		{
			case EffectNodeType::WITH_PREVIOUS:		nPos = 1; break;
			case EffectNodeType::AFTER_PREVIOUS:	nPos = 2; break;
		}
		mpLBStart->SelectEntryPos( nPos );
	}

	if( pSet->getPropertyState( nHandleBegin ) != STLPropertyState_AMBIGUOUS )
	{
		double fBegin = 0.0;
		pSet->getPropertyValue( nHandleBegin ) >>= fBegin;
		mpMFStartDelay->SetValue( (long)(fBegin*10) );
	}

	if( pSet->getPropertyState( nHandleDuration ) != STLPropertyState_AMBIGUOUS )
	{
		double fDuration = 0.0;
		pSet->getPropertyValue( nHandleDuration ) >>= fDuration;

		if( fDuration == 0.001 )
		{
			mpFTDuration->Disable();
			mpCBDuration->Disable();
			mpFTRepeat->Disable();
			mpCBRepeat->Disable();
			mpCBXRewind->Disable();
		}
		else
		{
			sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;

			if( fDuration == 5.0 )
				nPos = 0;
			else if( fDuration == 3.0 )
				nPos = 1;
			else if( fDuration == 2.0 )
				nPos = 2;
			else if( fDuration == 1.0 )
				nPos = 3;
			else if( fDuration == 0.5 )
				nPos = 4;

			if( nPos != LISTBOX_ENTRY_NOTFOUND )
				mpCBDuration->SelectEntryPos( nPos );
			else
				mpCBDuration->SetText( String::CreateFromDouble( fDuration ) );
		}
	}

	if( pSet->getPropertyState( nHandleRepeat ) != STLPropertyState_AMBIGUOUS )
	{
		Any aRepeatCount( pSet->getPropertyValue( nHandleRepeat ) );
		if( (aRepeatCount.getValueType() == ::getCppuType((const double*)0)) || !aRepeatCount.hasValue() )
		{
			double fRepeat = 0.0;
			if( aRepeatCount.hasValue() )
				aRepeatCount >>= fRepeat;

			sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;

			if( fRepeat == 0 )
				nPos = 0;
			else if( fRepeat == 2.0 )
				nPos = 1;
			else if( fRepeat == 3.0 )
				nPos = 2;
			else if( fRepeat == 4.0 )
				nPos = 3;
			else if( fRepeat == 5.0 )
				nPos = 4;
			else if( fRepeat == 10.0 )
				nPos = 5;

			if( nPos != LISTBOX_ENTRY_NOTFOUND )
				mpCBRepeat->SelectEntryPos( nPos );
			else
				mpCBRepeat->SetText( String::CreateFromDouble( fRepeat ) );
		}
		else if( aRepeatCount.getValueType() == ::getCppuType((const Timing*)0) )
		{
			Any aEnd;
			if( pSet->getPropertyState( nHandleEnd ) != STLPropertyState_AMBIGUOUS )
				aEnd = pSet->getPropertyValue( nHandleEnd );

			mpCBRepeat->SelectEntryPos( aEnd.hasValue() ? 6 : 7 );
		}
	}

	if( pSet->getPropertyState( nHandleRewind ) != STLPropertyState_AMBIGUOUS )
	{
		sal_Int16 nFill = 0;
		if( pSet->getPropertyValue( nHandleRewind ) >>= nFill )
		{
			mpCBXRewind->Check( (nFill == AnimationFill::REMOVE) ? sal_True : sal_False );
		}
		else
		{
			mpCBXRewind->SetState( STATE_DONTKNOW );
		}
	}

	Reference< XShape > xTrigger;

	if( pSet->getPropertyState( nHandleTrigger ) != STLPropertyState_AMBIGUOUS )
	{
		pSet->getPropertyValue( nHandleTrigger ) >>= xTrigger;

		mpRBInteractive->Check( xTrigger.is() );
		mpRBClickSequence->Check( !xTrigger.is() );
	}

	Reference< XDrawPage > xCurrentPage;
	pSet->getPropertyValue( nHandleCurrentPage ) >>= xCurrentPage;
	if( xCurrentPage.is() )
	{
		const OUString aStrIsEmptyPresObj( RTL_CONSTASCII_USTRINGPARAM( "IsEmptyPresentationObject" ) );

		sal_Int32 nShape, nCount = xCurrentPage->getCount();
		for( nShape = 0; nShape < nCount; nShape++ )
		{
			Reference< XShape > xShape( xCurrentPage->getByIndex( nShape ), UNO_QUERY );

			if( !xShape.is() )
				continue;

			Reference< XPropertySet > xSet( xShape, UNO_QUERY );
			if( xSet.is() && xSet->getPropertySetInfo()->hasPropertyByName( aStrIsEmptyPresObj ) )
			{
				sal_Bool bIsEmpty = sal_False;
				xSet->getPropertyValue( aStrIsEmptyPresObj ) >>= bIsEmpty;
				if( bIsEmpty )
					continue;
			}

			String aDescription( getShapeDescription( xShape, true ) );
			sal_uInt16 nPos = mpLBTrigger->InsertEntry( aDescription );

			mpLBTrigger->SetEntryData( nPos, (void*)nShape );
			if( xShape == xTrigger )
				mpLBTrigger->SelectEntryPos( nPos );
		}
	}
}

CustomAnimationDurationTabPage::~CustomAnimationDurationTabPage()
{
}

IMPL_LINK( CustomAnimationDurationTabPage, implControlHdl, Control*, pControl )
{
	if( pControl == mpLBTrigger.get() )
	{
		mpRBClickSequence->Check( sal_False );
		mpRBInteractive->Check( sal_True );
	}

	return 0;
}

void CustomAnimationDurationTabPage::update( STLPropertySet* pSet )
{
	sal_uInt16 nPos = mpLBStart->GetSelectEntryPos();
	if( nPos != LISTBOX_ENTRY_NOTFOUND )
	{
		sal_Int16 nStart;
		sal_Int16 nOldStart = -1;

		switch( nPos )
		{
		case 1: nStart = EffectNodeType::WITH_PREVIOUS; break;
		case 2: nStart = EffectNodeType::AFTER_PREVIOUS; break;
		default:
			nStart = EffectNodeType::ON_CLICK; break;
		}

		if(mpSet->getPropertyState( nHandleStart ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleStart ) >>= nOldStart;

		if( nStart != nOldStart )
			pSet->setPropertyValue( nHandleStart, makeAny( nStart ) );
	}

	// ---

	{
		double fBegin = static_cast<double>( mpMFStartDelay->GetValue()) / 10.0;
		double fOldBegin = -1.0;

		if( mpSet->getPropertyState( nHandleBegin ) != STLPropertyState_AMBIGUOUS )
			mpSet->getPropertyValue( nHandleBegin ) >>= fOldBegin;

		if( fBegin != fOldBegin )
			pSet->setPropertyValue( nHandleBegin, makeAny( fBegin ) );
	}

	// ---

	nPos = mpCBRepeat->GetSelectEntryPos();
	if( (nPos != LISTBOX_ENTRY_NOTFOUND) || (mpCBRepeat->GetText().Len() != 0) )
	{
		Any aRepeatCount;
		Any aEnd;

		switch( nPos )
		{
		case 0:
			break;
		case 6:
			{
				Event aEvent;
				aEvent.Trigger = EventTrigger::ON_NEXT;
				aEvent.Repeat = 0;
				aEnd <<= aEvent;
			}
			// ATTENTION: FALL THROUGH INTENDED!
		case 7:
			aRepeatCount <<= Timing_INDEFINITE;
			break;
		default:
			{
				String aText( mpCBRepeat->GetText() );
				if( aText.Len() )
					aRepeatCount <<= aText.ToDouble();
			}
		}

		Any aOldRepeatCount( aRepeatCount );
		if( mpSet->getPropertyState( nHandleRepeat ) != STLPropertyState_AMBIGUOUS )
			aOldRepeatCount = mpSet->getPropertyValue( nHandleRepeat );

		if( aRepeatCount != aOldRepeatCount )
			pSet->setPropertyValue( nHandleRepeat, aRepeatCount );

		Any aOldEnd( aEnd );
		if( mpSet->getPropertyState( nHandleEnd ) != STLPropertyState_AMBIGUOUS )
			aOldEnd = mpSet->getPropertyValue( nHandleEnd );

		if( aEnd != aOldEnd )
			pSet->setPropertyValue( nHandleEnd, aEnd );
	}

	// ---

	double fDuration = -1.0;
	nPos = mpCBDuration->GetSelectEntryPos();
	if( nPos != LISTBOX_ENTRY_NOTFOUND )
	{
		fDuration = *static_cast< const double * >( mpCBDuration->GetEntryData(nPos) );
	}
	else
	{
		String aText( mpCBDuration->GetText() );
		if( aText.Len() )
		{
			fDuration = aText.ToDouble();
		}
	}

	if( fDuration != -1.0 )
	{
		double fOldDuration = -1;

		if( mpSet->getPropertyState( nHandleDuration ) != STLPropertyState_AMBIGUOUS )
			mpSet->getPropertyValue( nHandleDuration ) >>= fOldDuration;

		if( fDuration != fOldDuration )
			pSet->setPropertyValue( nHandleDuration, makeAny( fDuration ) );
	}

	// ---

	if( mpCBXRewind->GetState() != STATE_DONTKNOW )
	{
		sal_Int16 nFill = mpCBXRewind->IsChecked() ? AnimationFill::REMOVE : AnimationFill::HOLD;

		bool bSet = true;

		if( mpSet->getPropertyState( nHandleRewind ) != STLPropertyState_AMBIGUOUS )
		{
			sal_Int16 nOldFill = 0;
			mpSet->getPropertyValue( nHandleRewind ) >>= nOldFill;
			bSet = nFill != nOldFill;
		}

		if( bSet )
			pSet->setPropertyValue( nHandleRewind, makeAny( nFill ) );
	}

	Reference< XShape > xTrigger;

	if( mpRBInteractive->IsChecked() )
	{
		nPos = mpLBTrigger->GetSelectEntryPos();
		if( nPos != LISTBOX_ENTRY_NOTFOUND )
		{
			sal_Int32 nShape = (sal_Int32)(sal_IntPtr)mpLBTrigger->GetEntryData( nPos );

			Reference< XDrawPage > xCurrentPage;
			mpSet->getPropertyValue( nHandleCurrentPage ) >>= xCurrentPage;

			if( xCurrentPage.is() && (nShape >= 0) && (nShape < xCurrentPage->getCount()) )
				xCurrentPage->getByIndex( nShape ) >>= xTrigger;
		}
	}


	if( xTrigger.is() || mpRBClickSequence->IsChecked() )
	{
		Any aNewValue( makeAny( xTrigger ) );
		Any aOldValue;

		if( mpSet->getPropertyState( nHandleTrigger ) != STLPropertyState_AMBIGUOUS )
			aOldValue = mpSet->getPropertyValue( nHandleTrigger );

		if( aNewValue != aOldValue )
			pSet->setPropertyValue( nHandleTrigger, aNewValue );
	}
}

class CustomAnimationTextAnimTabPage : public TabPage
{
public:
	CustomAnimationTextAnimTabPage( Window* pParent, const ResId& rResId, const STLPropertySet* pSet );

	void update( STLPropertySet* pSet );

	void updateControlStates();
	DECL_LINK( implSelectHdl, Control* );

private:
	FixedText	maFTGroupText;
	ListBox		maLBGroupText;
	CheckBox	maCBXGroupAuto;
	MetricField	maMFGroupAuto;
	CheckBox	maCBXAnimateForm;
	CheckBox	maCBXReverse;

	const STLPropertySet* mpSet;

	bool mbHasVisibleShapes;
};

CustomAnimationTextAnimTabPage::CustomAnimationTextAnimTabPage(Window* pParent, const ResId& rResId, const STLPropertySet* pSet)
:	TabPage( pParent, rResId ),
	maFTGroupText( this, SdResId( FT_GROUP_TEXT ) ),
	maLBGroupText( this, SdResId( LB_GROUP_TEXT ) ),
	maCBXGroupAuto( this, SdResId( CBX_GROUP_AUTO ) ),
	maMFGroupAuto( this, SdResId( MF_GROUP_AUTO ) ),
	maCBXAnimateForm( this, SdResId( CBX_ANIMATE_FORM ) ),
	maCBXReverse( this, SdResId( CBX_REVERSE ) ),
	mpSet( pSet ),
	mbHasVisibleShapes(true)
{
	FreeResource();

	maLBGroupText.SetSelectHdl( LINK( this, CustomAnimationTextAnimTabPage, implSelectHdl ) );

	if( pSet->getPropertyState( nHandleTextGrouping ) != STLPropertyState_AMBIGUOUS )
	{
		sal_Int32 nTextGrouping = 0;
		if( pSet->getPropertyValue( nHandleTextGrouping ) >>= nTextGrouping )
			maLBGroupText.SelectEntryPos( (sal_uInt16)(nTextGrouping + 1) );
	}

	if( pSet->getPropertyState( nHandleHasVisibleShape ) != STLPropertyState_AMBIGUOUS )
		pSet->getPropertyValue( nHandleHasVisibleShape ) >>= mbHasVisibleShapes;

	if( pSet->getPropertyState( nHandleTextGroupingAuto ) != STLPropertyState_AMBIGUOUS )
	{
		double fTextGroupingAuto = 0.0;
		if( pSet->getPropertyValue( nHandleTextGroupingAuto ) >>= fTextGroupingAuto )
		{
			maCBXGroupAuto.Check( fTextGroupingAuto >= 0.0 );
			if( fTextGroupingAuto >= 0.0 )
				maMFGroupAuto.SetValue( (long)(fTextGroupingAuto*10) );
		}
	}
	else
	{
		maCBXGroupAuto.SetState( STATE_DONTKNOW );
	}

	maCBXAnimateForm.SetState( STATE_DONTKNOW );
	if( pSet->getPropertyState( nHandleAnimateForm ) != STLPropertyState_AMBIGUOUS )
	{
		sal_Bool bAnimateForm = sal_False;
		if( pSet->getPropertyValue( nHandleAnimateForm ) >>= bAnimateForm )
		{
			maCBXAnimateForm.Check( bAnimateForm );
		}
	}
	else
	{
		maCBXAnimateForm.Enable( sal_False );
	}

	maCBXReverse.SetState( STATE_DONTKNOW );
	if( pSet->getPropertyState( nHandleTextReverse ) != STLPropertyState_AMBIGUOUS )
	{
		sal_Bool bTextReverse = sal_False;
		if( pSet->getPropertyValue( nHandleTextReverse ) >>= bTextReverse )
		{
			maCBXReverse.Check( bTextReverse );
		}
	}

	if( pSet->getPropertyState( nHandleMaxParaDepth ) == STLPropertyState_DIRECT )
	{
		sal_Int32 nMaxParaDepth = 0;
		pSet->getPropertyValue( nHandleMaxParaDepth ) >>= nMaxParaDepth;
		nMaxParaDepth += 1;

		sal_Int32 nPos = 6;
		while( (nPos > 2) && (nPos > nMaxParaDepth) )
		{
			maLBGroupText.RemoveEntry( (sal_uInt16)nPos );
			nPos--;
		}
	}

	updateControlStates();
}

void CustomAnimationTextAnimTabPage::update( STLPropertySet* pSet )
{
	sal_uInt16 nPos = maLBGroupText.GetSelectEntryPos();
	if( nPos != LISTBOX_ENTRY_NOTFOUND )
	{
		sal_Int32 nTextGrouping = nPos - 1;
		sal_Int32 nOldGrouping = -2;

		if(mpSet->getPropertyState( nHandleTextGrouping ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleTextGrouping ) >>= nOldGrouping;

		if( nTextGrouping != nOldGrouping )
			pSet->setPropertyValue( nHandleTextGrouping, makeAny( nTextGrouping ) );
	}

	if( nPos > 0 )
	{
		sal_Bool bTextReverse = maCBXReverse.IsChecked();
		sal_Bool bOldTextReverse = !bTextReverse;

		if(mpSet->getPropertyState( nHandleTextReverse ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleTextReverse ) >>= bOldTextReverse;

		if( bTextReverse != bOldTextReverse )
			pSet->setPropertyValue( nHandleTextReverse, makeAny( bTextReverse ) );

		if( nPos > 1 )
		{
			double fTextGroupingAuto = maCBXGroupAuto.IsChecked() ? maMFGroupAuto.GetValue() / 10.0 : -1.0;
			double fOldTextGroupingAuto = -2.0;

			if(mpSet->getPropertyState( nHandleTextGroupingAuto ) != STLPropertyState_AMBIGUOUS)
				mpSet->getPropertyValue( nHandleTextGroupingAuto ) >>= fOldTextGroupingAuto;

			if( fTextGroupingAuto != fOldTextGroupingAuto )
				pSet->setPropertyValue( nHandleTextGroupingAuto, makeAny( fTextGroupingAuto ) );
		}
	}
	//bug 120049
	//[crash] Aoo crash when modify the "Random effects" animation effect's trigger condition to "Start effect on click of" .
	//If this control is disabled, we should ignore its value
	if (maCBXAnimateForm.IsEnabled())
	{
		sal_Bool bAnimateForm = maCBXAnimateForm.IsChecked();
		sal_Bool bOldAnimateForm = !bAnimateForm;

		if(mpSet->getPropertyState( nHandleAnimateForm ) != STLPropertyState_AMBIGUOUS)
			mpSet->getPropertyValue( nHandleAnimateForm ) >>= bOldAnimateForm;

		if( bAnimateForm != bOldAnimateForm )
			pSet->setPropertyValue( nHandleAnimateForm, makeAny( bAnimateForm ) );
	}
}

void CustomAnimationTextAnimTabPage::updateControlStates()
{
	sal_uInt16 nPos = maLBGroupText.GetSelectEntryPos();

	maCBXGroupAuto.Enable( nPos > 1 );
	maMFGroupAuto.Enable( nPos > 1 );
	maCBXReverse.Enable( nPos > 0 );

	if( !mbHasVisibleShapes && nPos > 0 )
	{
		maCBXAnimateForm.Check(sal_False);
		maCBXAnimateForm.Enable(sal_False);
	}
	else
	{
		maCBXAnimateForm.Enable(sal_True);
	}
}

IMPL_LINK( CustomAnimationTextAnimTabPage, implSelectHdl, Control*, EMPTYARG )
{
	updateControlStates();
	return 0;
}

// --------------------------------------------------------------------

CustomAnimationDialog::CustomAnimationDialog( Window* pParent, STLPropertySet* pSet, sal_uInt16 nPage /* = 0 */  )
: TabDialog( pParent, SdResId( DLG_CUSTOMANIMATION ) ), mpSet( pSet ), mpResultSet( 0 )
{
	mpTabControl = new TabControl( this, SdResId( 1 ) );
	mpOKButton = new OKButton(this, SdResId( 1 ) ) ;
	mpCancelButton = new CancelButton(this, SdResId( 1 ) );
	mpHelpButton = new HelpButton(this, SdResId( 1 ) );

	FreeResource();

	mpEffectTabPage = new CustomAnimationEffectTabPage( mpTabControl, SdResId( RID_TP_CUSTOMANIMATION_EFFECT ), mpSet );
	mpTabControl->SetTabPage( RID_TP_CUSTOMANIMATION_EFFECT, mpEffectTabPage );
	mpDurationTabPage = new CustomAnimationDurationTabPage( mpTabControl, SdResId( RID_TP_CUSTOMANIMATION_DURATION ), mpSet );
	mpTabControl->SetTabPage( RID_TP_CUSTOMANIMATION_DURATION, mpDurationTabPage );

	sal_Bool bHasText = sal_False;
	if( pSet->getPropertyState( nHandleHasText ) != STLPropertyState_AMBIGUOUS )
		pSet->getPropertyValue( nHandleHasText ) >>= bHasText;

	if( bHasText )
	{
		mpTextAnimTabPage = new CustomAnimationTextAnimTabPage( mpTabControl, SdResId( RID_TP_CUSTOMANIMATION_TEXT ), mpSet );
		mpTabControl->SetTabPage( RID_TP_CUSTOMANIMATION_TEXT, mpTextAnimTabPage );
	}
	else
	{
		mpTextAnimTabPage = 0;
		mpTabControl->RemovePage( RID_TP_CUSTOMANIMATION_TEXT );
	}

	if( nPage )
		mpTabControl->SelectTabPage( nPage );
}

CustomAnimationDialog::~CustomAnimationDialog()
{
	delete mpEffectTabPage;
	delete mpDurationTabPage;
	delete mpTextAnimTabPage;

	delete mpTabControl;
	delete mpOKButton;
	delete mpCancelButton;
	delete mpHelpButton;

	delete mpSet;
	delete mpResultSet;
}

STLPropertySet* CustomAnimationDialog::getResultSet()
{
	if( mpResultSet )
		delete mpResultSet;

	mpResultSet = createDefaultSet();

	mpEffectTabPage->update( mpResultSet );
	mpDurationTabPage->update( mpResultSet );
	if( mpTextAnimTabPage )
		mpTextAnimTabPage->update( mpResultSet );

	return mpResultSet;
}

STLPropertySet* CustomAnimationDialog::createDefaultSet()
{
	Any aEmpty;

	STLPropertySet* pSet = new STLPropertySet();
	pSet->setPropertyDefaultValue( nHandleMaxParaDepth, makeAny( (sal_Int32)-1 ) );

	pSet->setPropertyDefaultValue( nHandleHasAfterEffect, makeAny( (sal_Bool)sal_False ) );
	pSet->setPropertyDefaultValue( nHandleAfterEffectOnNextEffect, makeAny( (sal_Bool)sal_False ) );
	pSet->setPropertyDefaultValue( nHandleDimColor, aEmpty );
	pSet->setPropertyDefaultValue( nHandleIterateType, makeAny( (sal_Int16)0 ) );
	pSet->setPropertyDefaultValue( nHandleIterateInterval, makeAny( (double)0.0 ) );

	pSet->setPropertyDefaultValue( nHandleStart, makeAny( (sal_Int16)EffectNodeType::ON_CLICK ) );
	pSet->setPropertyDefaultValue( nHandleBegin, makeAny( (double)0.0 ) );
	pSet->setPropertyDefaultValue( nHandleDuration, makeAny( (double)2.0 ) );
	pSet->setPropertyDefaultValue( nHandleRepeat, aEmpty );
	pSet->setPropertyDefaultValue( nHandleRewind, makeAny( AnimationFill::HOLD ) );

	pSet->setPropertyDefaultValue( nHandleEnd, aEmpty );

	pSet->setPropertyDefaultValue( nHandlePresetId, aEmpty );
	pSet->setPropertyDefaultValue( nHandleProperty1Type, makeAny( nPropertyTypeNone ) );
	pSet->setPropertyDefaultValue( nHandleProperty1Value, aEmpty );
	pSet->setPropertyDefaultValue( nHandleProperty2Type, makeAny( nPropertyTypeNone ) );
	pSet->setPropertyDefaultValue( nHandleProperty2Value, aEmpty );
	pSet->setPropertyDefaultValue( nHandleAccelerate, aEmpty );
	pSet->setPropertyDefaultValue( nHandleDecelerate, aEmpty );
	pSet->setPropertyDefaultValue( nHandleAutoReverse, aEmpty );
	pSet->setPropertyDefaultValue( nHandleTrigger, aEmpty );

	pSet->setPropertyDefaultValue( nHandleHasText, makeAny( sal_False ) );
	pSet->setPropertyDefaultValue( nHandleHasVisibleShape, makeAny( sal_False ) );
	pSet->setPropertyDefaultValue( nHandleTextGrouping, makeAny( (sal_Int32)-1 ) );
	pSet->setPropertyDefaultValue( nHandleAnimateForm, makeAny( sal_True ) );
	pSet->setPropertyDefaultValue( nHandleTextGroupingAuto, makeAny( (double)-1.0 ) );
	pSet->setPropertyDefaultValue( nHandleTextReverse, makeAny( sal_False ) );

	pSet->setPropertyDefaultValue( nHandleCurrentPage, aEmpty );

	pSet->setPropertyDefaultValue( nHandleSoundURL, aEmpty );
	pSet->setPropertyDefaultValue( nHandleSoundVolumne, makeAny( (double)1.0) );
	pSet->setPropertyDefaultValue( nHandleSoundEndAfterSlide, makeAny( (sal_Int32)0 ) );

	pSet->setPropertyDefaultValue( nHandleCommand, makeAny( (sal_Int16)0 ) );
	return pSet;
}

PropertyControl::PropertyControl( Window* pParent, const ResId& rResId )
: ListBox( pParent, rResId ), mpSubControl(0)
{
}

PropertyControl::~PropertyControl()
{
	if( mpSubControl )
		delete mpSubControl;
}

void PropertyControl::setSubControl( PropertySubControl* pSubControl )
{
	if( mpSubControl && mpSubControl != pSubControl )
		delete mpSubControl;

	mpSubControl = pSubControl;

	Control* pControl = pSubControl ? pSubControl->getControl() : 0;

	if( pControl )
	{
		pControl->SetPosSizePixel( GetPosPixel(), GetSizePixel() );
		pControl->SetZOrder( this, WINDOW_ZORDER_BEFOR );
		pControl->Show();
		Hide();
	}
	else
	{
		Show();
	}
}

void PropertyControl::Resize()
{
	Control* pControl = mpSubControl ? mpSubControl->getControl() : 0;
	if( pControl )
		pControl->SetPosSizePixel( GetPosPixel(), GetSizePixel() );
	ListBox::Resize();
}

// ====================================================================

PropertySubControl::~PropertySubControl()
{
}

PropertySubControl* PropertySubControl::create( sal_Int32 nType, Window* pParent, const Any& rValue, const OUString& rPresetId, const Link& rModifyHdl )
{
	PropertySubControl* pSubControl = NULL;
	switch( nType )
	{
	case nPropertyTypeDirection:
	case nPropertyTypeSpokes:
	case nPropertyTypeZoom:
		pSubControl = new PresetPropertyBox( nType, pParent, rValue, rPresetId, rModifyHdl );
		break;

	case nPropertyTypeColor:
	case nPropertyTypeFillColor:
	case nPropertyTypeFirstColor:
	case nPropertyTypeCharColor:
	case nPropertyTypeLineColor:
		pSubControl = new ColorPropertyBox( nType, pParent, rValue, rModifyHdl );
		break;

	case nPropertyTypeFont:
		pSubControl = new FontPropertyBox( nType, pParent, rValue, rModifyHdl );
		break;

	case nPropertyTypeCharHeight:
		pSubControl = new CharHeightPropertyBox( nType, pParent, rValue, rModifyHdl );
		break;

	case nPropertyTypeRotate:
		pSubControl = new RotationPropertyBox( nType, pParent, rValue, rModifyHdl );
		break;

	case nPropertyTypeTransparency:
		pSubControl = new TransparencyPropertyBox( nType, pParent, rValue, rModifyHdl );
		break;

	case nPropertyTypeScale:
		pSubControl = new ScalePropertyBox( nType, pParent, rValue, rModifyHdl );
		break;

	case nPropertyTypeCharDecoration:
		pSubControl = new FontStylePropertyBox( nType, pParent, rValue, rModifyHdl );
		break;
	}

	return pSubControl;
}

}
