diff options
Diffstat (limited to 'sd/source/ui/animations')
26 files changed, 13181 insertions, 0 deletions
diff --git a/sd/source/ui/animations/CustomAnimation.hrc b/sd/source/ui/animations/CustomAnimation.hrc new file mode 100644 index 000000000000..bfe4e1d9c6d4 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimation.hrc @@ -0,0 +1,144 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_CUSTOMANIMATION_HRC +#define _SD_CUSTOMANIMATION_HRC + +#include "glob.hrc" + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// attention, we have 200 ids free after RID_CUSTOMANIMATION_START +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +#define DLG_CUSTOMANIMATIONPANE RID_CUSTOMANIMATION_START+0 +#define DLG_CUSTOMANIMATION RID_CUSTOMANIMATION_START+1 +#define DLG_CUSTOMANIMATION_CREATE RID_CUSTOMANIMATION_START+2 +#define DLG_SLIDE_TRANSITION_PANE RID_CUSTOMANIMATION_START+3 +#define DLG_CUSTOMANIMATION_SCHEMES_PANE RID_CUSTOMANIMATION_START+4 +#define DLG_ANIMATION_SCHEMES_PANE RID_CUSTOMANIMATION_START+5 + +#define RID_EFFECT_CONTEXTMENU RID_CUSTOMANIMATION_START+0 +#define RID_TP_CUSTOMANIMATION_EFFECT RID_CUSTOMANIMATION_START+1 +#define RID_TP_CUSTOMANIMATION_DURATION RID_CUSTOMANIMATION_START+2 +#define RID_TP_CUSTOMANIMATION_TEXT RID_CUSTOMANIMATION_START+3 +#define RID_TP_CUSTOMANIMATION_ENTRANCE RID_CUSTOMANIMATION_START+4 +#define RID_TP_CUSTOMANIMATION_EMPHASIS RID_CUSTOMANIMATION_START+5 +#define RID_TP_CUSTOMANIMATION_EXIT RID_CUSTOMANIMATION_START+6 +#define RID_TP_CUSTOMANIMATION_MOTIONPATH RID_CUSTOMANIMATION_START+7 +#define RID_TP_CUSTOMANIMATION_MISCEFFECTS RID_CUSTOMANIMATION_START+8 +#define RID_CUSTOMANIMATION_ROTATION_POPUP RID_CUSTOMANIMATION_START+9 +#define RID_CUSTOMANIMATION_FONTSIZE_POPUP RID_CUSTOMANIMATION_START+10 +#define RID_CUSTOMANIMATION_SCALE_POPUP RID_CUSTOMANIMATION_START+11 +#define RID_CUSTOMANIMATION_FONTSTYLE_POPUP RID_CUSTOMANIMATION_START+12 + +#define IMG_CUSTOMANIMATION_ON_CLICK RID_CUSTOMANIMATION_START+0 +#define IMG_CUSTOMANIMATION_ON_CLICK_H RID_CUSTOMANIMATION_START+1 +#define IMG_CUSTOMANIMATION_AFTER_PREVIOUS RID_CUSTOMANIMATION_START+2 +#define IMG_CUSTOMANIMATION_AFTER_PREVIOUS_H RID_CUSTOMANIMATION_START+3 +#define IMG_CUSTOMANIMATION_ENTRANCE_EFFECT RID_CUSTOMANIMATION_START+4 +#define IMG_CUSTOMANIMATION_ENTRANCE_EFFECT_H RID_CUSTOMANIMATION_START+5 +#define IMG_CUSTOMANIMATION_EMPHASIS_EFFECT RID_CUSTOMANIMATION_START+6 +#define IMG_CUSTOMANIMATION_EMPHASIS_EFFECT_H RID_CUSTOMANIMATION_START+7 +#define IMG_CUSTOMANIMATION_EXIT_EFFECT RID_CUSTOMANIMATION_START+8 +#define IMG_CUSTOMANIMATION_EXIT_EFFECT_H RID_CUSTOMANIMATION_START+9 +#define IMG_CUSTOMANIMATION_MOTION_PATH RID_CUSTOMANIMATION_START+10 +#define IMG_CUSTOMANIMATION_MOTION_PATH_H RID_CUSTOMANIMATION_START+11 +#define IMG_CUSTOMANIMATION_OLE RID_CUSTOMANIMATION_START+12 +#define IMG_CUSTOMANIMATION_OLE_H RID_CUSTOMANIMATION_START+13 +#define IMG_CUSTOMANIMATION_MEDIA_PLAY RID_CUSTOMANIMATION_START+14 +#define IMG_CUSTOMANIMATION_MEDIA_PLAY_H RID_CUSTOMANIMATION_START+15 +#define IMG_CUSTOMANIMATION_MEDIA_PAUSE RID_CUSTOMANIMATION_START+16 +#define IMG_CUSTOMANIMATION_MEDIA_PAUSE_H RID_CUSTOMANIMATION_START+17 +#define IMG_CUSTOMANIMATION_MEDIA_STOP RID_CUSTOMANIMATION_START+18 +#define IMG_CUSTOMANIMATION_MEDIA_STOP_H RID_CUSTOMANIMATION_START+19 + +#define STR_CUSTOMANIMATION_DURATION_VERY_SLOW RID_CUSTOMANIMATION_START+0 +#define STR_CUSTOMANIMATION_DURATION_SLOW RID_CUSTOMANIMATION_START+1 +#define STR_CUSTOMANIMATION_DURATION_NORMAL RID_CUSTOMANIMATION_START+2 +#define STR_CUSTOMANIMATION_DURATION_FAST RID_CUSTOMANIMATION_START+3 +#define STR_CUSTOMANIMATION_DURATION_VERY_FAST RID_CUSTOMANIMATION_START+4 +#define STR_CUSTOMANIMATION_REPEAT_NONE RID_CUSTOMANIMATION_START+5 +#define STR_CUSTOMANIMATION_REPEAT_UNTIL_NEXT_CLICK RID_CUSTOMANIMATION_START+6 +#define STR_CUSTOMANIMATION_REPEAT_UNTIL_END_OF_SLIDE RID_CUSTOMANIMATION_START+7 +#define STR_CUSTOMANIMATION_DIRECTION_PROPERTY RID_CUSTOMANIMATION_START+8 +#define STR_CUSTOMANIMATION_ZOOM_PROPERTY RID_CUSTOMANIMATION_START+9 +#define STR_CUSTOMANIMATION_SPOKES_PROPERTY RID_CUSTOMANIMATION_START+10 +#define STR_CUSTOMANIMATION_FIRST_COLOR_PROPERTY RID_CUSTOMANIMATION_START+11 +#define STR_CUSTOMANIMATION_SECOND_COLOR_PROPERTY RID_CUSTOMANIMATION_START+12 +#define STR_CUSTOMANIMATION_FILL_COLOR_PROPERTY RID_CUSTOMANIMATION_START+13 +#define STR_CUSTOMANIMATION_STYLE_PROPERTY RID_CUSTOMANIMATION_START+14 +#define STR_CUSTOMANIMATION_FONT_PROPERTY RID_CUSTOMANIMATION_START+15 +#define STR_CUSTOMANIMATION_FONT_COLOR_PROPERTY RID_CUSTOMANIMATION_START+16 +#define STR_CUSTOMANIMATION_FONT_SIZE_STYLE_PROPERTY RID_CUSTOMANIMATION_START+17 +#define STR_CUSTOMANIMATION_FONT_STYLE_PROPERTY RID_CUSTOMANIMATION_START+18 +#define STR_CUSTOMANIMATION_LINE_COLOR_PROPERTY RID_CUSTOMANIMATION_START+19 +#define STR_CUSTOMANIMATION_SIZE_PROPERTY RID_CUSTOMANIMATION_START+20 +#define STR_CUSTOMANIMATION_AMOUNT_PROPERTY RID_CUSTOMANIMATION_START+21 +#define STR_CUSTOMANIMATION_COLOR_PROPERTY RID_CUSTOMANIMATION_START+22 +#define STR_CUSTOMANIMATION_NO_SOUND RID_CUSTOMANIMATION_START+23 +#define STR_CUSTOMANIMATION_STOP_PREVIOUS_SOUND RID_CUSTOMANIMATION_START+24 +#define STR_CUSTOMANIMATION_SCALE_PROPERTY RID_CUSTOMANIMATION_START+25 +#define STR_CUSTOMANIMATION_SAMPLE RID_CUSTOMANIMATION_START+26 +#define STR_CUSTOMANIMATION_BROWSE_SOUND RID_CUSTOMANIMATION_START+27 +#define STR_CUSTOMANIMATION_1_SPOKES RID_CUSTOMANIMATION_START+28 +#define STR_CUSTOMANIMATION_2_SPOKES RID_CUSTOMANIMATION_START+29 +#define STR_CUSTOMANIMATION_3_SPOKES RID_CUSTOMANIMATION_START+30 +#define STR_CUSTOMANIMATION_4_SPOKES RID_CUSTOMANIMATION_START+31 +#define STR_CUSTOMANIMATION_8_SPOKES RID_CUSTOMANIMATION_START+32 +#define STR_CUSTOMANIMATION_INSTANT RID_CUSTOMANIMATION_START+33 +#define STR_CUSTOMANIMATION_GRADUAL RID_CUSTOMANIMATION_START+34 +#define STR_CUSTOMANIMATION_TRIGGER RID_CUSTOMANIMATION_START+35 +#define STR_CUSTOMANIMATION_LIST_HELPTEXT RID_CUSTOMANIMATION_START+36 + +#define CM_WITH_CLICK 1 +#define CM_WITH_PREVIOUS 2 +#define CM_AFTER_PREVIOUS 3 +#define CM_OPTIONS 4 +#define CM_DURATION 5 +#define CM_REMOVE 6 +#define CM_CREATE 7 + +#define CM_QUARTER_SPIN 1 +#define CM_HALF_SPIN 2 +#define CM_FULL_SPIN 3 +#define CM_TWO_SPINS 4 +#define CM_CLOCKWISE 5 +#define CM_COUNTERCLOCKWISE 6 + +#define CM_SIZE_25 25 +#define CM_SIZE_50 50 +#define CM_SIZE_150 150 +#define CM_SIZE_400 400 +#define CM_HORIZONTAL 1 +#define CM_VERTICAL 2 +#define CM_BOTH 3 + +#define CM_BOLD 1 +#define CM_ITALIC 2 +#define CM_UNDERLINED 3 + +#endif // _SD_CUSTOMANIMATION_HRC diff --git a/sd/source/ui/animations/CustomAnimation.src b/sd/source/ui/animations/CustomAnimation.src new file mode 100644 index 000000000000..449107f05c75 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimation.src @@ -0,0 +1,495 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "CustomAnimation.hrc" + +Menu RID_EFFECT_CONTEXTMENU +{ + ItemList = + { + MenuItem + { + Identifier = CM_WITH_CLICK ; + Text [ en-US ] = "Start On ~Click" ; + }; + MenuItem + { + Identifier = CM_WITH_PREVIOUS ; + Text [ en-US ] = "Start ~With Previous" ; + }; + MenuItem + { + Identifier = CM_AFTER_PREVIOUS; + Text [ en-US ] = "Start ~After Previous" ; + }; + MenuItem + { + Separator = TRUE ; + }; + MenuItem + { + Identifier = CM_OPTIONS; + Text [ en-US ] = "~Effect Options..." ; + }; + MenuItem + { + Identifier = CM_DURATION; + Text [ en-US ] = "~Timing..." ; + }; + MenuItem + { + Identifier = CM_REMOVE; + Text [ en-US ] = "~Remove" ; + }; + }; +}; + +Menu RID_CUSTOMANIMATION_FONTSIZE_POPUP +{ + ItemList = + { + MenuItem + { + Identifier = CM_SIZE_25 ; + Text [ en-US ] = "Tiny" ; + }; + MenuItem + { + Identifier = CM_SIZE_50 ; + Text [ en-US ] = "Smaller" ; + }; + MenuItem + { + Identifier = CM_SIZE_150 ; + Text [ en-US ] = "Larger" ; + }; + MenuItem + { + Identifier = CM_SIZE_400 ; + Text [ en-US ] = "Extra large" ; + }; + }; +}; + +Menu RID_CUSTOMANIMATION_SCALE_POPUP +{ + ItemList = + { + MenuItem + { + Identifier = CM_SIZE_25 ; + Text [ en-US ] = "Tiny" ; + }; + MenuItem + { + Identifier = CM_SIZE_50 ; + Text [ en-US ] = "Smaller" ; + }; + MenuItem + { + Identifier = CM_SIZE_150 ; + Text [ en-US ] = "Larger" ; + }; + MenuItem + { + Identifier = CM_SIZE_400 ; + Text [ en-US ] = "Extra large" ; + }; + MenuItem + { + Separator = TRUE ; + }; + MenuItem + { + Identifier = CM_HORIZONTAL ; + Text [ en-US ] = "Horizontal" ; + + }; + MenuItem + { + Identifier = CM_VERTICAL ; + Text [ en-US ] = "Vertical" ; + + }; + MenuItem + { + Identifier = CM_BOTH ; + Text [ en-US ] = "Both" ; + + }; + }; +}; + +Menu RID_CUSTOMANIMATION_ROTATION_POPUP +{ + ItemList = + { + MenuItem + { + Identifier = CM_QUARTER_SPIN ; + Text [ en-US ] = "Quarter spin" ; + }; + MenuItem + { + Identifier = CM_HALF_SPIN ; + Text [ en-US ] = "Half spin" ; + }; + MenuItem + { + Identifier = CM_FULL_SPIN; + Text [ en-US ] = "Full spin" ; + }; + MenuItem + { + Identifier = CM_TWO_SPINS; + Text [ en-US ] = "Two spins" ; + }; + MenuItem + { + Separator = TRUE ; + }; + MenuItem + { + Identifier = CM_CLOCKWISE; + Text [ en-US ] = "Clockwise" ; + }; + MenuItem + { + Identifier = CM_COUNTERCLOCKWISE; + Text [ en-US ] = "Counter-clockwise" ; + }; + }; +}; + +Menu RID_CUSTOMANIMATION_FONTSTYLE_POPUP +{ + ItemList = + { + MenuItem + { + Identifier = CM_BOLD ; + Text [ en-US ] = "Bold" ; + }; + MenuItem + { + Identifier = CM_ITALIC ; + Text [ en-US ] = "Italic" ; + }; + MenuItem + { + Identifier = CM_UNDERLINED ; + Text [ en-US ] = "Underlined" ; + }; + }; +}; + +String STR_CUSTOMANIMATION_DURATION_VERY_SLOW +{ + Text [ en-US ] = "Very slow"; +}; + +String STR_CUSTOMANIMATION_DURATION_SLOW +{ + Text [ en-US ] = "Slow"; +}; + +String STR_CUSTOMANIMATION_DURATION_NORMAL +{ + Text [ en-US ] = "Medium"; +}; + +String STR_CUSTOMANIMATION_DURATION_FAST +{ + Text [ en-US ] = "Fast"; +}; + +String STR_CUSTOMANIMATION_DURATION_VERY_FAST +{ + Text [ en-US ] = "Very fast"; +}; + +String STR_CUSTOMANIMATION_REPEAT_NONE +{ + Text [ en-US ] = "none"; +}; + +String STR_CUSTOMANIMATION_REPEAT_UNTIL_NEXT_CLICK +{ + Text [ en-US ] = "Until next click"; +}; + +String STR_CUSTOMANIMATION_REPEAT_UNTIL_END_OF_SLIDE +{ + Text [ en-US ] = "Until end of slide"; +}; + +String STR_CUSTOMANIMATION_DIRECTION_PROPERTY +{ + Text [ en-US ] = "Direction"; +}; + +String STR_CUSTOMANIMATION_ZOOM_PROPERTY +{ + Text [ en-US ] = "Zoom"; +}; + +String STR_CUSTOMANIMATION_SPOKES_PROPERTY +{ + Text [ en-US ] = "Spokes"; +}; + +String STR_CUSTOMANIMATION_FIRST_COLOR_PROPERTY +{ + Text [ en-US ] = "First color"; +}; + +String STR_CUSTOMANIMATION_SECOND_COLOR_PROPERTY +{ + Text [ en-US ] = "Second color"; +}; + +String STR_CUSTOMANIMATION_FILL_COLOR_PROPERTY +{ + Text [ en-US ] = "Fill color"; +}; + +String STR_CUSTOMANIMATION_STYLE_PROPERTY +{ + Text [ en-US ] = "Style"; +}; + +String STR_CUSTOMANIMATION_FONT_PROPERTY +{ + Text [ en-US ] = "Font"; +}; + +String STR_CUSTOMANIMATION_FONT_COLOR_PROPERTY +{ + Text [ en-US ] = "Font color"; +}; + +String STR_CUSTOMANIMATION_FONT_SIZE_STYLE_PROPERTY +{ + Text [ en-US ] = "Style"; +}; + +String STR_CUSTOMANIMATION_FONT_STYLE_PROPERTY +{ + Text [ en-US ] = "Typeface"; +}; + +String STR_CUSTOMANIMATION_LINE_COLOR_PROPERTY +{ + Text [ en-US ] = "Line color"; +}; + +String STR_CUSTOMANIMATION_SIZE_PROPERTY +{ + Text [ en-US ] = "Font size"; +}; + +String STR_CUSTOMANIMATION_SCALE_PROPERTY +{ + Text [ en-US ] = "Size"; +}; + +String STR_CUSTOMANIMATION_AMOUNT_PROPERTY +{ + Text [ en-US ] = "Amount"; +}; + +String STR_CUSTOMANIMATION_COLOR_PROPERTY +{ + Text [ en-US ] = "Color"; +}; + +String STR_CUSTOMANIMATION_NO_SOUND +{ + Text [ en-US ] = "(No sound)"; +}; + +String STR_CUSTOMANIMATION_STOP_PREVIOUS_SOUND +{ + Text [ en-US ] = "(Stop previous sound)"; +}; + +String STR_CUSTOMANIMATION_BROWSE_SOUND +{ + Text [ en-US ] = "Other sound..."; +}; + +String STR_CUSTOMANIMATION_SAMPLE +{ + Text [ en-US ] = "Sample"; +}; + +String STR_CUSTOMANIMATION_1_SPOKES +{ + Text [ en-US ] = "1 Spoke"; +}; + +String STR_CUSTOMANIMATION_2_SPOKES +{ + Text [ en-US ] = "2 Spokes"; +}; + +String STR_CUSTOMANIMATION_3_SPOKES +{ + Text [ en-US ] = "3 Spokes"; +}; + +String STR_CUSTOMANIMATION_4_SPOKES +{ + Text [ en-US ] = "4 Spokes"; +}; + +String STR_CUSTOMANIMATION_8_SPOKES +{ + Text [ en-US ] = "8 Spokes"; +}; + +String STR_CUSTOMANIMATION_INSTANT +{ + Text [ en-US ] = "Instant"; +}; + +String STR_CUSTOMANIMATION_GRADUAL +{ + Text [ en-US ] = "Gradual"; +}; + +String STR_CUSTOMANIMATION_TRIGGER +{ + Text [ en-US ] = "Trigger"; +}; + +String STR_CUSTOMANIMATION_LIST_HELPTEXT +{ + Text [ en-US ] = "First select the slide element and then click 'Add...' to add an animation effect."; +}; + +Image IMG_CUSTOMANIMATION_ON_CLICK +{ + ImageBitmap = Bitmap { File = "click_16.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_ON_CLICK_H +{ + ImageBitmap = Bitmap { File = "click_16_h.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_AFTER_PREVIOUS +{ + ImageBitmap = Bitmap { File = "time_16.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_AFTER_PREVIOUS_H +{ + ImageBitmap = Bitmap { File = "time_16_h.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_ENTRANCE_EFFECT +{ + ImageBitmap = Bitmap { File = "effect_16.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_ENTRANCE_EFFECT_H +{ + ImageBitmap = Bitmap { File = "effect_16_h.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_EMPHASIS_EFFECT +{ + ImageBitmap = Bitmap { File = "effectshape_16.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_EMPHASIS_EFFECT_H +{ + ImageBitmap = Bitmap { File = "effectshape_16_h.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_EXIT_EFFECT +{ + ImageBitmap = Bitmap { File = "effectfade_16.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_EXIT_EFFECT_H +{ + ImageBitmap = Bitmap { File = "effectfade_16_h.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_MOTION_PATH +{ + ImageBitmap = Bitmap { File = "effectpath_16.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_MOTION_PATH_H +{ + ImageBitmap = Bitmap { File = "effectpath_16_h.png" ; }; +}; + +Image IMG_CUSTOMANIMATION_OLE +{ + ImageBitmap = Bitmap { File = "effectole_16.png"; } ; +}; + +Image IMG_CUSTOMANIMATION_OLE_H +{ + ImageBitmap = Bitmap { File = "effectole_16_h.png"; } ; +}; + +Image IMG_CUSTOMANIMATION_MEDIA_PLAY +{ + ImageBitmap = Bitmap { File = "playblue_16.png"; } ; +}; + +Image IMG_CUSTOMANIMATION_MEDIA_PLAY_H +{ + ImageBitmap = Bitmap { File = "playblue_16_h.png"; } ; +}; + +Image IMG_CUSTOMANIMATION_MEDIA_PAUSE +{ + ImageBitmap = Bitmap { File = "breakplayingblue_16.png"; } ; +}; + +Image IMG_CUSTOMANIMATION_MEDIA_PAUSE_H +{ + ImageBitmap = Bitmap { File = "breakplayingblue_16_h.png"; } ; +}; + +Image IMG_CUSTOMANIMATION_MEDIA_STOP +{ + ImageBitmap = Bitmap { File = "stopplayingblue_16.png"; } ; +}; + +Image IMG_CUSTOMANIMATION_MEDIA_STOP_H +{ + ImageBitmap = Bitmap { File = "stopplayingblue_16_h.png"; } ; +}; + + diff --git a/sd/source/ui/animations/CustomAnimationCreateDialog.cxx b/sd/source/ui/animations/CustomAnimationCreateDialog.cxx new file mode 100755 index 000000000000..430f3f7f6a9e --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationCreateDialog.cxx @@ -0,0 +1,713 @@ +/************************************************************************* + * + * 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" + +#ifndef _COM_SUN_STAR_UTIL_XCOLLATOR_HPP_ +#include <com/sun/star/i18n/XCollator.hpp> +#endif + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <vcl/svapp.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/tabpage.hxx> + +#ifndef _SV_BUTTON_HXX +#include <vcl/button.hxx> +#endif +#include <vcl/fixed.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/combobox.hxx> +#include <svtools/valueset.hxx> + +#include <svx/svdetc.hxx> +#include <svx/svdstr.hrc> +#include "sdresid.hxx" +#include <unotools/viewoptions.hxx> +#include <com/sun/star/presentation/EffectNodeType.hpp> +#include "CustomAnimationCreateDialog.hxx" +#ifndef _SD_CUSTOMANIMATIONCREATEDIALOG_HRC +#include "CustomAnimationCreateDialog.hrc" +#endif +#ifndef _SD_CUSTOMANIMATION_HRC +#include "CustomAnimation.hrc" +#endif +#include "CustomAnimationPane.hxx" +#include "optsitem.hxx" +#include "sddll.hxx" + +#include "helpids.h" + +using namespace ::com::sun::star; + +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::Reference; +using ::com::sun::star::uno::Exception; + +using namespace ::com::sun::star::presentation; + +namespace sd { + + +const int ENTRANCE = 0; +const int EMPHASIS = 1; +const int EXIT = 2; +const int MOTIONPATH = 3; +const int MISCEFFECTS = 4; + +extern void fillDurationComboBox( ComboBox* pBox ); + +// -------------------------------------------------------------------- + +class CategoryListBox : public ListBox +{ +public: + CategoryListBox( Window* pParent, const ResId& rResId ); + ~CategoryListBox(); + + virtual void MouseButtonUp( const MouseEvent& rMEvt ); + + sal_uInt16 InsertCategory( const XubString& rStr, sal_uInt16 nPos = LISTBOX_APPEND ); + + void SetDoubleClickLink( const Link& rDoubleClickHdl ) { maDoubleClickHdl = rDoubleClickHdl; } + + DECL_LINK( implDoubleClickHdl, Control* ); + +private: + virtual void UserDraw( const UserDrawEvent& rUDEvt ); + + Link maDoubleClickHdl; +}; + +CategoryListBox::CategoryListBox( Window* pParent, const ResId& rResId ) +: ListBox( pParent, rResId ) +{ + EnableUserDraw( sal_True ); + SetDoubleClickHdl( LINK( this, CategoryListBox, implDoubleClickHdl ) ); +} + +CategoryListBox::~CategoryListBox() +{ +} + +sal_uInt16 CategoryListBox::InsertCategory( const XubString& rStr, sal_uInt16 nPos /* = LISTBOX_APPEND */ ) +{ + sal_uInt16 n = ListBox::InsertEntry( rStr, nPos ); + if( n != LISTBOX_ENTRY_NOTFOUND ) + ListBox::SetEntryFlags( n, ListBox::GetEntryFlags(n) | LISTBOX_ENTRY_FLAG_DISABLE_SELECTION ); + + return n; +} + +void CategoryListBox::UserDraw( const UserDrawEvent& rUDEvt ) +{ + const sal_uInt16 nItem = rUDEvt.GetItemId(); + + if( ListBox::GetEntryFlags(nItem) & LISTBOX_ENTRY_FLAG_DISABLE_SELECTION ) + { + Rectangle aOutRect( rUDEvt.GetRect() ); + OutputDevice* pDev = rUDEvt.GetDevice(); + + // fill the background + Color aColor (GetSettings().GetStyleSettings().GetDialogColor()); + + pDev->SetFillColor (aColor); + pDev->SetLineColor (); + pDev->DrawRect(aOutRect); + + // Erase the four corner pixels to make the rectangle appear rounded. + pDev->SetLineColor( GetSettings().GetStyleSettings().GetWindowColor()); + pDev->DrawPixel( aOutRect.TopLeft()); + pDev->DrawPixel( Point(aOutRect.Right(), aOutRect.Top())); + pDev->DrawPixel( Point(aOutRect.Left(), aOutRect.Bottom())); + pDev->DrawPixel( Point(aOutRect.Right(), aOutRect.Bottom())); + + // draw the category title + pDev->DrawText (aOutRect, GetEntry(nItem), TEXT_DRAW_CENTER ); + } + else + { + DrawEntry( rUDEvt, sal_True, sal_True ); + } +} + +// -------------------------------------------------------------------- + +IMPL_LINK( CategoryListBox, implDoubleClickHdl, Control*, EMPTYARG ) +{ + CaptureMouse(); + return 0; +} + +// -------------------------------------------------------------------- + +void CategoryListBox::MouseButtonUp( const MouseEvent& rMEvt ) +{ + ReleaseMouse(); + if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) ) + { + if( maDoubleClickHdl.IsSet() ) + maDoubleClickHdl.Call( this ); + } + else + { + ListBox::MouseButtonUp( rMEvt ); + } +} + +// -------------------------------------------------------------------- + +class CustomAnimationCreateTabPage : public TabPage +{ +public: + CustomAnimationCreateTabPage( Window* pParent, CustomAnimationCreateDialog* pDialogParent, int nTabId, const PresetCategoryList& rCategoryList, bool bHasText ); + ~CustomAnimationCreateTabPage(); + + PathKind getCreatePathKind() const; + CustomAnimationPresetPtr getSelectedPreset() const; + double getDuration() const; + void setDuration( double fDuration ); + + bool getIsPreview() const; + void setIsPreview( bool bIsPreview ); + + bool select( const OUString& rsPresetId ); + +private: + DECL_LINK( implSelectHdl, Control* ); + DECL_LINK( implDoubleClickHdl, Control* ); + + void onSelectEffect(); + + void clearEffects(); + +private: + CategoryListBox* mpLBEffects; + FixedText* mpFTSpeed; + ComboBox* mpCBSpeed; + CheckBox* mpCBXPReview; + + CustomAnimationCreateDialog* mpParent; + + sal_uInt16 mnCurvePathPos; + sal_uInt16 mnPolygonPathPos; + sal_uInt16 mnFreeformPathPos; + +}; + +struct ImplStlEffectCategorySortHelper +{ + ImplStlEffectCategorySortHelper(); + bool operator()( const CustomAnimationPresetPtr& p1, const CustomAnimationPresetPtr& p2 ); + +private: + uno::Reference< i18n::XCollator > mxCollator; +}; + +ImplStlEffectCategorySortHelper::ImplStlEffectCategorySortHelper() +{ + uno::Reference<lang::XMultiServiceFactory> xFac( ::comphelper::getProcessServiceFactory() ); + if( xFac.is() ) + { + mxCollator.set( xFac->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ) ), uno::UNO_QUERY ); + + if( mxCollator.is() ) + { + const lang::Locale& rLocale = Application::GetSettings().GetLocale(); + mxCollator->loadDefaultCollator(rLocale, 0); + } + } +} + +bool ImplStlEffectCategorySortHelper::operator()( const CustomAnimationPresetPtr& p1, const CustomAnimationPresetPtr& p2 ) +{ + return mxCollator.is() ? mxCollator->compareString(p1->getLabel(), p2->getLabel()) == -1 : false; +} + +CustomAnimationCreateTabPage::CustomAnimationCreateTabPage( Window* pParent, CustomAnimationCreateDialog* pDialogParent, int nTabId, const PresetCategoryList& rCategoryList, bool bHasText ) +: TabPage( pParent, SdResId( RID_TP_CUSTOMANIMATION_ENTRANCE ) ) +, mpParent( pDialogParent ) +, mnCurvePathPos( LISTBOX_ENTRY_NOTFOUND ) +, mnPolygonPathPos( LISTBOX_ENTRY_NOTFOUND ) +, mnFreeformPathPos( LISTBOX_ENTRY_NOTFOUND ) +{ + mpLBEffects = new CategoryListBox( this, SdResId( LB_EFFECTS ) ); + mpFTSpeed = new FixedText( this, SdResId( FT_SPEED ) ); + mpCBSpeed = new ComboBox( this, SdResId( CB_SPEED ) ); + mpCBXPReview = new CheckBox( this, SdResId( CBX_PREVIEW ) ); + + String sMotionPathLabel( SdResId( STR_USERPATH ) ); + + FreeResource(); + + sal_uInt16 nFirstEffect = LISTBOX_ENTRY_NOTFOUND; + + if( nTabId == MOTIONPATH ) + { + mpLBEffects->InsertCategory( sMotionPathLabel ); + + mnCurvePathPos = nFirstEffect = mpLBEffects->InsertEntry( sdr::GetResourceString(STR_ObjNameSingulCOMBLINE) ); + mnPolygonPathPos = mpLBEffects->InsertEntry( sdr::GetResourceString(STR_ObjNameSingulPOLY) ); + mnFreeformPathPos = mpLBEffects->InsertEntry( sdr::GetResourceString(STR_ObjNameSingulFREELINE) ); + }; + + PresetCategoryList::const_iterator aCategoryIter( rCategoryList.begin() ); + const PresetCategoryList::const_iterator aCategoryEnd( rCategoryList.end() ); + while( aCategoryIter != aCategoryEnd ) + { + PresetCategoryPtr pCategory( *aCategoryIter++ ); + if( pCategory.get() ) + { + mpLBEffects->InsertCategory( pCategory->maLabel ); + + std::vector< CustomAnimationPresetPtr > aSortedVector(pCategory->maEffects.size()); + std::copy( pCategory->maEffects.begin(), pCategory->maEffects.end(), aSortedVector.begin() ); + ImplStlEffectCategorySortHelper aSortHelper; + std::sort( aSortedVector.begin(), aSortedVector.end(), aSortHelper ); + + std::vector< CustomAnimationPresetPtr >::const_iterator aIter( aSortedVector.begin() ); + const std::vector< CustomAnimationPresetPtr >::const_iterator aEnd( aSortedVector.end() ); + while( aIter != aEnd ) + { + CustomAnimationPresetPtr pDescriptor = (*aIter++); + if( pDescriptor.get() && (bHasText || !pDescriptor->isTextOnly() ) ) + { + sal_uInt16 nPos = mpLBEffects->InsertEntry( pDescriptor->getLabel() ); + mpLBEffects->SetEntryData( nPos, static_cast<void*>( new CustomAnimationPresetPtr( pDescriptor ) ) ); + + if( nFirstEffect == LISTBOX_ENTRY_NOTFOUND ) + nFirstEffect = nPos; + } + } + } + } + + mpLBEffects->SelectEntryPos( nFirstEffect ); + + fillDurationComboBox( mpCBSpeed ); + + if( nFirstEffect != LISTBOX_ENTRY_NOTFOUND ) + onSelectEffect(); + + mpLBEffects->SetSelectHdl( LINK( this, CustomAnimationCreateTabPage, implSelectHdl ) ); + mpLBEffects->SetDoubleClickLink( LINK( this, CustomAnimationCreateTabPage, implDoubleClickHdl ) ); +} + +CustomAnimationCreateTabPage::~CustomAnimationCreateTabPage() +{ + clearEffects(); + + delete mpLBEffects; + delete mpFTSpeed; + delete mpCBSpeed; + delete mpCBXPReview; +} + +IMPL_LINK( CustomAnimationCreateTabPage, implSelectHdl, Control*, pControl ) +{ + if( pControl == mpLBEffects ) + onSelectEffect(); + return 0; +} + +IMPL_LINK( CustomAnimationCreateTabPage, implDoubleClickHdl, Control*, pControl ) +{ + if( pControl == mpLBEffects ) + { + if( mpLBEffects->GetSelectEntryCount() ) + mpParent->EndDialog( sal_True ); + } + return 0; +} + +void CustomAnimationCreateTabPage::onSelectEffect() +{ + CustomAnimationPresetPtr*p = static_cast< CustomAnimationPresetPtr* >( mpLBEffects->GetEntryData( mpLBEffects->GetSelectEntryPos() ) ); + + if( !p ) + return; + + CustomAnimationPresetPtr pPreset( *p ); + + const double fDuration = pPreset->getDuration(); + sal_uInt16 nPos = 0xffff; + + 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; + + mpCBSpeed->SelectEntryPos( nPos ); + + bool bHasSpeed = pPreset->getDuration() > 0.001; + mpCBSpeed->Enable( bHasSpeed ); + mpFTSpeed->Enable( bHasSpeed ); + + if( mpCBXPReview->IsChecked() ) + { + mpParent->preview( pPreset ); + } +} + +void CustomAnimationCreateTabPage::clearEffects() +{ + sal_uInt16 nPos = mpLBEffects->GetEntryCount(); + while( nPos-- ) + delete static_cast< CustomAnimationPresetPtr* >( mpLBEffects->GetEntryData( nPos ) ); + + mpLBEffects->Clear(); +} + +CustomAnimationPresetPtr CustomAnimationCreateTabPage::getSelectedPreset() const +{ + CustomAnimationPresetPtr pPreset; + + if( mpLBEffects->GetSelectEntryCount() == 1 ) + { + void* pEntryData = mpLBEffects->GetEntryData( mpLBEffects->GetSelectEntryPos() ); + if( pEntryData ) + pPreset = *static_cast< CustomAnimationPresetPtr* >( pEntryData ); + } + + return pPreset; +} + +PathKind CustomAnimationCreateTabPage::getCreatePathKind() const +{ + PathKind eKind = NONE; + + if( mpLBEffects->GetSelectEntryCount() == 1 ) + { + const sal_uInt16 nPos = mpLBEffects->GetSelectEntryPos(); + if( nPos == mnCurvePathPos ) + { + eKind = CURVE; + } + else if( nPos == mnPolygonPathPos ) + { + eKind = POLYGON; + } + else if( nPos == mnFreeformPathPos ) + { + eKind = FREEFORM; + } + } + + return eKind; +} + + + +double CustomAnimationCreateTabPage::getDuration() const +{ + sal_uInt16 nPos = mpCBSpeed->GetSelectEntryPos(); + if( (nPos == 0xffff) || !mpCBSpeed->IsEnabled() ) + { + CustomAnimationPresetPtr pPreset = getSelectedPreset(); + if( pPreset.get() ) + return pPreset->getDuration(); + } + + switch( nPos ) + { + case 0: return 5.0f; + case 1: return 3.0f; + case 2: return 2.0f; + case 3: return 1.0f; + case 4: return 0.5f; + } + + return 0.0f; +} + +void CustomAnimationCreateTabPage::setDuration( double fDuration ) +{ + sal_uInt16 nPos = 0; + if( fDuration < 2.0f ) + { + if( fDuration < 1.0f ) + { + nPos = 4; + } + else + { + nPos = 3; + } + } + else if( fDuration < 5.0f ) + { + if( fDuration < 3.0f ) + { + nPos = 2; + } + else + { + nPos = 1; + } + } + + mpCBSpeed->SelectEntryPos( nPos ); +} + +bool CustomAnimationCreateTabPage::getIsPreview() const +{ + return mpCBXPReview->IsChecked() ? true : false; +} + +void CustomAnimationCreateTabPage::setIsPreview( bool bIsPreview ) +{ + mpCBXPReview->Check( bIsPreview ? sal_True : sal_False ); +} + +bool CustomAnimationCreateTabPage::select( const OUString& rsPresetId ) +{ + sal_uInt16 nPos = mpLBEffects->GetEntryCount(); + while( nPos-- ) + { + void* pEntryData = mpLBEffects->GetEntryData( nPos ); + if( pEntryData ) + { + CustomAnimationPresetPtr& pPtr = *static_cast< CustomAnimationPresetPtr* >(pEntryData); + if( pPtr.get() && pPtr->getPresetId() == rsPresetId ) + { + mpLBEffects->SelectEntryPos( nPos ); + return true; + } + } + } + + return false; +} + +// -------------------------------------------------------------------- + +CustomAnimationCreateDialog::CustomAnimationCreateDialog( Window* pParent, CustomAnimationPane* pPane, const std::vector< ::com::sun::star::uno::Any >& rTargets, bool bHasText, const ::rtl::OUString& rsPresetId, double fDuration ) +: TabDialog( pParent, SdResId( DLG_CUSTOMANIMATION_CREATE ) ) +, mpPane( pPane ) +, mrTargets( rTargets ) +, mfDuration( fDuration ) +{ + 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(); + + SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS); + mbIsPreview = pOptions->IsPreviewNewEffects(); + + const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets(); + mpTabPages[ENTRANCE] = new CustomAnimationCreateTabPage( mpTabControl, this, ENTRANCE, rPresets.getEntrancePresets(), bHasText ); + mpTabPages[ENTRANCE]->SetHelpId( HID_SD_CUSTOMANIMATIONDIALOG_ENTRANCE ); + mpTabControl->SetTabPage( RID_TP_CUSTOMANIMATION_ENTRANCE, mpTabPages[ENTRANCE] ); + mpTabPages[EMPHASIS] = new CustomAnimationCreateTabPage( mpTabControl, this, EMPHASIS, rPresets.getEmphasisPresets(), bHasText ); + mpTabPages[EMPHASIS]->SetHelpId( HID_SD_CUSTOMANIMATIONDIALOG_EMPHASIS ); + mpTabControl->SetTabPage( RID_TP_CUSTOMANIMATION_EMPHASIS, mpTabPages[EMPHASIS] ); + mpTabPages[EXIT] = new CustomAnimationCreateTabPage( mpTabControl, this, EXIT, rPresets.getExitPresets(), bHasText ); + mpTabPages[EXIT]->SetHelpId( HID_SD_CUSTOMANIMATIONDIALOG_EXIT ); + mpTabControl->SetTabPage( RID_TP_CUSTOMANIMATION_EXIT, mpTabPages[EXIT] ); + mpTabPages[MOTIONPATH] = new CustomAnimationCreateTabPage( mpTabControl, this, MOTIONPATH, rPresets.getMotionPathsPresets(), bHasText ); + mpTabPages[MOTIONPATH]->SetHelpId( HID_SD_CUSTOMANIMATIONDIALOG_MOTIONPATH ); + mpTabControl->SetTabPage( RID_TP_CUSTOMANIMATION_MOTIONPATH, mpTabPages[MOTIONPATH] ); + mpTabPages[MISCEFFECTS] = new CustomAnimationCreateTabPage( mpTabControl, this, MISCEFFECTS, rPresets.getMiscPresets(), bHasText ); + mpTabPages[MISCEFFECTS]->SetHelpId( HID_SD_CUSTOMANIMATIONDIALOG_MISCEFFECTS ); + mpTabControl->SetTabPage( RID_TP_CUSTOMANIMATION_MISCEFFECTS, mpTabPages[MISCEFFECTS] ); + + getCurrentPage()->setDuration( mfDuration ); + getCurrentPage()->setIsPreview( mbIsPreview ); + + mpTabControl->SetActivatePageHdl( LINK( this, CustomAnimationCreateDialog, implActivatePagekHdl ) ); + mpTabControl->SetDeactivatePageHdl( LINK( this, CustomAnimationCreateDialog, implDeactivatePagekHdl ) ); + + setPosition(); + + // select current preset if available + if( rsPresetId.getLength() != 0 ) + { + for( sal_uInt16 i = ENTRANCE; i <= MOTIONPATH; i++ ) + { + if( mpTabPages[i]->select( rsPresetId ) ) + { + mpTabControl->SetCurPageId( RID_TP_CUSTOMANIMATION_ENTRANCE + i ); + break; + } + } + } +} + +CustomAnimationCreateDialog::~CustomAnimationCreateDialog() +{ + storePosition(); + + SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS); + pOptions->SetPreviewNewEffects( getCurrentPage()->getIsPreview() ); + + delete mpTabPages[ENTRANCE]; + delete mpTabPages[EMPHASIS]; + delete mpTabPages[EXIT]; + delete mpTabPages[MOTIONPATH]; + delete mpTabPages[MISCEFFECTS]; + + delete mpTabControl; + delete mpOKButton; + delete mpCancelButton; + delete mpHelpButton; +} + +CustomAnimationCreateTabPage* CustomAnimationCreateDialog::getCurrentPage() const +{ + switch( mpTabControl->GetCurPageId() ) + { + case RID_TP_CUSTOMANIMATION_ENTRANCE: return mpTabPages[ENTRANCE]; + case RID_TP_CUSTOMANIMATION_EMPHASIS: return mpTabPages[EMPHASIS]; + case RID_TP_CUSTOMANIMATION_EXIT: return mpTabPages[EXIT]; + case RID_TP_CUSTOMANIMATION_MISCEFFECTS:return mpTabPages[MISCEFFECTS]; + //case RID_TP_CUSTOMANIMATION_MOTIONPATH: + default: + return mpTabPages[MOTIONPATH]; + } +} + +PathKind CustomAnimationCreateDialog::getCreatePathKind() const +{ + return getCurrentPage()->getCreatePathKind(); +} + +CustomAnimationPresetPtr CustomAnimationCreateDialog::getSelectedPreset() const +{ + return getCurrentPage()->getSelectedPreset(); +} + +double CustomAnimationCreateDialog::getSelectedDuration() const +{ + return getCurrentPage()->getDuration(); +} + +IMPL_LINK( CustomAnimationCreateDialog, implActivatePagekHdl, Control*, EMPTYARG ) +{ + getCurrentPage()->setDuration( mfDuration ); + getCurrentPage()->setIsPreview( mbIsPreview ); + return 1; +} + +IMPL_LINK( CustomAnimationCreateDialog, implDeactivatePagekHdl, Control*, EMPTYARG ) +{ + mfDuration = getCurrentPage()->getDuration(); + mbIsPreview = getCurrentPage()->getIsPreview(); + return 1; +} + +void CustomAnimationCreateDialog::preview( const CustomAnimationPresetPtr& pPreset ) const +{ + MainSequencePtr pSequence( new MainSequence() ); + + std::vector< Any >::const_iterator aIter( mrTargets.begin() ); + const std::vector< Any >::const_iterator aEnd( mrTargets.end() ); + + const double fDuration = getSelectedDuration(); + + bool bFirst = true; + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pNew( + pSequence->append( pPreset, (*aIter++), fDuration ) ); + + if( bFirst ) + bFirst = false; + else + pNew->setNodeType( EffectNodeType::WITH_PREVIOUS ); + } + + mpPane->preview( pSequence->getRootNode() ); +} + +namespace +{ +Window * lcl_GetTopmostParent( Window * pWindow ) +{ + Window * pResult = 0; + Window * pCurrent = pWindow ? pWindow->GetParent() : 0; + while( pCurrent ) + { + pResult = pCurrent; + pCurrent = pCurrent->GetParent(); + } + return pResult; +} +} + +void CustomAnimationCreateDialog::setPosition() +{ + SvtViewOptions aDlgOpt( + E_TABDIALOG, String::CreateFromInt32( DLG_CUSTOMANIMATION_CREATE ) ); + if ( aDlgOpt.Exists() ) + { + SetWindowState( ByteString( aDlgOpt.GetWindowState().getStr(), + RTL_TEXTENCODING_ASCII_US ) ); + } + else + { + // default position: aligned with right edge of parent + Window * pParent = lcl_GetTopmostParent( this ); + if( pParent ) + { + Point aPos( GetPosPixel()); + Size aSize( GetSizePixel()); + Point aParentPos( pParent->GetPosPixel()); + Size aParentSize( pParent->GetSizePixel()); + + // right center + aPos.setX( aParentSize.getWidth() - aSize.getWidth() ); + aPos.setY( (aParentSize.getHeight() - aSize.getHeight()) / 2 ); + SetPosPixel( aPos ); + } + } +} + +void CustomAnimationCreateDialog::storePosition() +{ + // save settings (screen position and current page) + SvtViewOptions aDlgOpt( + E_TABDIALOG, String::CreateFromInt32( DLG_CUSTOMANIMATION_CREATE ) ); + aDlgOpt.SetWindowState( + OUString::createFromAscii( GetWindowState( WINDOWSTATE_MASK_POS ).GetBuffer() ) ); +} + +} diff --git a/sd/source/ui/animations/CustomAnimationCreateDialog.hrc b/sd/source/ui/animations/CustomAnimationCreateDialog.hrc new file mode 100644 index 000000000000..0bc4ff2535d5 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationCreateDialog.hrc @@ -0,0 +1,38 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_CUSTOMANIMATIONCREATEDIALOG_HRC +#define _SD_CUSTOMANIMATIONCREATEDIALOG_HRC + +// TabPage RID_TP_CUSTOMANIMATION_ENTRANCE +#define LB_EFFECTS 1 +#define FT_SPEED 2 +#define CB_SPEED 3 +#define CBX_PREVIEW 4 +#define STR_USERPATH 5 + +#endif // _SD_CUSTOMANIMATIONCREATEDIALOG_HRC diff --git a/sd/source/ui/animations/CustomAnimationCreateDialog.hxx b/sd/source/ui/animations/CustomAnimationCreateDialog.hxx new file mode 100644 index 000000000000..48b87045b70f --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationCreateDialog.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_CUSTOMANIMATIONCREATEDIALOG_HXX +#define _SD_CUSTOMANIMATIONCREATEDIALOG_HXX + +#include "CustomAnimationPreset.hxx" +#include <vcl/tabdlg.hxx> + +enum PathKind { NONE, CURVE, POLYGON, FREEFORM }; + +class TabControl; +class OKButton; +class CancelButton; +class HelpButton; + +namespace sd { + +// -------------------------------------------------------------------- + +class CustomAnimationCreateTabPage; +class CustomAnimationPane; + +class CustomAnimationCreateDialog : public TabDialog +{ + friend class CustomAnimationCreateTabPage; +public: + CustomAnimationCreateDialog( ::Window* pParent, CustomAnimationPane* pPane, const std::vector< ::com::sun::star::uno::Any >& rTargets, bool bHasText, const ::rtl::OUString& rsPresetId, double fDuration ); + ~CustomAnimationCreateDialog(); + + PathKind getCreatePathKind() const; + CustomAnimationPresetPtr getSelectedPreset() const; + double getSelectedDuration() const; + +private: + CustomAnimationCreateTabPage* getCurrentPage() const; + void preview( const CustomAnimationPresetPtr& pPreset ) const; + void setPosition(); + void storePosition(); + + DECL_LINK( implActivatePagekHdl, Control* ); + DECL_LINK( implDeactivatePagekHdl, Control* ); + +private: + CustomAnimationPane* mpPane; + const std::vector< ::com::sun::star::uno::Any >& mrTargets; + + double mfDuration; + bool mbIsPreview; + + TabControl* mpTabControl; + OKButton* mpOKButton; + CancelButton* mpCancelButton; + HelpButton* mpHelpButton; + + CustomAnimationCreateTabPage* mpTabPages[5]; +}; + +} + +#endif // _SD_CUSTOMANIMATIONCREATEDIALOG_HXX diff --git a/sd/source/ui/animations/CustomAnimationCreateDialog.src b/sd/source/ui/animations/CustomAnimationCreateDialog.src new file mode 100644 index 000000000000..62abf708d883 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationCreateDialog.src @@ -0,0 +1,148 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "CustomAnimationCreateDialog.hrc" +#include "CustomAnimation.hrc" + +TabDialog DLG_CUSTOMANIMATION_CREATE +{ + Size = MAP_APPFONT ( 162 , 244 ) ; + OutputSize = TRUE ; + SVLook = TRUE ; + Moveable = TRUE ; + Closeable = TRUE ; + + Text [ en-US ] = "Custom Animation" ; + + TabControl 1 + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 3 , 3 ) ; + Size = MAP_APPFONT ( 156, 217 ) ; + PageList = + { + PageItem + { + Identifier = RID_TP_CUSTOMANIMATION_ENTRANCE ; + Text [ en-US ] = "Entrance" ; + }; + + PageItem + { + Identifier = RID_TP_CUSTOMANIMATION_EMPHASIS; + Text [ en-US ] = "Emphasis"; + }; + + PageItem + { + Identifier = RID_TP_CUSTOMANIMATION_EXIT; + Text [ en-US ] = "Exit"; + }; + + PageItem + { + Identifier = RID_TP_CUSTOMANIMATION_MOTIONPATH; + Text [ en-US ] = "Motion Paths"; + }; + + PageItem + { + Identifier = RID_TP_CUSTOMANIMATION_MISCEFFECTS; + Text [ en-US ] = "Misc Effects"; + }; + }; + }; + OKButton 1 + { + Pos = MAP_APPFONT ( 3 , 223 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + }; + CancelButton 1 + { + Pos = MAP_APPFONT ( 56 , 223 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + }; + HelpButton 1 + { + Pos = MAP_APPFONT ( 109 , 223 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + }; +}; + +TabPage RID_TP_CUSTOMANIMATION_ENTRANCE +{ + HelpID = "sd:TabPage:RID_TP_CUSTOMANIMATION_ENTRANCE"; + Hide = TRUE; + Size = MAP_APPFONT ( 156, 217 ); + + ListBox LB_EFFECTS + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_ENTRANCE:LB_EFFECTS"; + Pos = MAP_APPFONT ( 3 , 3 ) ; + Size = MAP_APPFONT( 144, 160 ); + OutputSize = TRUE; + TabStop = TRUE ; + Border = TRUE ; + }; + + FixedText FT_SPEED + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( 3 , 167 ) ; + Size = MAP_APPFONT( 42, 8 ); + + Text [ en-US ] = "Speed"; + }; + + ComboBox CB_SPEED + { + HelpID = "sd:ComboBox:RID_TP_CUSTOMANIMATION_ENTRANCE:CB_SPEED"; + Pos = MAP_APPFONT ( 48 , 166 ) ; + Size = MAP_APPFONT ( 101, 48 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; + + CheckBox CBX_PREVIEW + { + HelpID = "sd:CheckBox:RID_TP_CUSTOMANIMATION_ENTRANCE:CBX_PREVIEW"; + Pos = MAP_APPFONT ( 3 , 181 ) ; + Size = MAP_APPFONT ( 143 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Automatic preview" ; + }; + + String STR_USERPATH + { + Text [ en-US ] = "User paths"; + }; +}; + diff --git a/sd/source/ui/animations/CustomAnimationDialog.cxx b/sd/source/ui/animations/CustomAnimationDialog.cxx new file mode 100755 index 000000000000..4beb1a7d8e0b --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationDialog.cxx @@ -0,0 +1,2638 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <com/sun/star/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!" ); + XColorTable* pColorTable = NULL; + bool bKillTable = false; + const SfxPoolItem* pItem = NULL; + + if ( pDocSh && ( ( pItem = pDocSh->GetItem( SID_COLOR_TABLE ) ) != 0) ) + pColorTable = ( (SvxColorTableItem*)pItem )->GetColorTable(); + + if ( !pColorTable ) + { + pColorTable = new XColorTable( SvtPathOptions().GetPalettePath() ); + bKillTable = sal_True; + } + + sal_Int32 nColor = 0; + rValue >>= nColor; + + for ( long i = 0; i < pColorTable->Count(); i++ ) + { + XColorEntry* pEntry = pColorTable->GetColor(i); + sal_uInt16 nPos = mpControl->InsertEntry( pEntry->GetColor(), pEntry->GetName() ); + if( pEntry->GetColor().GetRGBColor() == (sal_uInt32)nColor ) + mpControl->SelectEntryPos( nPos ); + } + + if ( bKillTable ) + delete pColorTable; +} + +// -------------------------------------------------------------------- + +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!" ); + XColorTable* pColorTable = NULL; + bool bKillTable = false; + const SfxPoolItem* pItem = NULL; + + if ( pDocSh && ( (pItem = pDocSh->GetItem( SID_COLOR_TABLE ) ) != 0 ) ) + pColorTable = ( (SvxColorTableItem*)pItem )->GetColorTable(); + + if ( !pColorTable ) + { + pColorTable = new XColorTable( SvtPathOptions().GetPalettePath() ); + bKillTable = sal_True; + } + + mpCLBDimColor->SetUpdateMode( sal_False ); + + for ( long i = 0; i < pColorTable->Count(); i++ ) + { + XColorEntry* pEntry = pColorTable->GetColor(i); + mpCLBDimColor->InsertEntry( pEntry->GetColor(), pEntry->GetName() ); + } + + mpCLBDimColor->SetUpdateMode( sal_True ); + + if ( bKillTable ) + delete pColorTable; + + // + // 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, SGA_FORMAT_SOUND ) ) + { + 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 ) ); + } + } + + 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; +} + +} diff --git a/sd/source/ui/animations/CustomAnimationDialog.hrc b/sd/source/ui/animations/CustomAnimationDialog.hrc new file mode 100644 index 000000000000..a7895543304b --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationDialog.hrc @@ -0,0 +1,89 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_CUSTOMANIMATIONDIALOG_HRC +#define _SD_CUSTOMANIMATIONDIALOG_HRC + +// TabPage RID_TP_CUSTOMANIMATION_EFFECT +#define FL_SETTINGS 1 +#define FT_PROPERTY_1 2 +#define LB_PROPERTY_1 3 +#define FT_PROPERTY_2 4 +#define LB_PROPERTY_2 5 +#define CB_SMOOTH_START 6 +#define CB_SMOOTH_END 7 +#define CB_AUTORESTART 8 +#define FL_ENHANCEMENTS 9 +#define FT_SOUND 10 +#define LB_SOUND 11 +#define PB_SOUND_PREVIEW 12 +#define FT_AFTER_EFFECT 13 +#define LB_AFTER_EFFECT 14 +#define FT_DIMCOLOR 15 +#define CLB_DIMCOLOR 16 +#define FT_TEXT_ANIM 17 +#define LB_TEXT_ANIM 18 +#define MF_TEXT_DELAY 19 +#define FT_TEXT_DELAY 20 +#define FL_PLAY 21 +#define RB_FROM_START 22 +#define RB_FROM_LAST 23 +#define RB_FROM_TIME 24 +#define MF_START_TIME 25 +#define FL_STOP 26 +#define RB_STOP_ON_CLICK 27 +#define RB_STOP_ON_NEXT_SLIDE 28 +#define RB_STOP_AFTER_N_SLIDES 29 +#define MF_STOP_AFTER_SLIDES 30 +#define TP_CUSTOMANIMATION_EFFECT_COUNT 31 + +// TabPage RID_TP_CUSTOMANIMATION_DURATION +#define FT_START 1 +#define LB_START 2 +#define FT_START_DELAY 3 +#define MF_START_DELAY 4 +#define FT_DURATION 5 +#define CB_DURATION 6 +#define FT_REPEAT 7 +#define CB_REPEAT 8 +#define CBX_REWIND 9 +#define FL_TRIGGER 10 +#define RB_CLICKSEQUENCE 11 +#define RB_INTERACTIVE 12 +#define LB_TRIGGER 13 +#define TP_CUSTOMANIMATION_DURATION_COUNT 13 + +// TabPage RID_TP_CUSTOMANIMATION_TEXT +#define FT_GROUP_TEXT 1 +#define LB_GROUP_TEXT 2 +#define CBX_GROUP_AUTO 3 +#define MF_GROUP_AUTO 4 +#define CBX_ANIMATE_FORM 5 +#define CBX_REVERSE 6 +#define TP_CUSTOMANIMATION_TEXT_COUNT 6 + +#endif // _SD_CUSTOMANIMATIONDIALOG_HRC diff --git a/sd/source/ui/animations/CustomAnimationDialog.hxx b/sd/source/ui/animations/CustomAnimationDialog.hxx new file mode 100755 index 000000000000..cf479d874470 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationDialog.hxx @@ -0,0 +1,186 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_CUSTOMANIMATIONDIALOG_HXX +#define _SD_CUSTOMANIMATIONDIALOG_HXX + +#include "CustomAnimationEffect.hxx" +#include "CustomAnimationPreset.hxx" +#include <vcl/tabdlg.hxx> +#include <vcl/lstbox.hxx> + +class TabControl; +class OKButton; +class CancelButton; +class HelpButton; +namespace sd { + + +// -------------------------------------------------------------------- + +// property handles +const sal_Int32 nHandleSound = 0; +const sal_Int32 nHandleHasAfterEffect = 1; +const sal_Int32 nHandleIterateType = 2; +const sal_Int32 nHandleIterateInterval = 3; +const sal_Int32 nHandleStart = 4; +const sal_Int32 nHandleBegin = 5; +const sal_Int32 nHandleDuration = 6; +const sal_Int32 nHandleRepeat = 7; +const sal_Int32 nHandleRewind = 8; +const sal_Int32 nHandleEnd = 9; +const sal_Int32 nHandleAfterEffectOnNextEffect = 10; +const sal_Int32 nHandleDimColor = 11; +const sal_Int32 nHandleMaxParaDepth = 12; +const sal_Int32 nHandlePresetId = 13; +const sal_Int32 nHandleProperty1Type = 14; +const sal_Int32 nHandleProperty1Value = 15; +const sal_Int32 nHandleProperty2Type = 16; +const sal_Int32 nHandleProperty2Value = 17; + +const sal_Int32 nHandleAccelerate = 18; +const sal_Int32 nHandleDecelerate = 19; +const sal_Int32 nHandleAutoReverse = 20; +const sal_Int32 nHandleTrigger = 21; + +const sal_Int32 nHandleHasText = 22; +const sal_Int32 nHandleTextGrouping = 23; +const sal_Int32 nHandleAnimateForm = 24; +const sal_Int32 nHandleTextGroupingAuto = 25; +const sal_Int32 nHandleTextReverse = 26; + +const sal_Int32 nHandleCurrentPage = 27; +const sal_Int32 nHandleSoundURL = 28; +const sal_Int32 nHandleSoundVolumne = 29; +const sal_Int32 nHandleSoundEndAfterSlide = 30; + +const sal_Int32 nHandleCommand = 31; + +const sal_Int32 nHandleHasVisibleShape = 32; + +const sal_Int32 nPropertyTypeNone = 0; +const sal_Int32 nPropertyTypeDirection = 1; +const sal_Int32 nPropertyTypeSpokes = 2; +const sal_Int32 nPropertyTypeFirstColor = 3; +const sal_Int32 nPropertyTypeSecondColor = 4; +const sal_Int32 nPropertyTypeZoom = 5; +const sal_Int32 nPropertyTypeFillColor = 6; +const sal_Int32 nPropertyTypeColorStyle = 7; +const sal_Int32 nPropertyTypeFont = 8; +const sal_Int32 nPropertyTypeCharHeight = 9; +const sal_Int32 nPropertyTypeCharColor = 10; +const sal_Int32 nPropertyTypeCharHeightStyle = 11; +const sal_Int32 nPropertyTypeCharDecoration = 12; +const sal_Int32 nPropertyTypeLineColor = 13; +const sal_Int32 nPropertyTypeRotate = 14; +const sal_Int32 nPropertyTypeColor = 15; +const sal_Int32 nPropertyTypeAccelerate = 16; +const sal_Int32 nPropertyTypeDecelerate = 17; +const sal_Int32 nPropertyTypeAutoReverse = 18; +const sal_Int32 nPropertyTypeTransparency = 19; +const sal_Int32 nPropertyTypeFontStyle = 20; +const sal_Int32 nPropertyTypeScale = 21; + +// -------------------------------------------------------------------- + +class PropertySubControl +{ +public: + PropertySubControl( sal_Int32 nType ) : mnType( nType ) {} + virtual ~PropertySubControl(); + + virtual ::com::sun::star::uno::Any getValue() = 0; + virtual void setValue( const ::com::sun::star::uno::Any& rValue, const rtl::OUString& rPresetId ) = 0; + + virtual Control* getControl() = 0; + + static PropertySubControl* + create( sal_Int32 nType, + ::Window* pParent, + const ::com::sun::star::uno::Any& rValue, + const rtl::OUString& rPresetId, + const Link& rModifyHdl ); + + sal_Int32 getControlType() const { return mnType; } + +protected: + sal_Int32 mnType; +}; + +// -------------------------------------------------------------------- + +class PropertyControl : public ListBox +{ +public: + PropertyControl( Window* pParent, const ResId& rResId ); + ~PropertyControl(); + + void setSubControl( PropertySubControl* pSubControl ); + PropertySubControl* getSubControl() const { return mpSubControl; } + + virtual void Resize(); + +private: + PropertySubControl* mpSubControl; +}; + +// -------------------------------------------------------------------- + +class CustomAnimationDurationTabPage; +class CustomAnimationEffectTabPage; +class CustomAnimationTextAnimTabPage; +class STLPropertySet; + +class CustomAnimationDialog : public TabDialog +{ +public: + CustomAnimationDialog( Window* pParent, STLPropertySet* pSet, sal_uInt16 nPage = 0 ); + ~CustomAnimationDialog(); + + STLPropertySet* getDefaultSet() { return mpSet; } + STLPropertySet* getResultSet(); + + static STLPropertySet* createDefaultSet(); + +private: + STLPropertySet* mpSet; + STLPropertySet* mpResultSet; + + CustomAnimationEffectPtr mpEffect; + TabControl* mpTabControl; + OKButton* mpOKButton; + CancelButton* mpCancelButton; + HelpButton* mpHelpButton; + + CustomAnimationDurationTabPage* mpDurationTabPage; + CustomAnimationEffectTabPage* mpEffectTabPage; + CustomAnimationTextAnimTabPage* mpTextAnimTabPage; +}; + +} + +#endif // _SD_CUSTOMANIMATIONDIALOG_HXX diff --git a/sd/source/ui/animations/CustomAnimationDialog.src b/sd/source/ui/animations/CustomAnimationDialog.src new file mode 100644 index 000000000000..270fef75db50 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationDialog.src @@ -0,0 +1,688 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "CustomAnimationDialog.hrc" +#include "CustomAnimation.hrc" + +#define X0 6 +#define X1 6 +#define X2 73 +#define W0 268 +#define W1 67 +#define W2 100 +#define WIDTH 260 + +TabDialog DLG_CUSTOMANIMATION +{ + Size = MAP_APPFONT ( WIDTH+6 , 200 ) ; + OutputSize = TRUE ; + SVLook = TRUE ; + Moveable = TRUE ; + Closeable = TRUE ; + Text [ en-US ] = "Effect Options"; + + TabControl 1 + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 3 , 3 ) ; + Size = MAP_APPFONT ( 240 , 159 ) ; + PageList = + { + PageItem + { + PageResID = RID_TP_CUSTOMANIMATION_EFFECT ; + Identifier = RID_TP_CUSTOMANIMATION_EFFECT ; + Text [ en-US ] = "Effect" ; + }; + + PageItem + { + PageResID = RID_TP_CUSTOMANIMATION_DURATION; + Identifier = RID_TP_CUSTOMANIMATION_DURATION; + Text [ en-US ] = "Timing"; + }; + + PageItem + { + PageResID = RID_TP_CUSTOMANIMATION_TEXT; + Identifier = RID_TP_CUSTOMANIMATION_TEXT; + Text [ en-US ] = "Text Animation"; + }; + }; + }; + OKButton 1 + { + Pos = MAP_APPFONT ( 10 , 175 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + }; + CancelButton 1 + { + Pos = MAP_APPFONT ( 64 , 175 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + }; + HelpButton 1 + { + Pos = MAP_APPFONT ( 119 , 175 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + }; +}; + +TabPage RID_TP_CUSTOMANIMATION_EFFECT +{ + HelpID = "sd:TabPage:RID_TP_CUSTOMANIMATION_EFFECT"; + Hide = TRUE; + Size = MAP_APPFONT ( WIDTH , 159 ); + Text [ en-US ] = "Effect"; + + FixedLine FL_SETTINGS + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 3 ) ; + Size = MAP_APPFONT( W0, 8 ); + Hide = TRUE; + + Text [ en-US ] = "Settings"; + }; + + FixedText FT_PROPERTY_1 + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1+6 , 16 ) ; + Size = MAP_APPFONT( W1, 8 ); + Hide = TRUE; + }; + + ListBox LB_PROPERTY_1 + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_EFFECT:LB_PROPERTY_1"; + Pos = MAP_APPFONT ( X2+6 , 14 ) ; + Size = MAP_APPFONT ( W2, 100 ); + Hide = TRUE; + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + ClipChildren = TRUE; + }; + + FixedText FT_PROPERTY_2 + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1+6 , 16 ) ; + Size = MAP_APPFONT( W1, 8 ); + Hide = TRUE; + }; + + ListBox LB_PROPERTY_2 + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_EFFECT:LB_PROPERTY_2"; + Pos = MAP_APPFONT ( X2+6 , 14 ) ; + Size = MAP_APPFONT ( W2, 100 ); + Hide = TRUE; + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; + + CheckBox CB_SMOOTH_START + { + HelpID = "sd:CheckBox:RID_TP_CUSTOMANIMATION_EFFECT:CB_SMOOTH_START"; + Pos = MAP_APPFONT( X1+6, 14 ); + Size = MAP_APPFONT ( (W0 / 2) , 10 ) ; + Hide = TRUE; + + Text [ en-US ] = "Accelerated start"; + }; + + CheckBox CB_SMOOTH_END + { + HelpID = "sd:CheckBox:RID_TP_CUSTOMANIMATION_EFFECT:CB_SMOOTH_END"; + Pos = MAP_APPFONT( X1 + (W0 / 2) + 3, 14 ); + Size = MAP_APPFONT ( (W0 / 2) , 10 ) ; + Hide = TRUE; + + Text [ en-US ] = "Decelerated end"; + }; + + CheckBox CB_AUTORESTART + { + HelpID = "sd:CheckBox:RID_TP_CUSTOMANIMATION_EFFECT:CB_AUTORESTART"; + Pos = MAP_APPFONT( X1+6, 14 ); + Size = MAP_APPFONT ( W0 , 10 ) ; + Hide = TRUE; + + Text [ en-US ] = "Reverse automatically"; + }; + +// +// controls for playback command +// +/* + FixedLine FL_PLAY + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 3 ) ; + Size = MAP_APPFONT( W0, 8 ); + Hide = TRUE; + + Text [ en-US ] = "Play"; + }; + + RadioButton RB_FROM_START + { + HelpID = "sd:RadioButton:RID_TP_CUSTOMANIMATION_EFFECT:RB_FROM_START"; + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 16 ) ; + Size = MAP_APPFONT( W0, 10 ); + TabStop = TRUE ; + Hide = TRUE; + + Text [ en-US ] = "From start"; + }; + + RadioButton RB_FROM_LAST + { + HelpID = "sd:RadioButton:RID_TP_CUSTOMANIMATION_EFFECT:RB_FROM_LAST"; + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 29 ) ; + Size = MAP_APPFONT( W0, 10 ); + TabStop = TRUE ; + Hide = TRUE; + + Text [en-US ] = "From last"; + }; + + RadioButton RB_FROM_TIME + { + HelpID = "sd:RadioButton:RID_TP_CUSTOMANIMATION_EFFECT:RB_FROM_TIME"; + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 42 ) ; + Size = MAP_APPFONT( W0, 10 ); + TabStop = TRUE ; + Hide = TRUE; + + Text [ en-US ] = "From time:"; + }; + + MetricField MF_START_TIME + { + HelpID = "sd:MetricField:RID_TP_CUSTOMANIMATION_EFFECT:MF_START_TIME"; + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 55 ) ; + Size = MAP_APPFONT ( W1, 12 ); + OutputSize = TRUE; + Border = TRUE ; + TabStop = TRUE ; + Left = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Minimum = 0 ; + Maximum = 9999 ; + DecimalDigits = 1 ; + Unit = FUNIT_CUSTOM ; + CustomUnitText [ en-US ] = "sec"; + SpinSize = 5 ; + Hide = TRUE; + }; + + FixedLine FL_STOP + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 70 ) ; + Size = MAP_APPFONT( W0, 8 ); + Hide = TRUE; + + Text [ en-US ] = "Stop playback"; + }; + + RadioButton RB_STOP_ON_CLICK + { + HelpID = "sd:RadioButton:RID_TP_CUSTOMANIMATION_EFFECT:RB_STOP_ON_CLICK"; + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 81 ) ; + Size = MAP_APPFONT( W0, 10 ); + TabStop = TRUE ; + Hide = TRUE; + + Text [ en-US ] = "On click"; + }; + + RadioButton RB_STOP_ON_NEXT_SLIDE + { + HelpID = "sd:RadioButton:RID_TP_CUSTOMANIMATION_EFFECT:RB_STOP_ON_NEXT_SLIDE"; + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 94 ) ; + Size = MAP_APPFONT( W0, 10 ); + TabStop = TRUE ; + Hide = TRUE; + + Text [ en-US ] = "After current slide"; + }; + + RadioButton RB_STOP_AFTER_N_SLIDES + { + HelpID = "sd:RadioButton:RID_TP_CUSTOMANIMATION_EFFECT:RB_STOP_AFTER_N_SLIDES"; + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 107 ) ; + Size = MAP_APPFONT( W0, 10 ); + TabStop = TRUE ; + Hide = TRUE; + + Text [ en-US ] = "After"; + }; + + MetricField MF_STOP_AFTER_SLIDES + { + HelpID = "sd:MetricField:RID_TP_CUSTOMANIMATION_EFFECT:MF_STOP_AFTER_SLIDES"; + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 55 ) ; + Size = MAP_APPFONT ( W1, 12 ); + OutputSize = TRUE; + Border = TRUE ; + TabStop = TRUE ; + Left = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Minimum = 0 ; + Maximum = 9999 ; + DecimalDigits = 0 ; + Unit = FUNIT_CUSTOM ; + CustomUnitText [ en-US ] = "Slides"; + SpinSize = 1 ; + Hide = TRUE; + }; +*/ + // + // common settings + // + + FixedLine FL_ENHANCEMENTS + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 3 ) ; + Size = MAP_APPFONT( W0, 8 ); + Hide = TRUE; + + Text [ en-US ] = "Enhancement"; + }; + + FixedText FT_SOUND + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 5 ) ; + Size = MAP_APPFONT( W1, 8 ); + + Text [ en-US ] = "Sound"; + }; + + ListBox LB_SOUND + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_EFFECT:LB_SOUND"; + Pos = MAP_APPFONT ( X2 , 3 ) ; + Size = MAP_APPFONT ( W2 - 19, 100 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; + + PushButton PB_SOUND_PREVIEW + { + HelpID = "sd:PushButton:RID_TP_CUSTOMANIMATION_EFFECT:PB_SOUND_PREVIEW"; + Pos = MAP_APPFONT ( X2 + W2 - 16 , 2 ) ; + Size = MAP_APPFONT( 16, 14 ); + OutputSize = TRUE; + TabStop = TRUE; + }; + + FixedText FT_AFTER_EFFECT + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 20 ) ; + Size = MAP_APPFONT( W1, 8 ); + + Text [ en-US ] = "After animation "; + }; + + ListBox LB_AFTER_EFFECT + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_EFFECT:LB_AFTER_EFFECT"; + Pos = MAP_APPFONT ( X2 , 18 ) ; + Size = MAP_APPFONT ( W2, 100 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + + StringList [ en-US ] = + { + < "Don't dim" ; > ; + < "Dim with color" ; > ; + < "Hide after animation" ; > ; + < "Hide on next animation" ; > ; + }; + }; + + FixedText FT_DIMCOLOR + { + Pos = MAP_APPFONT( X1, 35 ); + Size = MAP_APPFONT( W1, 8 ); + Text [ en-US ] = "Dim Color"; + }; + + ListBox CLB_DIMCOLOR + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_EFFECT:CLB_DIMCOLOR"; + Pos = MAP_APPFONT( X2, 33 ); + Size = MAP_APPFONT ( W2, 100 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; + + FixedText FT_TEXT_ANIM + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X1 , 50 ) ; + Size = MAP_APPFONT( W1, 8 ); + + Text [ en-US ] = "Text animation"; + }; + + ListBox LB_TEXT_ANIM + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_EFFECT:LB_TEXT_ANIM"; + Pos = MAP_APPFONT ( X2 , 48 ) ; + Size = MAP_APPFONT ( W2, 100 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + + StringList [ en-US ] = + { + < "All at once" ; > ; + < "Word by word" ; > ; + < "Letter by letter" ; > ; + }; + }; + + FixedText FT_TEXT_DELAY + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X2 + 45, 66 ) ; + Size = MAP_APPFONT( W0 - X2 - 45, 8 ); + + Text [ en-US ] = "delay between characters"; + }; + + MetricField MF_TEXT_DELAY + { + HelpID = "sd:MetricField:RID_TP_CUSTOMANIMATION_EFFECT:MF_TEXT_DELAY"; + Pos = MAP_APPFONT ( X2, 64 ) ; + Size = MAP_APPFONT ( 42, 12 ); + TabStop = TRUE ; + Border = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Minimum = 0 ; + Maximum = 1024 ; + DecimalDigits = 1 ; + Unit = FUNIT_CUSTOM ; + CustomUnitText [ en-US ] = "%"; + SpinSize = 1 ; + + }; +}; + +TabPage RID_TP_CUSTOMANIMATION_DURATION +{ + HelpID = "sd:TabPage:RID_TP_CUSTOMANIMATION_DURATION"; + Hide = TRUE; + Size = MAP_APPFONT ( WIDTH , 159 ); + Text [ en-US ] = "Timing"; + + FixedText FT_START + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 5 ) ; + Size = MAP_APPFONT( W1, 8 ); + + Text [ en-US ] = "Start"; + }; + + ListBox LB_START + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_DURATION:LB_START"; + Pos = MAP_APPFONT ( X2 , 3 ) ; + Size = MAP_APPFONT ( W2, 48 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + + StringList [ en-US ] = + { + < "On click" ; > ; + < "With previous" ; > ; + < "After previous" ; > ; + }; + }; + + FixedText FT_START_DELAY + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 20 ) ; + Size = MAP_APPFONT( W1, 8 ); + + Text [ en-US ] = "Delay"; + }; + + MetricField MF_START_DELAY + { + HelpID = "sd:MetricField:RID_TP_CUSTOMANIMATION_DURATION:MF_START_DELAY"; + Pos = MAP_APPFONT ( X2 , 18 ) ; + Size = MAP_APPFONT ( W2, 12 ); + Border = TRUE ; + TabStop = TRUE ; + Left = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Minimum = 0 ; + Maximum = 9999 ; + DecimalDigits = 1 ; + Unit = FUNIT_CUSTOM ; + CustomUnitText [ en-US ] = "sec"; + SpinSize = 5 ; + }; + + FixedText FT_DURATION + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 35 ) ; + Size = MAP_APPFONT( W1, 8 ); + + Text [ en-US ] = "Speed"; + }; + + ComboBox CB_DURATION + { + HelpID = "sd:ComboBox:RID_TP_CUSTOMANIMATION_DURATION:CB_DURATION"; + Pos = MAP_APPFONT ( X2 , 33 ) ; + Size = MAP_APPFONT ( W2, 48 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; + + FixedText FT_REPEAT + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 50 ) ; + Size = MAP_APPFONT( W1, 8 ); + + Text [ en-US ] = "Repeat"; + }; + + ComboBox CB_REPEAT + { + HelpID = "sd:ComboBox:RID_TP_CUSTOMANIMATION_DURATION:CB_REPEAT"; + Pos = MAP_APPFONT ( X2 , 48 ) ; + Size = MAP_APPFONT ( W2, 48 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; + + CheckBox CBX_REWIND + { + HelpID = "sd:CheckBox:RID_TP_CUSTOMANIMATION_DURATION:CBX_REWIND"; + Pos = MAP_APPFONT ( X0 , 66 ) ; + Size = MAP_APPFONT ( W0 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Rewind when done playing" ; + }; + + FixedLine FL_TRIGGER + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 79 ) ; + Size = MAP_APPFONT( W0, 8 ); + + Text [ en-US ] = "Trigger"; + }; + + RadioButton RB_CLICKSEQUENCE + { + HelpID = "sd:RadioButton:RID_TP_CUSTOMANIMATION_DURATION:RB_CLICKSEQUENCE"; + Pos = MAP_APPFONT ( X1+6, 92 ) ; + Size = MAP_APPFONT ( W0 , 10 ) ; + Text [ en-US ] = "Animate as part of click sequence" ; + TabStop = TRUE ; + }; + + RadioButton RB_INTERACTIVE + { + HelpID = "sd:RadioButton:RID_TP_CUSTOMANIMATION_DURATION:RB_INTERACTIVE"; + Pos = MAP_APPFONT ( X1+6, 105 ) ; + Size = MAP_APPFONT ( W0 , 10 ) ; + Text [ en-US ] = "Start effect on click of" ; + TabStop = TRUE ; + }; + + ListBox LB_TRIGGER + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_DURATION:LB_TRIGGER"; + Pos = MAP_APPFONT ( X1+18 , 118 ); + Size = MAP_APPFONT ( W2, 80 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; +}; + +TabPage RID_TP_CUSTOMANIMATION_TEXT +{ + HelpID = "sd:TabPage:RID_TP_CUSTOMANIMATION_TEXT"; + Hide = TRUE; + Size = MAP_APPFONT ( WIDTH , 159 ); + Text [ en-US ] = "Text Animation"; + + FixedText FT_GROUP_TEXT + { + OutputSize = TRUE; + Pos = MAP_APPFONT ( X0 , 5 ) ; + Size = MAP_APPFONT( W1, 8 ); + + Text [ en-US ] = "Group text"; + }; + + ListBox LB_GROUP_TEXT + { + HelpID = "sd:ListBox:RID_TP_CUSTOMANIMATION_TEXT:LB_GROUP_TEXT"; + Pos = MAP_APPFONT ( X2 , 3 ) ; + Size = MAP_APPFONT ( W2, 48 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + + StringList [ en-US ] = + { + < "As one object" ; > ; + < "All paragraphs at once" ; > ; + < "By 1st level paragraphs" ; > ; + < "By 2nd level paragraphs" ; > ; + < "By 3rd level paragraphs" ; > ; + < "By 4th level paragraphs" ; > ; + < "By 5th level paragraphs" ; > ; + }; + }; + + CheckBox CBX_GROUP_AUTO + { + HelpID = "sd:CheckBox:RID_TP_CUSTOMANIMATION_TEXT:CBX_GROUP_AUTO"; + Pos = MAP_APPFONT ( X0 , 20 ) ; + Size = MAP_APPFONT ( W0 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Automatically after" ; + }; + + + MetricField MF_GROUP_AUTO + { + HelpID = "sd:MetricField:RID_TP_CUSTOMANIMATION_TEXT:MF_GROUP_AUTO"; + Pos = MAP_APPFONT ( X2 , 18 ) ; + Size = MAP_APPFONT ( W2, 12 ); + Border = TRUE ; + TabStop = TRUE ; + Left = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Minimum = 0 ; + Maximum = 9999 ; + DecimalDigits = 1 ; + Unit = FUNIT_CUSTOM ; + CustomUnitText [ en-US ] = "sec"; + SpinSize = 5 ; + }; + + CheckBox CBX_ANIMATE_FORM + { + HelpID = "sd:CheckBox:RID_TP_CUSTOMANIMATION_TEXT:CBX_ANIMATE_FORM"; + Pos = MAP_APPFONT ( X0 , 33 ) ; + Size = MAP_APPFONT ( W0 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Animate attached shape" ; + }; + + CheckBox CBX_REVERSE + { + HelpID = "sd:CheckBox:RID_TP_CUSTOMANIMATION_TEXT:CBX_REVERSE"; + Pos = MAP_APPFONT ( X0 , 46 ) ; + Size = MAP_APPFONT ( W0 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "In reverse order" ; + }; +}; diff --git a/sd/source/ui/animations/CustomAnimationList.cxx b/sd/source/ui/animations/CustomAnimationList.cxx new file mode 100755 index 000000000000..a80617e17eb0 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationList.cxx @@ -0,0 +1,1018 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/presentation/ShapeAnimationSubType.hpp> +#include <com/sun/star/presentation/EffectNodeType.hpp> +#include <com/sun/star/presentation/ParagraphTarget.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/animations/XIterateContainer.hpp> +#include <com/sun/star/presentation/EffectPresetClass.hpp> +#include <com/sun/star/presentation/EffectCommands.hpp> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <svx/ShapeTypeHandler.hxx> +#include "CustomAnimationList.hxx" +#ifndef _SD_CUSTOMANIMATIONPANE_HRC +#include "CustomAnimationPane.hrc" +#endif +#ifndef _SD_CUSTOMANIMATION_HRC +#include "CustomAnimation.hrc" +#endif +#include "CustomAnimationPreset.hxx" +#include <svtools/treelist.hxx> +#include <vcl/svapp.hxx> +#include "sdresid.hxx" + +#include "res_bmp.hrc" +#include "glob.hrc" + +#include <algorithm> + +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::Sequence; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::text::XTextRange; +using ::com::sun::star::drawing::XShape; +using ::com::sun::star::drawing::XShapes; +using ::com::sun::star::drawing::XDrawPage; +using ::com::sun::star::container::XChild; +using ::com::sun::star::container::XIndexAccess; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::beans::XPropertySetInfo; +using ::accessibility::ShapeTypeHandler; + +namespace sd { + +// go recursivly through all shapes in the given XShapes collection and return true as soon as the +// given shape is found. nIndex is incremented for each shape with the same shape type as the given +// shape is found until the given shape is found. +static bool getShapeIndex( const Reference< XShapes >& xShapes, const Reference< XShape >& xShape, sal_Int32& nIndex ) +{ + const sal_Int32 nCount = xShapes->getCount(); + sal_Int32 n; + for( n = 0; n < nCount; n++ ) + { + Reference< XShape > xChild; + xShapes->getByIndex( n ) >>= xChild; + if( xChild == xShape ) + return true; + + if( xChild->getShapeType() == xShape->getShapeType() ) + nIndex++; + + Reference< XShapes > xChildContainer( xChild, UNO_QUERY ); + if( xChildContainer.is() ) + { + if( getShapeIndex( xChildContainer, xShape, nIndex ) ) + return true; + } + } + + return false; +} + +// returns the index of the shape type from the given shape +static sal_Int32 getShapeIndex( const Reference< XShape >& xShape ) +{ + Reference< XChild > xChild( xShape, UNO_QUERY ); + Reference< XShapes > xPage; + + while( xChild.is() && !xPage.is() ) + { + Reference< XInterface > x( xChild->getParent() ); + xChild = Reference< XChild >::query( x ); + Reference< XDrawPage > xTestPage( x, UNO_QUERY ); + if( xTestPage.is() ) + xPage = Reference< XShapes >::query( x ); + } + + sal_Int32 nIndex = 1; + + if( xPage.is() && getShapeIndex( xPage, xShape, nIndex ) ) + return nIndex; + else + return -1; +} + +OUString getShapeDescription( const Reference< XShape >& xShape, bool bWithText = true ) +{ + OUString aDescription; + Reference< XPropertySet > xSet( xShape, UNO_QUERY ); + if( xSet.is() ) + { + Reference< XPropertySetInfo > xInfo( xSet->getPropertySetInfo() ); + const OUString aPropName( RTL_CONSTASCII_USTRINGPARAM("UINameSingular") ); + if( xInfo->hasPropertyByName( aPropName ) ) + xSet->getPropertyValue( aPropName ) >>= aDescription; + } + + aDescription += OUString( RTL_CONSTASCII_USTRINGPARAM(" ")); + aDescription += OUString::valueOf( getShapeIndex( xShape ) ); + + if( bWithText ) + { + Reference< XTextRange > xText( xShape, UNO_QUERY ); + if( xText.is() ) + { + OUString aText( xText->getString() ); + if( aText.getLength() ) + { + aDescription += OUString(RTL_CONSTASCII_USTRINGPARAM(": ")); + + aText = aText.replace( (sal_Unicode)'\n', (sal_Unicode)' ' ); + aText = aText.replace( (sal_Unicode)'\r', (sal_Unicode)' ' ); + + aDescription += aText; + } + } + } + return aDescription; +} + +static OUString getDescription( const Any& rTarget, bool bWithText = true ) +{ + OUString aDescription; + + if( rTarget.getValueType() == ::getCppuType((const ParagraphTarget*)0) ) + { + ParagraphTarget aParaTarget; + rTarget >>= aParaTarget; + + Reference< XEnumerationAccess > xText( aParaTarget.Shape, UNO_QUERY_THROW ); + Reference< XEnumeration > xEnumeration( xText->createEnumeration(), UNO_QUERY_THROW ); + sal_Int32 nPara = aParaTarget.Paragraph; + + while( xEnumeration->hasMoreElements() && nPara ) + { + xEnumeration->nextElement(); + nPara--; + } + + DBG_ASSERT( xEnumeration->hasMoreElements(), "sd::CustomAnimationEffect::prepareText(), paragraph out of range!" ); + + if( xEnumeration->hasMoreElements() ) + { + Reference< XTextRange > xParagraph; + xEnumeration->nextElement() >>= xParagraph; + + if( xParagraph.is() ) + aDescription = xParagraph->getString(); + } + } + else + { + Reference< XShape > xShape; + rTarget >>= xShape; + if( xShape.is() ) + aDescription = getShapeDescription( xShape, bWithText ); + } + + return aDescription; +} + +// ==================================================================== + +class CustomAnimationListEntryItem : public SvLBoxString +{ +public: + CustomAnimationListEntryItem( SvLBoxEntry*,sal_uInt16 nFlags, OUString aDescription, CustomAnimationEffectPtr pEffect, CustomAnimationList* pParent ); + virtual ~CustomAnimationListEntryItem(); + void InitViewData( SvLBox*,SvLBoxEntry*,SvViewDataItem* ); + void Paint( const Point&, SvLBox& rDev, sal_uInt16 nFlags,SvLBoxEntry* ); + SvLBoxItem* Create() const; + void Clone( SvLBoxItem* pSource ); + +private: + CustomAnimationList* mpParent; + OUString maDescription; + CustomAnimationEffectPtr mpEffect; +}; + +// -------------------------------------------------------------------- + +CustomAnimationListEntryItem::CustomAnimationListEntryItem( SvLBoxEntry* pEntry, sal_uInt16 nFlags, OUString aDescription, CustomAnimationEffectPtr pEffect, CustomAnimationList* pParent ) +: SvLBoxString( pEntry, nFlags, aDescription ) +, mpParent( pParent ) +, maDescription( aDescription ) +, mpEffect(pEffect) +{ +} + +// -------------------------------------------------------------------- + +CustomAnimationListEntryItem::~CustomAnimationListEntryItem() +{ +} + +// -------------------------------------------------------------------- + +void CustomAnimationListEntryItem::InitViewData( SvLBox* pView, SvLBoxEntry* pEntry, SvViewDataItem* pViewData ) +{ + if( !pViewData ) + pViewData = pView->GetViewDataItem( pEntry, this ); + + Size aSize(pView->GetTextWidth( maDescription ) + 2 * 19, pView->GetTextHeight() ); + if( aSize.Height() < 19 ) + aSize.Height() = 19; + pViewData->aSize = aSize; +} + +// -------------------------------------------------------------------- + +void CustomAnimationListEntryItem::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16, SvLBoxEntry* pEntry ) +{ + const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); + + SvViewDataItem* pViewData = mpParent->GetViewDataItem( pEntry, this ); + + Point aPos( rPos ); + Size aSize( pViewData->aSize ); + + sal_Int16 nNodeType = mpEffect->getNodeType(); + if( nNodeType == EffectNodeType::ON_CLICK ) + { + rDev.DrawImage( aPos, mpParent->getImage( IMG_CUSTOMANIMATION_ON_CLICK, bHighContrast ) ); + } + else if( nNodeType == EffectNodeType::AFTER_PREVIOUS ) + { + rDev.DrawImage( aPos, mpParent->getImage( IMG_CUSTOMANIMATION_AFTER_PREVIOUS, bHighContrast ) ); + } + + aPos.X() += 19; + + sal_uInt16 nImage; + switch( mpEffect->getPresetClass() ) + { + case EffectPresetClass::ENTRANCE: nImage = IMG_CUSTOMANIMATION_ENTRANCE_EFFECT; break; + case EffectPresetClass::EXIT: nImage = IMG_CUSTOMANIMATION_EXIT_EFFECT; break; + case EffectPresetClass::EMPHASIS: nImage = IMG_CUSTOMANIMATION_EMPHASIS_EFFECT; break; + case EffectPresetClass::MOTIONPATH: nImage = IMG_CUSTOMANIMATION_MOTION_PATH; break; + case EffectPresetClass::OLEACTION: nImage = IMG_CUSTOMANIMATION_OLE; break; + case EffectPresetClass::MEDIACALL: + switch( mpEffect->getCommand() ) + { + case EffectCommands::TOGGLEPAUSE: nImage = IMG_CUSTOMANIMATION_MEDIA_PAUSE; break; + case EffectCommands::STOP: nImage = IMG_CUSTOMANIMATION_MEDIA_STOP; break; + case EffectCommands::PLAY: + default: nImage = IMG_CUSTOMANIMATION_MEDIA_PLAY; break; + } + break; + default: nImage = 0xffff; + } + + if( nImage != 0xffff ) + { + const Image& rImage = mpParent->getImage( nImage, bHighContrast ); + Point aImagePos( aPos ); + aImagePos.Y() += ( aSize.Height() - rImage.GetSizePixel().Height() ) >> 1; + rDev.DrawImage( aImagePos, rImage ); + } + + aPos.X() += 19; + aPos.Y() += ( aSize.Height() - rDev.GetTextHeight()) >> 1; + + rDev.DrawText( aPos, rDev.GetEllipsisString( maDescription, rDev.GetOutputSizePixel().Width() - aPos.X() ) ); +} + +// -------------------------------------------------------------------- + +SvLBoxItem* CustomAnimationListEntryItem::Create() const +{ + return NULL; +} + +// -------------------------------------------------------------------- + +void CustomAnimationListEntryItem::Clone( SvLBoxItem* ) +{ +} + +// ==================================================================== + +class CustomAnimationListEntry : public SvLBoxEntry +{ +public: + CustomAnimationListEntry(); + CustomAnimationListEntry( CustomAnimationEffectPtr pEffect ); + virtual ~CustomAnimationListEntry(); + + CustomAnimationEffectPtr getEffect() const { return mpEffect; } + +private: + CustomAnimationEffectPtr mpEffect; +}; + +// -------------------------------------------------------------------- + +CustomAnimationListEntry::CustomAnimationListEntry() +{ +} + +// -------------------------------------------------------------------- + +CustomAnimationListEntry::CustomAnimationListEntry( CustomAnimationEffectPtr pEffect ) +: mpEffect( pEffect ) +{ +} + +// -------------------------------------------------------------------- + +CustomAnimationListEntry::~CustomAnimationListEntry() +{ +} + +// ==================================================================== + +class CustomAnimationTriggerEntryItem : public SvLBoxString +{ +public: + CustomAnimationTriggerEntryItem( SvLBoxEntry*,sal_uInt16 nFlags, OUString aDescription, CustomAnimationList* pParent ); + virtual ~CustomAnimationTriggerEntryItem(); + virtual sal_uInt16 IsA(); + void InitViewData( SvLBox*,SvLBoxEntry*,SvViewDataItem* ); + void Paint( const Point&, SvLBox& rDev, sal_uInt16 nFlags,SvLBoxEntry* ); + SvLBoxItem* Create() const; + void Clone( SvLBoxItem* pSource ); + +private: + CustomAnimationList* mpParent; + OUString maDescription; +}; + +// -------------------------------------------------------------------- + +CustomAnimationTriggerEntryItem::CustomAnimationTriggerEntryItem( SvLBoxEntry* pEntry, sal_uInt16 nFlags, OUString aDescription, CustomAnimationList* pParent ) +: SvLBoxString( pEntry, nFlags, aDescription ), mpParent( pParent ), maDescription( aDescription ) +{ +} + +// -------------------------------------------------------------------- + +CustomAnimationTriggerEntryItem::~CustomAnimationTriggerEntryItem() +{ +} + +// -------------------------------------------------------------------- + +sal_uInt16 CustomAnimationTriggerEntryItem::IsA() +{ + return (sal_uInt16)-1; +} + +// -------------------------------------------------------------------- + +void CustomAnimationTriggerEntryItem::InitViewData( SvLBox* pView, SvLBoxEntry* pEntry, SvViewDataItem* pViewData ) +{ + if( !pViewData ) + pViewData = pView->GetViewDataItem( pEntry, this ); + + Size aSize(pView->GetTextWidth( maDescription ) + 2 * 19, pView->GetTextHeight() ); + if( aSize.Height() < 19 ) + aSize.Height() = 19; + pViewData->aSize = aSize; + +/* + SvViewData* pViewData = pView->GetViewData( pEntry ); + if( pViewData ) + pViewData->SetSelectable(false); +*/ +} + +// -------------------------------------------------------------------- + +void CustomAnimationTriggerEntryItem::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16, SvLBoxEntry* ) +{ + Size aSize( rDev.GetOutputSizePixel().Width(), static_cast< SvTreeListBox* >(&rDev)->GetEntryHeight() ); + + Point aPos( 0, rPos.Y() ); + + Rectangle aOutRect( aPos, aSize ); + + // fill the background + Color aColor (rDev.GetSettings().GetStyleSettings().GetDialogColor()); + + rDev.Push(); + rDev.SetFillColor (aColor); + rDev.SetLineColor (); + rDev.DrawRect(aOutRect); + + // Erase the four corner pixels to make the rectangle appear rounded. + rDev.SetLineColor( rDev.GetSettings().GetStyleSettings().GetWindowColor()); + rDev.DrawPixel( aOutRect.TopLeft()); + rDev.DrawPixel( Point(aOutRect.Right(), aOutRect.Top())); + rDev.DrawPixel( Point(aOutRect.Left(), aOutRect.Bottom())); + rDev.DrawPixel( Point(aOutRect.Right(), aOutRect.Bottom())); + + // draw the category title + + int nVertBorder = (( aSize.Height() - rDev.GetTextHeight()) >> 1); + int nHorzBorder = rDev.LogicToPixel( Size( 3, 3 ), MAP_APPFONT ).Width(); + + aOutRect.nLeft += nHorzBorder; + aOutRect.nRight -= nHorzBorder; + aOutRect.nTop += nVertBorder; + aOutRect.nBottom -= nVertBorder; + + rDev.DrawText (aOutRect, rDev.GetEllipsisString( maDescription, aOutRect.GetWidth() ) ); + rDev.Pop(); +} + +// -------------------------------------------------------------------- + +SvLBoxItem* CustomAnimationTriggerEntryItem::Create() const +{ + return NULL; +} + +// -------------------------------------------------------------------- + +void CustomAnimationTriggerEntryItem::Clone( SvLBoxItem* ) +{ +} + +// ==================================================================== + +CustomAnimationList::CustomAnimationList( ::Window* pParent, const ResId& rResId, ICustomAnimationListController* pController ) +: SvTreeListBox( pParent, rResId ) +, mbIgnorePaint( false ) +, mpController( pController ) +, mpLastParentEntry(0) +{ + SetStyle( GetStyle() | WB_TABSTOP | WB_BORDER | WB_HASLINES | WB_HASBUTTONS | WB_HASBUTTONSATROOT ); + + EnableContextMenuHandling(); + SetSelectionMode( MULTIPLE_SELECTION ); + SetIndent(16); + SetNodeDefaultImages(); +} + +// -------------------------------------------------------------------- + +const Image& CustomAnimationList::getImage( sal_uInt16 nId, bool bHighContrast ) +{ + DBG_ASSERT( (nId >= IMG_CUSTOMANIMATION_ON_CLICK) && (nId <= IMG_CUSTOMANIMATION_MEDIA_STOP), "sd::CustomAnimationList::getImage(), illegal index!" ); + + if( bHighContrast ) + nId += 1; + + Image& rImage = maImages[nId - IMG_CUSTOMANIMATION_ON_CLICK]; + + // load on demand + if( rImage.GetSizePixel().Width() == 0 ) + rImage = Image(SdResId( nId ) ); + + return rImage; +} + +// -------------------------------------------------------------------- + +CustomAnimationList::~CustomAnimationList() +{ + if( mpMainSequence.get() ) + mpMainSequence->removeListener( this ); + + clear(); +} + +// -------------------------------------------------------------------- + +void CustomAnimationList::KeyInput( const KeyEvent& rKEvt ) +{ + const int nKeyCode = rKEvt.GetKeyCode().GetCode(); + switch( nKeyCode ) + { + case KEY_DELETE: mpController->onContextMenu( CM_REMOVE ); return; + case KEY_INSERT: mpController->onContextMenu( CM_CREATE ); return; + case KEY_SPACE: + { + const Point aPos; + const CommandEvent aCEvt( aPos, COMMAND_CONTEXTMENU ); + Command( aCEvt ); + return; + } + + } + + ::SvTreeListBox::KeyInput( rKEvt ); +} + +// -------------------------------------------------------------------- + +/** selects or deselects the given effect. + Selections of other effects are not changed */ +void CustomAnimationList::select( CustomAnimationEffectPtr pEffect, bool bSelect /* = true */ ) +{ + CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(First()); + while( pEntry ) + { + if( pEntry->getEffect() == pEffect ) + { + Select( pEntry, bSelect ); + break; + } + pEntry = static_cast< CustomAnimationListEntry* >(Next( pEntry )); + } + + if( !pEntry && bSelect ) + { + append( pEffect ); + select( pEffect ); + } +} + +// -------------------------------------------------------------------- + +void CustomAnimationList::clear() +{ + Clear(); + + mpLastParentEntry = 0; + mxLastTargetShape = 0; +} + +// -------------------------------------------------------------------- + +void CustomAnimationList::update( MainSequencePtr pMainSequence ) +{ + if( mpMainSequence.get() ) + mpMainSequence->removeListener( this ); + + mpMainSequence = pMainSequence; + update(); + + if( mpMainSequence.get() ) + mpMainSequence->addListener( this ); +} + +// -------------------------------------------------------------------- + +struct stl_append_effect_func : public std::unary_function<CustomAnimationEffectPtr, void> +{ + stl_append_effect_func( CustomAnimationList& rList ) : mrList( rList ) {} + void operator()(CustomAnimationEffectPtr pEffect); + CustomAnimationList& mrList; +}; + +void stl_append_effect_func::operator()(CustomAnimationEffectPtr pEffect) +{ + mrList.append( pEffect ); +} +// -------------------------------------------------------------------- + +void CustomAnimationList::update() +{ + mbIgnorePaint = true; + + CustomAnimationListEntry* pEntry = 0; + + std::list< CustomAnimationEffectPtr > aExpanded; + std::list< CustomAnimationEffectPtr > aSelected; + + CustomAnimationEffectPtr pFirstVisibleEffect; + + if( mpMainSequence.get() ) + { + // save selection and expand states + pEntry = static_cast<CustomAnimationListEntry*>(FirstVisible()); + if( pEntry ) + pFirstVisibleEffect = pEntry->getEffect(); + + pEntry = static_cast<CustomAnimationListEntry*>(First()); + + while( pEntry ) + { + CustomAnimationEffectPtr pEffect( pEntry->getEffect() ); + if( pEffect.get() ) + { + if( IsExpanded( pEntry ) ) + aExpanded.push_back( pEffect ); + + if( IsSelected( pEntry ) ) + aSelected.push_back( pEffect ); + } + + pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry )); + } + } + + // rebuild list + clear(); + if( mpMainSequence.get() ) + { + std::for_each( mpMainSequence->getBegin(), mpMainSequence->getEnd(), stl_append_effect_func( *this ) ); + mpLastParentEntry = 0; + + const InteractiveSequenceList& rISL = mpMainSequence->getInteractiveSequenceList(); + + InteractiveSequenceList::const_iterator aIter( rISL.begin() ); + const InteractiveSequenceList::const_iterator aEnd( rISL.end() ); + while( aIter != aEnd ) + { + InteractiveSequencePtr pIS( (*aIter++) ); + + Reference< XShape > xShape( pIS->getTriggerShape() ); + if( xShape.is() ) + { + SvLBoxEntry* pLBoxEntry = new CustomAnimationListEntry; + pLBoxEntry->AddItem( new SvLBoxContextBmp( pLBoxEntry, 0, Image(), Image(), 0)); + OUString aDescription = String( SdResId( STR_CUSTOMANIMATION_TRIGGER ) ); + aDescription += OUString( RTL_CONSTASCII_USTRINGPARAM(": ") ); + aDescription += getShapeDescription( xShape, false ); + pLBoxEntry->AddItem( new CustomAnimationTriggerEntryItem( pLBoxEntry, 0, aDescription, this ) ); + Insert( pLBoxEntry ); + SvViewData* pViewData = GetViewData( pLBoxEntry ); + if( pViewData ) + pViewData->SetSelectable(false); + + std::for_each( pIS->getBegin(), pIS->getEnd(), stl_append_effect_func( *this ) ); + mpLastParentEntry = 0; + } + } + + // restore selection and expand states + pEntry = static_cast<CustomAnimationListEntry*>(First()); + + while( pEntry ) + { + CustomAnimationEffectPtr pEffect( pEntry->getEffect() ); + if( pEffect.get() ) + { + if( std::find( aExpanded.begin(), aExpanded.end(), pEffect ) != aExpanded.end() ) + Expand( pEntry ); + + if( std::find( aSelected.begin(), aSelected.end(), pEffect ) != aSelected.end() ) + Select( pEntry ); + + if( pFirstVisibleEffect == pEffect ) + MakeVisible( pEntry ); + } + + pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry )); + } + } + + mbIgnorePaint = false; + Invalidate(); +} + +// -------------------------------------------------------------------- + +/* +void CustomAnimationList::update( CustomAnimationEffectPtr pEffect ) +{ + SvLBoxEntry* pEntry = First(); + while( pEntry ) + { + if( static_cast< CustomAnimationEffectPtr * >( pEntry->GetUserData() )->get() == pEffect.get() ) + { + CustomAnimationPresetsPtr pPresets = mpController->getPresets(); + const CustomAnimationPresetPtr pPreset = pPresets->getEffectDescriptor( pEffect->getPresetId() ); + if( pPreset.get() ) + pEffect->setName( pPresets->getUINameForPresetId( pPreset->getPresetId() ) ); + else + pEffect->setName( pEffect->getPresetId() ); + break; + } + pEntry = Next( pEntry ); + } + + Invalidate(); +} +*/ + +// -------------------------------------------------------------------- + +void CustomAnimationList::append( CustomAnimationEffectPtr pEffect ) +{ + // create a ui description + OUString aDescription; + + Any aTarget( pEffect->getTarget() ); + if( aTarget.hasValue() ) try + { + aDescription = getDescription( aTarget, pEffect->getTargetSubItem() != ShapeAnimationSubType::ONLY_BACKGROUND ); + + SvLBoxEntry* pParentEntry = 0; + + Reference< XShape > xTargetShape( pEffect->getTargetShape() ); + sal_Int32 nGroupId = pEffect->getGroupId(); + + // if this effect has the same target and group-id as the last root effect, + // the last root effect is also this effects parent + if( mpLastParentEntry && (nGroupId != -1) && (mxLastTargetShape == xTargetShape) && (mnLastGroupId == nGroupId) ) + pParentEntry = mpLastParentEntry; + + // create an entry for the effect + SvLBoxEntry* pEntry = new CustomAnimationListEntry( pEffect ); + + pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0)); + pEntry->AddItem( new CustomAnimationListEntryItem( pEntry, 0, aDescription, pEffect, this ) ); + + if( pParentEntry ) + { + // add a subentry + Insert( pEntry, pParentEntry ); + } + else + { + // add a root entry + Insert( pEntry ); + + // and the new root entry becomes the possible next group header + mxLastTargetShape = xTargetShape; + mnLastGroupId = nGroupId; + mpLastParentEntry = pEntry; + } + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR("sd::CustomAnimationList::append(), exception catched!" ); + } +} + +// -------------------------------------------------------------------- + +/* +void CustomAnimationList::remove( CustomAnimationEffectPtr pEffect ) +{ + SvLBoxEntry* pEntry = First(); + while( pEntry ) + { + if( static_cast< CustomAnimationEffectPtr * >( pEntry->GetUserData() )->get() == pEffect.get() ) + { + GetModel()->Remove( pEntry ); + if( pEntry == mpLastParentEntry ) + { + mpLastParentEntry = 0; + mxLastTargetShape = 0; + } + break; + } + pEntry = Next( pEntry ); + } + + Invalidate(); +} +*/ + +// -------------------------------------------------------------------- + +void selectShape( SvTreeListBox* pTreeList, Reference< XShape > xShape ) +{ + CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(pTreeList->First()); + while( pEntry ) + { + CustomAnimationEffectPtr pEffect( pEntry->getEffect() ); + if( pEffect.get() ) + { + if( pEffect->getTarget() == xShape ) + pTreeList->Select( pEntry ); + } + + pEntry = static_cast< CustomAnimationListEntry* >(pTreeList->Next( pEntry )); + } +} + +// -------------------------------------------------------------------- + +void CustomAnimationList::onSelectionChanged( Any aSelection ) +{ + try + { + SelectAll(sal_False); + + if( aSelection.hasValue() ) + { + Reference< XIndexAccess > xShapes( aSelection, UNO_QUERY ); + if( xShapes.is() ) + { + sal_Int32 nCount = xShapes->getCount(); + sal_Int32 nIndex; + for( nIndex = 0; nIndex < nCount; nIndex++ ) + { + Reference< XShape > xShape( xShapes->getByIndex( nIndex ), UNO_QUERY ); + if( xShape.is() ) + selectShape( this, xShape ); + } + } + else + { + Reference< XShape > xShape( aSelection, UNO_QUERY ); + if( xShape.is() ) + selectShape( this, xShape ); + } + } + + SelectHdl(); + } + catch( Exception& ) + { + DBG_ERROR( "sd::CustomAnimationList::onSelectionChanged(), Exception catched!" ); + } +} + +// -------------------------------------------------------------------- + +void CustomAnimationList::SelectHdl() +{ + SvTreeListBox::SelectHdl(); + mpController->onSelect(); +} + +// -------------------------------------------------------------------- + +bool CustomAnimationList::isExpanded( const CustomAnimationEffectPtr& pEffect ) const +{ + CustomAnimationListEntry* pEntry = static_cast<CustomAnimationListEntry*>(First()); + + while( pEntry ) + { + if( pEntry->getEffect() == pEffect ) + break; + + pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry )); + } + + if( pEntry ) + pEntry = static_cast<CustomAnimationListEntry*>(GetParent( pEntry )); + + return (pEntry == 0) || IsExpanded( pEntry ); +} + +// -------------------------------------------------------------------- +EffectSequence CustomAnimationList::getSelection() const +{ + EffectSequence aSelection; + + CustomAnimationListEntry* pEntry = dynamic_cast< CustomAnimationListEntry* >(FirstSelected()); + while( pEntry ) + { + CustomAnimationEffectPtr pEffect( pEntry->getEffect() ); + if( pEffect.get() ) + aSelection.push_back( pEffect ); + + // if the selected effect is not expanded and has children + // we say that the children are automaticly selected + if( !IsExpanded( pEntry ) ) + { + CustomAnimationListEntry* pChild = dynamic_cast< CustomAnimationListEntry* >( FirstChild( pEntry ) ); + while( pChild ) + { + if( !IsSelected( pChild ) ) + { + CustomAnimationEffectPtr pChildEffect( pChild->getEffect() ); + if( pChildEffect.get() ) + aSelection.push_back( pChildEffect ); + } + + pChild = dynamic_cast< CustomAnimationListEntry* >( NextSibling( pChild ) ); + } + } + + pEntry = static_cast< CustomAnimationListEntry* >(NextSelected( pEntry )); + } + + return aSelection; +} + +// -------------------------------------------------------------------- + +sal_Bool CustomAnimationList::DoubleClickHdl() +{ + mpController->onDoubleClick(); + return false; +} + +// -------------------------------------------------------------------- + +PopupMenu* CustomAnimationList::CreateContextMenu() +{ + PopupMenu* pMenu = new PopupMenu(SdResId( RID_EFFECT_CONTEXTMENU )); + + sal_Int16 nNodeType = -1; + sal_Int16 nEntries = 0; + + CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(FirstSelected()); + while( pEntry ) + { + nEntries++; + CustomAnimationEffectPtr pEffect( pEntry->getEffect() ); + if( pEffect.get() ) + { + if( nNodeType == -1 ) + { + nNodeType = pEffect->getNodeType(); + } + else + { + if( nNodeType != pEffect->getNodeType() ) + { + nNodeType = -1; + break; + } + } + } + + pEntry = static_cast< CustomAnimationListEntry* >(NextSelected( pEntry )); + } + + pMenu->CheckItem( CM_WITH_CLICK, nNodeType == EffectNodeType::ON_CLICK ); + pMenu->CheckItem( CM_WITH_PREVIOUS, nNodeType == EffectNodeType::WITH_PREVIOUS ); + pMenu->CheckItem( CM_AFTER_PREVIOUS, nNodeType == EffectNodeType::AFTER_PREVIOUS ); + pMenu->EnableItem( CM_OPTIONS, nEntries == 1 ); + pMenu->EnableItem( CM_DURATION, nEntries == 1 ); + + return pMenu; +} + +// -------------------------------------------------------------------- + +void CustomAnimationList::ExcecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry ) +{ + mpController->onContextMenu( nSelectedPopupEntry ); +} + +// -------------------------------------------------------------------- + +void CustomAnimationList::SetTabs() +{ + SvTreeListBox::SetTabs(); +} + +// -------------------------------------------------------------------- + +void CustomAnimationList::notify_change() +{ + update(); + mpController->onSelect(); +} + +void CustomAnimationList::Paint( const Rectangle& rRect ) +{ + if( mbIgnorePaint ) + return; + + SvTreeListBox::Paint( rRect ); + + // draw help text if list box is still empty + if( First() == 0 ) + { + Color aOldColor( GetTextColor() ); + SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() ); + ::Point aOffset( LogicToPixel( Point( 6, 6 ), MAP_APPFONT ) ); + + Rectangle aRect( Point( 0,0 ), GetOutputSizePixel() ); + + aRect.Left() += aOffset.X(); + aRect.Top() += aOffset.Y(); + aRect.Right() -= aOffset.X(); + aRect.Bottom() -= aOffset.Y(); + + DrawText( aRect, String( SdResId( STR_CUSTOMANIMATION_LIST_HELPTEXT ) ), + TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK | TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER ); + + SetTextColor( aOldColor ); + } +} + +} diff --git a/sd/source/ui/animations/CustomAnimationList.hxx b/sd/source/ui/animations/CustomAnimationList.hxx new file mode 100755 index 000000000000..185c1a6dbb5c --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationList.hxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_CUSTOMANIMATIONLIST_HXX +#define _SD_CUSTOMANIMATIONLIST_HXX + +#include <com/sun/star/drawing/XShape.hpp> +#include <svtools/svtreebx.hxx> +#include <CustomAnimationEffect.hxx> +#include "CustomAnimationPreset.hxx" +#ifndef _SD_CUSTOMANIMATION_HRC +#include "CustomAnimation.hrc" +#endif + +namespace sd { + +class CustomAnimationEffect; +typedef boost::shared_ptr< CustomAnimationEffect > CustomAnimationEffectPtr; + +class ICustomAnimationListController +{ +public: + virtual void onSelect() = 0; + virtual void onDoubleClick() = 0; + virtual void onContextMenu( sal_uInt16 nSelectedPopupEntry ) = 0; + virtual ~ICustomAnimationListController() {} +}; + +class CustomAnimationList : public SvTreeListBox, public ISequenceListener +{ + friend class CustomAnimationListEntryItem; + friend struct stl_append_effect_func; + +public: + CustomAnimationList( ::Window* pParent, const ResId& rResId, ICustomAnimationListController* pController ); + virtual ~CustomAnimationList(); + + // methods + + /** selects or deselects the given effect. + Selections of other effects are not changed */ + void select( CustomAnimationEffectPtr pEffect, bool bSelect = true ); + + /** populates the list with all effects from the given MainSequence */ + void update( MainSequencePtr pMainSequence ); + + /** updates the given effect in the list */ +// void update( CustomAnimationEffectPtr pEffect ); + + void update(); + + /** removes the given effect to the list*/ +// void remove( CustomAnimationEffectPtr pEffect ); + + EffectSequence getSelection() const; + + // events + void onSelectionChanged( ::com::sun::star::uno::Any aSelection ); + + // overrides + virtual void SelectHdl(); + virtual sal_Bool DoubleClickHdl(); + + virtual void Paint( const Rectangle& rRect ); + + virtual PopupMenu* CreateContextMenu( void ); + virtual void ExcecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry ); + + virtual void KeyInput( const KeyEvent& rKEvt ); + +// virtual SvLBoxEntry* CreateEntry() const; + virtual void SetTabs(); + + virtual void notify_change(); + + const Image& getImage( sal_uInt16 nId, bool bHighContrast ); + + bool isExpanded( const CustomAnimationEffectPtr& pEffect ) const; + + /// clears all entries from the listbox + void clear(); + +private: + bool mbIgnorePaint; + + /** appends the given effect to the list*/ + void append( CustomAnimationEffectPtr pEffect ); + + ICustomAnimationListController* mpController; + + MainSequencePtr mpMainSequence; + + Image maImgEmpty; + + Image maImages[ IMG_CUSTOMANIMATION_MEDIA_STOP_H - IMG_CUSTOMANIMATION_ON_CLICK + 1]; + + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mxLastTargetShape; + sal_Int32 mnLastGroupId; + SvLBoxEntry* mpLastParentEntry; + +}; + +} + +#endif // _SD_CUSTOMANIMATIONLIST_HXX + diff --git a/sd/source/ui/animations/CustomAnimationPane.cxx b/sd/source/ui/animations/CustomAnimationPane.cxx new file mode 100755 index 000000000000..73d595a8eb1e --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationPane.cxx @@ -0,0 +1,2499 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include <com/sun/star/presentation/EffectPresetClass.hpp> +#include <com/sun/star/animations/XAnimationNodeSupplier.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/presentation/EffectNodeType.hpp> +#include <com/sun/star/presentation/EffectCommands.hpp> +#include <com/sun/star/animations/AnimationTransformType.hpp> +#include <com/sun/star/text/XTextRangeCompare.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/presentation/ParagraphTarget.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/drawing/FillStyle.hpp> +#include <comphelper/processfactory.hxx> +#include <sfx2/dispatch.hxx> +#include "STLPropertySet.hxx" +#include "CustomAnimationPane.hxx" +#include "CustomAnimationDialog.hxx" +#include "CustomAnimationCreateDialog.hxx" +#include "CustomAnimationPane.hrc" +#include "CustomAnimation.hrc" +#include "CustomAnimationList.hxx" +#include <vcl/lstbox.hxx> +#include <vcl/fixed.hxx> + +#include <vcl/button.hxx> +#include <vcl/combobox.hxx> +#include <vcl/scrbar.hxx> + +#include <comphelper/sequence.hxx> +#include <sfx2/frame.hxx> + +#include <svx/unoapi.hxx> +#include <svx/svxids.hrc> +#include <DrawDocShell.hxx> +#include <ViewShellBase.hxx> +#include "DrawViewShell.hxx" +#include "DrawController.hxx" +#include "sdresid.hxx" +#include "drawview.hxx" +#include "slideshow.hxx" +#include "undoanim.hxx" +#include "optsitem.hxx" +#include "sddll.hxx" +#include "framework/FrameworkHelper.hxx" + +#include "EventMultiplexer.hxx" +#include "DialogListBox.hxx" + +#include "glob.hrc" +#include "sdpage.hxx" +#include "drawdoc.hxx" +#include "app.hrc" + +#include <memory> +#include <algorithm> + +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/range/b2drange.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::animations; +using namespace ::com::sun::star::presentation; +using namespace ::com::sun::star::text; + +using ::rtl::OUString; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing; +using ::com::sun::star::view::XSelectionSupplier; +using ::com::sun::star::view::XSelectionChangeListener; +using ::com::sun::star::frame::XController; +using ::com::sun::star::frame::XModel; +using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::beans::XPropertyChangeListener; +using ::com::sun::star::container::XIndexAccess; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::text::XText; +using ::sd::framework::FrameworkHelper; + +namespace sd { + +// -------------------------------------------------------------------- + +void fillDurationComboBox( ComboBox* pBox ) +{ + static const double gdVerySlow = 5.0; + static const double gdSlow = 3.0; + static const double gdNormal = 2.0; + static const double gdFast = 1.0; + static const double gdVeryFast = 0.5; + + String aVerySlow( SdResId( STR_CUSTOMANIMATION_DURATION_VERY_SLOW ) ); + pBox->SetEntryData( pBox->InsertEntry( aVerySlow ), (void*)&gdVerySlow ); + + String aSlow( SdResId( STR_CUSTOMANIMATION_DURATION_SLOW ) ); + pBox->SetEntryData( pBox->InsertEntry( aSlow ), (void*)&gdSlow ); + + String aNormal( SdResId( STR_CUSTOMANIMATION_DURATION_NORMAL ) ); + pBox->SetEntryData( pBox->InsertEntry( aNormal ), (void*)&gdNormal ); + + String aFast( SdResId( STR_CUSTOMANIMATION_DURATION_FAST ) ); + pBox->SetEntryData( pBox->InsertEntry( aFast ), (void*)&gdFast ); + + String aVeryFast( SdResId( STR_CUSTOMANIMATION_DURATION_VERY_FAST ) ); + pBox->SetEntryData( pBox->InsertEntry( aVeryFast ), (void*)&gdVeryFast ); +} + +void fillRepeatComboBox( ComboBox* pBox ) +{ + String aNone( SdResId( STR_CUSTOMANIMATION_REPEAT_NONE ) ); + pBox->SetEntryData( pBox->InsertEntry( aNone ), (void*)((sal_Int32)0) ); + + pBox->SetEntryData( pBox->InsertEntry( String::CreateFromInt32( 2 ) ), (void*)((sal_Int32)1) ); + pBox->SetEntryData( pBox->InsertEntry( String::CreateFromInt32( 3 ) ), (void*)((sal_Int32)3) ); + pBox->SetEntryData( pBox->InsertEntry( String::CreateFromInt32( 4 ) ), (void*)((sal_Int32)4) ); + pBox->SetEntryData( pBox->InsertEntry( String::CreateFromInt32( 5 ) ), (void*)((sal_Int32)5) ); + pBox->SetEntryData( pBox->InsertEntry( String::CreateFromInt32( 10 ) ), (void*)((sal_Int32)10) ); + + String aUntilClick( SdResId( STR_CUSTOMANIMATION_REPEAT_UNTIL_NEXT_CLICK ) ); + pBox->SetEntryData( pBox->InsertEntry( aUntilClick ), (void*)((sal_Int32)-1) ); + + String aEndOfSlide( SdResId( STR_CUSTOMANIMATION_REPEAT_UNTIL_END_OF_SLIDE ) ); + pBox->SetEntryData( pBox->InsertEntry( aEndOfSlide ), (void*)((sal_Int32)-2) ); +} + +// -------------------------------------------------------------------- + +CustomAnimationPane::CustomAnimationPane( ::Window* pParent, ViewShellBase& rBase, const Size& rMinSize ) +: Control( pParent, SdResId(DLG_CUSTOMANIMATIONPANE) ), + mrBase( rBase ), + mpCustomAnimationPresets(NULL), + mnPropertyType( nPropertyTypeNone ), + maMinSize( rMinSize ), + mxModel( rBase.GetDocShell()->GetDoc()->getUnoModel(), UNO_QUERY ), + maLateInitTimer() +{ + // load resources + mpFLEffect = new FixedLine( this, SdResId( FL_EFFECT ) ); + + mpPBAddEffect = new PushButton( this, SdResId( PB_ADD_EFFECT ) ); + mpPBChangeEffect = new PushButton( this, SdResId( PB_CHANGE_EFFECT ) ); + mpPBRemoveEffect = new PushButton( this, SdResId( PB_REMOVE_EFFECT ) ); + + mpFLModify = new FixedLine( this, SdResId( FL_MODIFY ) ); + + mpFTStart = new FixedText( this, SdResId( FT_START ) ); + mpLBStart = new ListBox( this, SdResId( LB_START ) ); + mpFTProperty = new FixedText( this, SdResId( FT_PROPERTY ) ); + mpLBProperty = new PropertyControl( this, SdResId( LB_PROPERTY ) ); + mpPBPropertyMore = new PushButton( this, SdResId( PB_PROPERTY_MORE ) ); + + mpFTSpeed = new FixedText( this, SdResId( FT_SPEED ) ); + mpCBSpeed = new ComboBox( this, SdResId( CB_SPEED ) ); + + mpCustomAnimationList = new CustomAnimationList( this, SdResId( CT_CUSTOM_ANIMATION_LIST ), this ); + + mpPBMoveUp = new PushButton( this, SdResId( PB_MOVE_UP ) ); + mpPBMoveDown = new PushButton( this, SdResId( PB_MOVE_DOWN ) ); + mpFTChangeOrder = new FixedText( this, SdResId( FT_CHANGE_ORDER ) ); + mpFLSeperator1 = new FixedLine( this, SdResId( FL_SEPERATOR1 ) ); + mpPBPlay = new PushButton( this, SdResId( PB_PLAY ) ); + mpPBSlideShow = new PushButton( this, SdResId( PB_SLIDE_SHOW ) ); + mpFLSeperator2 = new FixedLine( this, SdResId( FL_SEPERATOR2 ) ); + mpCBAutoPreview = new CheckBox( this, SdResId( CB_AUTOPREVIEW ) ); + + maStrProperty = mpFTProperty->GetText(); + + FreeResource(); + + // use bold font for group headings (same font for all fixed lines): + Font font( mpFLEffect->GetFont() ); + font.SetWeight( WEIGHT_BOLD ); + mpFLEffect->SetFont( font ); + mpFLModify->SetFont( font ); + + fillDurationComboBox( mpCBSpeed ); + mpPBMoveUp->SetSymbol( SYMBOL_ARROW_UP ); + mpPBMoveDown->SetSymbol( SYMBOL_ARROW_DOWN ); + + mpPBAddEffect->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpPBChangeEffect->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpPBRemoveEffect->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpLBStart->SetSelectHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpCBSpeed->SetSelectHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpPBPropertyMore->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpPBMoveUp->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpPBMoveDown->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpPBPlay->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpPBSlideShow->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + mpCBAutoPreview->SetClickHdl( LINK( this, CustomAnimationPane, implControlHdl ) ); + + maStrModify = mpFLEffect->GetText(); + + // resize controls according to current size + updateLayout(); + + // get current controller and initialize listeners + try + { + mxView = Reference< XDrawView >::query(mrBase.GetController()); + addListener(); + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR( "sd::CustomAnimationPane::CustomAnimationPane(), Exception cought!" ); + } + + // get current page and update custom animation list + onChangeCurrentPage(); + + // Wait a short time before the presets list is created. This gives the + // system time to paint the control. + maLateInitTimer.SetTimeout(100); + maLateInitTimer.SetTimeoutHdl(LINK(this, CustomAnimationPane, lateInitCallback)); + maLateInitTimer.Start(); +} + +CustomAnimationPane::~CustomAnimationPane() +{ + maLateInitTimer.Stop(); + + removeListener(); + + MotionPathTagVector aTags; + aTags.swap( maMotionPathTags ); + MotionPathTagVector::iterator aIter; + for( aIter = aTags.begin(); aIter != aTags.end(); aIter++ ) + (*aIter)->Dispose(); + + delete mpFLModify; + delete mpPBAddEffect; + delete mpPBChangeEffect; + delete mpPBRemoveEffect; + delete mpFLEffect; + delete mpFTStart; + delete mpLBStart; + delete mpFTProperty; + delete mpLBProperty; + delete mpPBPropertyMore; + delete mpFTSpeed; + delete mpCBSpeed; + delete mpCustomAnimationList; + delete mpFTChangeOrder; + delete mpPBMoveUp; + delete mpPBMoveDown; + delete mpFLSeperator1; + delete mpPBPlay; + delete mpPBSlideShow; + delete mpFLSeperator2; + delete mpCBAutoPreview; +} + +void CustomAnimationPane::addUndo() +{ + ::svl::IUndoManager* pManager = mrBase.GetDocShell()->GetUndoManager(); + if( pManager ) + { + SdPage* pPage = SdPage::getImplementation( mxCurrentPage ); + if( pPage ) + pManager->AddUndoAction( new UndoAnimation( mrBase.GetDocShell()->GetDoc(), pPage ) ); + } +} + +void CustomAnimationPane::Resize() +{ + updateLayout(); +} + +void CustomAnimationPane::StateChanged( StateChangedType nStateChange ) +{ + Control::StateChanged( nStateChange ); + + if( nStateChange == STATE_CHANGE_VISIBLE ) + updateMotionPathTags(); +} + +void CustomAnimationPane::KeyInput( const KeyEvent& rKEvt ) +{ + if( mpCustomAnimationList ) + mpCustomAnimationList->KeyInput( rKEvt ); +} + +void CustomAnimationPane::addListener() +{ + Link aLink( LINK(this,CustomAnimationPane,EventMultiplexerListener) ); + mrBase.GetEventMultiplexer()->AddEventListener ( + aLink, + tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION + | tools::EventMultiplexerEvent::EID_CURRENT_PAGE + | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED + | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED + | tools::EventMultiplexerEvent::EID_DISPOSING + | tools::EventMultiplexerEvent::EID_END_TEXT_EDIT); +} + +void CustomAnimationPane::removeListener() +{ + Link aLink( LINK(this,CustomAnimationPane,EventMultiplexerListener) ); + mrBase.GetEventMultiplexer()->RemoveEventListener( aLink ); +} + +IMPL_LINK(CustomAnimationPane,EventMultiplexerListener, + tools::EventMultiplexerEvent*,pEvent) +{ + switch (pEvent->meEventId) + { + case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION: + onSelectionChanged(); + break; + + case tools::EventMultiplexerEvent::EID_CURRENT_PAGE: + onChangeCurrentPage(); + break; + + case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED: + // At this moment the controller may not yet been set at model + // or ViewShellBase. Take it from the view shell passed with + // the event. + if (mrBase.GetMainViewShell() != NULL) + { + if( mrBase.GetMainViewShell()->GetShellType() == ViewShell::ST_IMPRESS ) + { + mxView = Reference<XDrawView>::query(mrBase.GetDrawController()); + onSelectionChanged(); + onChangeCurrentPage(); + break; + } + } + // fall through intended + case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED: + mxView = 0; + mxCurrentPage = 0; + updateControls(); + break; + + case tools::EventMultiplexerEvent::EID_DISPOSING: + mxView = Reference<XDrawView>(); + onSelectionChanged(); + onChangeCurrentPage(); + break; + case tools::EventMultiplexerEvent::EID_END_TEXT_EDIT: + if( mpMainSequence.get() && pEvent->mpUserData ) + mpCustomAnimationList->update( mpMainSequence ); + break; + } + return 0; +} + + +void CustomAnimationPane::updateLayout() +{ + Size aPaneSize( GetSizePixel() ); + if( aPaneSize.Width() < maMinSize.Width() ) + aPaneSize.Width() = maMinSize.Width(); + + if( aPaneSize.Height() < maMinSize.Height() ) + aPaneSize.Height() = maMinSize.Height(); + + Point aOffset( LogicToPixel( Point(3,3), MAP_APPFONT ) ); + Point aCursor( aOffset ); + + // place the modify fixed line + + // place the "modify effect" fixed line + Size aSize( mpFLModify->GetSizePixel() ); + aSize.Width() = aPaneSize.Width() - 2 * aOffset.X(); + + mpFLModify->SetPosSizePixel( aCursor, aSize ); + + aCursor.Y() += aSize.Height() + aOffset.Y(); + + const int nButtonExtraWidth = 4 * aOffset.X(); + + // the "add effect" button is placed top-left + Size aCtrlSize( mpPBAddEffect->GetSizePixel() ); + aCtrlSize.setWidth( mpPBAddEffect->CalcMinimumSize( aSize.Width() ).getWidth() + nButtonExtraWidth ); + mpPBAddEffect->SetPosSizePixel( aCursor, aCtrlSize ); + + aCursor.X() += aOffset.X() + aCtrlSize.Width(); + + // place the "change effect" button + + // if the "change" button does not fit right of the "add effect", put it on the next line + aCtrlSize = mpPBChangeEffect->GetSizePixel(); + aCtrlSize.setWidth( mpPBChangeEffect->CalcMinimumSize( aSize.Width() ).getWidth() + nButtonExtraWidth ); + if( ( aCursor.X() + aCtrlSize.Width() + aOffset.X() ) > aPaneSize.Width() ) + { + aCursor.X() = aOffset.X(); + aCursor.Y() += aCtrlSize.Height() + aOffset.Y(); + } + mpPBChangeEffect->SetPosSizePixel( aCursor, aCtrlSize ); + + aCursor.X() += aOffset.X() + aCtrlSize.Width(); + + // place the "remove effect" button + + // if the "remove" button does not fit right of the "add effect", put it on the next line + aCtrlSize = mpPBRemoveEffect->GetSizePixel(); + aCtrlSize.setWidth( mpPBRemoveEffect->CalcMinimumSize( aSize.Width() ).getWidth() + nButtonExtraWidth ); + if( ( aCursor.X() + aCtrlSize.Width() + aOffset.X() ) > aPaneSize.Width() ) + { + aCursor.X() = aOffset.X(); + aCursor.Y() += aCtrlSize.Height() + aOffset.Y(); + } + + mpPBRemoveEffect->SetPosSizePixel( aCursor, aCtrlSize ); + + aCursor.X() = aOffset.X(); + aCursor.Y() += aCtrlSize.Height() + 2 * aOffset.Y(); + + // place the "modify effect" fixed line + aSize = mpFLEffect->GetSizePixel(); + aSize.Width() = aPaneSize.Width() - 2 * aOffset.X(); + + mpFLEffect->SetPosSizePixel( aCursor, aSize ); + + aCursor.Y() += aSize.Height() + aOffset.Y(); + + // --------------------------------------------------------------------------- + // place the properties controls + + // calc minimum width for fixedtext + + Size aFixedTextSize( mpFTStart->CalcMinimumSize() ); + long nWidth = aFixedTextSize.Width(); + aFixedTextSize = mpFTProperty->CalcMinimumSize(); + nWidth = std::max( nWidth, aFixedTextSize.Width() ); + aFixedTextSize = mpFTSpeed->CalcMinimumSize(); + aFixedTextSize.Width() = std::max( nWidth, aFixedTextSize.Width() ) + aOffset.X(); + mpFTStart->SetSizePixel(aFixedTextSize); + mpFTProperty->SetSizePixel(aFixedTextSize); + mpFTSpeed->SetSizePixel(aFixedTextSize); + + aSize = mpPBPropertyMore->GetSizePixel(); + + // place the "start" fixed text + + Point aFTPos( aCursor ); + Point aLBPos( aCursor ); + Size aListBoxSize( LogicToPixel( Size( 60, 12 ), MAP_APPFONT ) ); + long nDeltaY = aListBoxSize.Height() + aOffset.Y(); + + // linebreak? + if( (aFixedTextSize.Width() + aListBoxSize.Width() + aSize.Width() + 4 * aOffset.X()) > aPaneSize.Width() ) + { + // y position for list box is below fixed text + aLBPos.Y() += aFixedTextSize.Height() + aOffset.Y(); + + // height of fixed text + list box + something = 2 * list box + nDeltaY = aListBoxSize.Height() + aFixedTextSize.Height() + 2*aOffset.Y(); + } + else + { + // x position for list box is right of fixed text + aLBPos.X() += aFixedTextSize.Width() + aOffset.X(); + + if( aListBoxSize.Height() > aFixedTextSize.Height() ) + aFTPos.Y() = aLBPos.Y() + ((aListBoxSize.Height() - aFixedTextSize.Height()) >> 1); + else + aLBPos.Y() = aFTPos.Y() + ((aFixedTextSize.Height() - aListBoxSize.Height()) >> 1); + } + + // width of the listbox is from its left side until end of pane + aListBoxSize.Width() = aPaneSize.Width() - aLBPos.X() - aSize.Width() - 2 * aOffset.X(); + + mpFTStart->SetPosPixel( aFTPos ); + mpLBStart->SetPosSizePixel( aLBPos, aListBoxSize ); + + aFTPos.Y() += nDeltaY; aLBPos.Y() += nDeltaY; + + mpFTProperty->SetPosPixel( aFTPos ); + mpLBProperty->SetPosSizePixel( aLBPos, aListBoxSize ); + mpLBProperty->Resize(); + + Point aMorePos( aLBPos ); + aMorePos.X() += aListBoxSize.Width() + aOffset.X(); + mpPBPropertyMore->SetPosPixel( aMorePos ); + + aFTPos.Y() += nDeltaY; aLBPos.Y() += nDeltaY; + + mpFTSpeed->SetPosPixel( aFTPos ); + mpCBSpeed->SetPosSizePixel( aLBPos, aListBoxSize ); + + aFTPos.Y() += nDeltaY + aOffset.Y(); + + Point aListPos( aFTPos ); + + // positionate the buttons on the bottom + + // place the auto preview checkbox + aCursor = Point( aOffset.X(), aPaneSize.Height() - mpCBAutoPreview->GetSizePixel().Height() - aOffset.Y() ); + mpCBAutoPreview->SetPosPixel( aCursor ); + + // place the seperator 2 fixed line + aCursor.Y() -= /* aOffset.Y() + */ mpFLSeperator2->GetSizePixel().Height(); + aSize = mpFLSeperator2->GetSizePixel(); + aSize.Width() = aPaneSize.Width() - 2 * aOffset.X(); + mpFLSeperator2->SetPosSizePixel( aCursor, aSize ); + + // next, layout and place the play and slide show buttons + aCtrlSize = mpPBSlideShow->GetSizePixel(); + aCtrlSize.setWidth( mpPBSlideShow->CalcMinimumSize( aSize.Width() ).getWidth() + nButtonExtraWidth ); + + Size aPlaySize( mpPBPlay->GetSizePixel() ); + aPlaySize.setWidth( mpPBPlay->CalcMinimumSize( aSize.Width() ).getWidth() + nButtonExtraWidth ); + + aCursor.Y() -= aCtrlSize.Height() /* + aOffset.Y() */; + + // do we need two lines for the buttons? + int aTestWidth = aCursor.X() + mpPBPlay->GetSizePixel().Width() + 2 * aOffset.X() + mpPBSlideShow->GetSizePixel().Width(); + if( aTestWidth > aPaneSize.Width() ) + { + mpPBSlideShow->SetPosSizePixel( aCursor, aCtrlSize ); + aCursor.Y() -= aCtrlSize.Height() + aOffset.Y(); + mpPBPlay->SetPosSizePixel( aCursor, aPlaySize ); + } + else + { + mpPBPlay->SetPosSizePixel( aCursor, aPlaySize ); + aCursor.X() += aPlaySize.Width() + aOffset.X(); + mpPBSlideShow->SetPosSizePixel( aCursor, aCtrlSize ); + } + + // place the seperator 1 fixed line + aCursor.X() = aOffset.X(); + aCursor.Y() -= /* aOffset.Y() + */ mpFLSeperator1->GetSizePixel().Height(); + aSize = mpFLSeperator1->GetSizePixel(); + aSize.Width() = aPaneSize.Width() - 2 * aOffset.X(); + mpFLSeperator1->SetPosSizePixel( aCursor, aSize ); + + // place the move down button + aSize = mpPBMoveDown->GetSizePixel(); + + aCursor.X() = aPaneSize.Width() - aOffset.X() - aSize.Width(); + aCursor.Y() -= aOffset.Y() + aSize.Height(); + mpPBMoveDown->SetPosPixel( aCursor ); + + aCursor.X() -= aOffset.X() + aSize.Width(); + mpPBMoveUp->SetPosPixel( aCursor ); + + // Place the change order label. + // Its width has to be calculated dynamically so that is can be + // displayed flush right without having too much space to the buttons + // with some languages or truncated text with others. + mpFTChangeOrder->SetSizePixel(mpFTChangeOrder->CalcMinimumSize()); + + aCursor.X() -= aOffset.X() + mpFTChangeOrder->GetSizePixel().Width(); + aCursor.Y() += (aSize.Height() - mpFTChangeOrder->GetSizePixel().Height()) >> 1; + mpFTChangeOrder->SetPosPixel( aCursor ); + + // positionate the custom animation list control + Size aCustomAnimationListSize( aPaneSize.Width() - aListPos.X() - aOffset.X(), aCursor.Y() - aListPos.Y() - 2 * aOffset.Y() ); + mpCustomAnimationList->SetPosSizePixel( aListPos, aCustomAnimationListSize ); +} + +static sal_Int32 getPropertyType( const OUString& rProperty ) +{ + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Direction") ) ) + return nPropertyTypeDirection; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Spokes") ) ) + return nPropertyTypeSpokes; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Zoom") ) ) + return nPropertyTypeZoom; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Accelerate") ) ) + return nPropertyTypeAccelerate; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Decelerate") ) ) + return nPropertyTypeDecelerate; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Color1") ) ) + return nPropertyTypeFirstColor; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Color2") ) ) + return nPropertyTypeSecondColor; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FillColor") ) ) + return nPropertyTypeFillColor; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ColorStyle") ) ) + return nPropertyTypeColorStyle; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AutoReverse") ) ) + return nPropertyTypeAutoReverse; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FontStyle") ) ) + return nPropertyTypeFont; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CharColor") ) ) + return nPropertyTypeCharColor; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CharHeight") ) ) + return nPropertyTypeCharHeight; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CharDecoration") ) ) + return nPropertyTypeCharDecoration; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("LineColor") ) ) + return nPropertyTypeLineColor; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Rotate") ) ) + return nPropertyTypeRotate; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Transparency") ) ) + return nPropertyTypeTransparency; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Color") ) ) + return nPropertyTypeColor; + + if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Scale") ) ) + return nPropertyTypeScale; + + return nPropertyTypeNone; +} + +OUString getPropertyName( sal_Int32 nPropertyType ) +{ + switch( nPropertyType ) + { + case nPropertyTypeDirection: + return OUString( String( SdResId( STR_CUSTOMANIMATION_DIRECTION_PROPERTY ) ) ); + + case nPropertyTypeSpokes: + return OUString( String( SdResId( STR_CUSTOMANIMATION_SPOKES_PROPERTY ) ) ); + + case nPropertyTypeFirstColor: + return OUString( String( SdResId( STR_CUSTOMANIMATION_FIRST_COLOR_PROPERTY ) ) ); + + case nPropertyTypeSecondColor: + return OUString( String( SdResId( STR_CUSTOMANIMATION_SECOND_COLOR_PROPERTY ) ) ); + + case nPropertyTypeZoom: + return OUString( String( SdResId( STR_CUSTOMANIMATION_ZOOM_PROPERTY ) ) ); + + case nPropertyTypeFillColor: + return OUString( String( SdResId( STR_CUSTOMANIMATION_FILL_COLOR_PROPERTY ) ) ); + + case nPropertyTypeColorStyle: + return OUString( String( SdResId( STR_CUSTOMANIMATION_STYLE_PROPERTY ) ) ); + + case nPropertyTypeFont: + return OUString( String( SdResId( STR_CUSTOMANIMATION_FONT_PROPERTY ) ) ); + + case nPropertyTypeCharHeight: + return OUString( String( SdResId( STR_CUSTOMANIMATION_SIZE_PROPERTY ) ) ); + + case nPropertyTypeCharColor: + return OUString( String( SdResId( STR_CUSTOMANIMATION_FONT_COLOR_PROPERTY ) ) ); + + case nPropertyTypeCharHeightStyle: + return OUString( String( SdResId( STR_CUSTOMANIMATION_FONT_SIZE_STYLE_PROPERTY ) ) ); + + case nPropertyTypeCharDecoration: + return OUString( String( SdResId( STR_CUSTOMANIMATION_FONT_STYLE_PROPERTY ) ) ); + + case nPropertyTypeLineColor: + return OUString( String( SdResId( STR_CUSTOMANIMATION_LINE_COLOR_PROPERTY ) ) ); + + case nPropertyTypeRotate: + return OUString( String( SdResId( STR_CUSTOMANIMATION_AMOUNT_PROPERTY ) ) ); + + case nPropertyTypeColor: + return OUString( String( SdResId( STR_CUSTOMANIMATION_COLOR_PROPERTY ) ) ); + + case nPropertyTypeTransparency: + return OUString( String( SdResId( STR_CUSTOMANIMATION_AMOUNT_PROPERTY ) ) ); + + case nPropertyTypeScale: + return OUString( String( SdResId( STR_CUSTOMANIMATION_SCALE_PROPERTY ) ) ); + } + + OUString aStr; + return aStr; +} + +void CustomAnimationPane::updateControls() +{ + mpFLModify->Enable( mxView.is() ); + mpFTSpeed->Enable( mxView.is() ); + mpCBSpeed->Enable( mxView.is() ); + mpCustomAnimationList->Enable( mxView.is() ); + mpFTChangeOrder->Enable( mxView.is() ); + mpPBMoveUp->Enable( mxView.is() ); + mpPBMoveDown->Enable( mxView.is() ); + mpFLSeperator1->Enable( mxView.is() ); + mpPBPlay->Enable( mxView.is() ); + mpPBSlideShow->Enable( mxView.is() ); + mpFLSeperator2->Enable( mxView.is() ); + mpCBAutoPreview->Enable( mxView.is() ); + + if( !mxView.is() ) + { + mpPBAddEffect->Enable( sal_False ); + mpPBChangeEffect->Enable( sal_False ); + mpPBRemoveEffect->Enable( sal_False ); + mpFLEffect->Enable( sal_False ); + mpFTStart->Enable( sal_False ); + mpLBStart->Enable( sal_False ); + mpPBPropertyMore->Enable( sal_False ); + mpLBProperty->Enable( sal_False ); + mpFTProperty->Enable( sal_False ); + mpCustomAnimationList->clear(); + return; + } + + const int nSelectionCount = maListSelection.size(); + + mpPBAddEffect->Enable( maViewSelection.hasValue() ); + mpPBChangeEffect->Enable( nSelectionCount); + mpPBRemoveEffect->Enable(nSelectionCount); + + mpFLEffect->Enable(nSelectionCount > 0); + mpFTStart->Enable(nSelectionCount > 0); + mpLBStart->Enable(nSelectionCount > 0); + mpPBPropertyMore->Enable(nSelectionCount > 0); + +// mpPBPlay->Enable(nSelectionCount > 0); + + mpFTProperty->SetText( maStrProperty ); + + mnPropertyType = nPropertyTypeNone; + + if( nSelectionCount == 1 ) + { + CustomAnimationEffectPtr pEffect = maListSelection.front(); + + OUString aUIName( getPresets().getUINameForPresetId( pEffect->getPresetId() ) ); + + OUString aTemp( maStrModify ); + + if( aUIName.getLength() ) + { + aTemp += OUString( (sal_Unicode)' ' ); + aTemp += aUIName; + } + mpFLEffect->SetText( aTemp ); + + CustomAnimationPresetPtr pDescriptor = getPresets().getEffectDescriptor( pEffect->getPresetId() ); + if( pDescriptor.get() ) + { + PropertySubControl* pSubControl = NULL; + + Any aValue; + + UStringList aProperties( pDescriptor->getProperties() ); + if( aProperties.size() >= 1 ) + { + OUString aProperty( aProperties.front() ); + + mnPropertyType = getPropertyType( aProperties.front() ); + + mpFTProperty->SetText( getPropertyName( mnPropertyType ) ); + + aValue = getProperty1Value( mnPropertyType, pEffect ); + } + + if( aValue.hasValue() ) + { + pSubControl = mpLBProperty->getSubControl(); + if( !pSubControl || (pSubControl->getControlType() != mnPropertyType) ) + { + pSubControl = PropertySubControl::create( mnPropertyType, this, aValue, pEffect->getPresetId(), LINK( this, CustomAnimationPane, implPropertyHdl ) ); + mpLBProperty->setSubControl( pSubControl ); + } + else + { + pSubControl->setValue( aValue, pEffect->getPresetId() ); + } + } + else + { + mpLBProperty->setSubControl( 0 ); + } + + bool bEnable = (pSubControl != 0) && (pSubControl->getControl()->IsEnabled()); + mpLBProperty->Enable( bEnable ); + mpFTProperty->Enable( bEnable ); + } + else + { + mpLBProperty->setSubControl( 0 ); + mpFTProperty->Enable( sal_False ); + mpLBProperty->Enable( sal_False ); + mpPBPropertyMore->Enable( sal_False ); + } + + // + // --- + // + sal_uInt16 nPos = 0xffff; + + sal_Int16 nNodeType = pEffect->getNodeType(); + switch( nNodeType ) + { + case EffectNodeType::ON_CLICK: nPos = 0; break; + case EffectNodeType::WITH_PREVIOUS: nPos = 1; break; + case EffectNodeType::AFTER_PREVIOUS: nPos = 2; break; + } + + mpLBStart->SelectEntryPos( nPos ); + + double fDuration = pEffect->getDuration(); + const bool bHasSpeed = fDuration > 0.001; + + mpFTSpeed->Enable(bHasSpeed); + mpCBSpeed->Enable(bHasSpeed); + + if( bHasSpeed ) + { + 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; + else + nPos = 0xffff; + + mpCBSpeed->SelectEntryPos( nPos ); + } + + mpPBPropertyMore->Enable( sal_True ); + + mpFTChangeOrder->Enable( sal_True ); + } + else + { + mpLBProperty->setSubControl( 0 ); + mpFTProperty->Enable( sal_False ); + mpLBProperty->Enable( sal_False ); + mpPBPropertyMore->Enable( sal_False ); + mpFTSpeed->Enable(sal_False); + mpCBSpeed->Enable(sal_False); + mpFTChangeOrder->Enable( sal_False ); + mpLBStart->SetNoSelection(); + mpCBSpeed->SetNoSelection(); + mpFLEffect->SetText( maStrModify ); + } + + bool bEnableUp = true; + bool bEnableDown = true; + if( nSelectionCount == 0 ) + { + bEnableUp = false; + bEnableDown = false; + } + else + { + if( mpMainSequence->find( maListSelection.front() ) == mpMainSequence->getBegin() ) + bEnableUp = false; + + EffectSequence::iterator aIter( mpMainSequence->find( maListSelection.back() ) ); + if( aIter == mpMainSequence->getEnd() ) + { + bEnableDown = false; + } + else + { + do + { + aIter++; + } + while( (aIter != mpMainSequence->getEnd()) && !(mpCustomAnimationList->isExpanded((*aIter)) ) ); + + if( aIter == mpMainSequence->getEnd() ) + bEnableDown = false; + } + + if( bEnableUp || bEnableDown ) + { + MainSequenceRebuildGuard aGuard( mpMainSequence ); + + EffectSequenceHelper* pSequence = 0; + EffectSequence::iterator aRebuildIter( maListSelection.begin() ); + const EffectSequence::iterator aRebuildEnd( maListSelection.end() ); + while( aRebuildIter != aRebuildEnd ) + { + CustomAnimationEffectPtr pEffect = (*aRebuildIter++); + + if( pEffect.get() ) + { + if( pSequence == 0 ) + { + pSequence = pEffect->getEffectSequence(); + } + else + { + if( pSequence != pEffect->getEffectSequence() ) + { + bEnableUp = false; + bEnableDown = false; + break; + } + } + } + } + } + } + + mpPBMoveUp->Enable(bEnableUp); + mpPBMoveDown->Enable(bEnableDown); + + SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS); + mpCBAutoPreview->Check( pOptions->IsPreviewChangedEffects() == sal_True ); + + updateMotionPathTags(); +} + +static bool updateMotionPathImpl( CustomAnimationPane& rPane, ::sd::View& rView, EffectSequence::iterator aIter, EffectSequence::iterator aEnd, MotionPathTagVector& rOldTags, MotionPathTagVector& rNewTags ) +{ + bool bChanges = false; + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect( (*aIter++) ); + if( pEffect.get() && pEffect->getPresetClass() == ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH ) + { + rtl::Reference< MotionPathTag > xMotionPathTag; + // first try to find if there is already a tag for this + MotionPathTagVector::iterator aMIter( rOldTags.begin() ); + for( ; aMIter != rOldTags.end(); aMIter++ ) + { + rtl::Reference< MotionPathTag > xTag( (*aMIter) ); + if( xTag->getEffect() == pEffect ) + { + if( !xTag->isDisposed() ) + { + xMotionPathTag = xTag; + rOldTags.erase( aMIter ); + } + break; + } + } + + // if not found, create new one + if( !xMotionPathTag.is() ) + { + xMotionPathTag.set( new MotionPathTag( rPane, rView, pEffect ) ); + bChanges = true; + } + + if( xMotionPathTag.is() ) + rNewTags.push_back( xMotionPathTag ); + } + } + + return bChanges; +} + +void CustomAnimationPane::updateMotionPathTags() +{ + bool bChanges = false; + + MotionPathTagVector aTags; + aTags.swap( maMotionPathTags ); + + ::sd::View* pView = 0; + + if( mxView.is() ) + { + ::boost::shared_ptr<ViewShell> xViewShell( mrBase.GetMainViewShell() ); + if( xViewShell.get() ) + pView = xViewShell->GetView(); + } + + if( IsVisible() && mpMainSequence.get() && pView ) + { + bChanges = updateMotionPathImpl( *this, *pView, mpMainSequence->getBegin(), mpMainSequence->getEnd(), aTags, maMotionPathTags ); + + const InteractiveSequenceList& rISL = mpMainSequence->getInteractiveSequenceList(); + InteractiveSequenceList::const_iterator aISI( rISL.begin() ); + while( aISI != rISL.end() ) + { + InteractiveSequencePtr pIS( (*aISI++) ); + bChanges |= updateMotionPathImpl( *this, *pView, pIS->getBegin(), pIS->getEnd(), aTags, maMotionPathTags ); + } + } + + if( !aTags.empty() ) + { + bChanges = true; + MotionPathTagVector::iterator aIter( aTags.begin() ); + while( aIter != aTags.end() ) + { + rtl::Reference< MotionPathTag > xTag( (*aIter++) ); + xTag->Dispose(); + } + } + + if( bChanges && pView ) + pView->updateHandles(); +} + +void CustomAnimationPane::onSelectionChanged() +{ + if( !maSelectionLock.isLocked() ) + { + ScopeLockGuard aGuard( maSelectionLock ); + + if( mxView.is() ) try + { + Reference< XSelectionSupplier > xSel( mxView, UNO_QUERY_THROW ); + if (xSel.is()) + { + maViewSelection = xSel->getSelection(); + mpCustomAnimationList->onSelectionChanged( maViewSelection ); + updateControls(); + } + } + catch( Exception& ) + { + DBG_ERROR( "sd::CustomAnimationPane::onSelectionChanged(), Exception catched!" ); + } + } +} + +void CustomAnimationPane::onDoubleClick() +{ + showOptions(); +} + +void CustomAnimationPane::onContextMenu( sal_uInt16 nSelectedPopupEntry ) +{ + switch( nSelectedPopupEntry ) + { + case CM_WITH_CLICK: onChangeStart( EffectNodeType::ON_CLICK ); break; + case CM_WITH_PREVIOUS: onChangeStart( EffectNodeType::WITH_PREVIOUS ); break; + case CM_AFTER_PREVIOUS: onChangeStart( EffectNodeType::AFTER_PREVIOUS ); break; + case CM_OPTIONS: showOptions(); break; + case CM_DURATION: showOptions(RID_TP_CUSTOMANIMATION_DURATION); break; + case CM_REMOVE: onRemove(); break; + case CM_CREATE: if( maViewSelection.hasValue() ) onChange( true ); break; + } + + updateControls(); +} + +void addValue( STLPropertySet* pSet, sal_Int32 nHandle, const Any& rValue ) +{ + switch( pSet->getPropertyState( nHandle ) ) + { + case STLPropertyState_AMBIGUOUS: + // value is already ambiguous, do nothing + break; + case STLPropertyState_DIRECT: + // set to ambiguous if existing value is different + if( rValue != pSet->getPropertyValue( nHandle ) ) + pSet->setPropertyState( nHandle, STLPropertyState_AMBIGUOUS ); + break; + case STLPropertyState_DEFAULT: + // just set new value + pSet->setPropertyValue( nHandle, rValue ); + break; + } +} + +static sal_Int32 calcMaxParaDepth( Reference< XShape > xTargetShape ) +{ + sal_Int32 nMaxParaDepth = -1; + + if( xTargetShape.is() ) + { + Reference< XEnumerationAccess > xText( xTargetShape, UNO_QUERY ); + if( xText.is() ) + { + Reference< XPropertySet > xParaSet; + const OUString strNumberingLevel( RTL_CONSTASCII_USTRINGPARAM("NumberingLevel") ); + + Reference< XEnumeration > xEnumeration( xText->createEnumeration(), UNO_QUERY_THROW ); + while( xEnumeration->hasMoreElements() ) + { + xEnumeration->nextElement() >>= xParaSet; + if( xParaSet.is() ) + { + sal_Int32 nParaDepth = 0; + xParaSet->getPropertyValue( strNumberingLevel ) >>= nParaDepth; + + if( nParaDepth > nMaxParaDepth ) + nMaxParaDepth = nParaDepth; + } + } + } + } + + return nMaxParaDepth + 1; +} + +Any CustomAnimationPane::getProperty1Value( sal_Int32 nType, CustomAnimationEffectPtr pEffect ) +{ + switch( nType ) + { + case nPropertyTypeDirection: + case nPropertyTypeSpokes: + case nPropertyTypeZoom: + return makeAny( pEffect->getPresetSubType() ); + + case nPropertyTypeColor: + case nPropertyTypeFillColor: + case nPropertyTypeFirstColor: + case nPropertyTypeSecondColor: + case nPropertyTypeCharColor: + case nPropertyTypeLineColor: + { + const sal_Int32 nIndex = (nPropertyTypeFirstColor == nType) ? 0 : 1; + return pEffect->getColor( nIndex ); + } + + case nPropertyTypeFont: + return pEffect->getProperty( AnimationNodeType::SET, OUString( RTL_CONSTASCII_USTRINGPARAM("CharFontName") ), VALUE_TO ); + + case nPropertyTypeCharHeight: + { + const OUString aAttributeName( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) ); + Any aValue( pEffect->getProperty( AnimationNodeType::SET, aAttributeName, VALUE_TO ) ); + if( !aValue.hasValue() ) + aValue = pEffect->getProperty( AnimationNodeType::ANIMATE, aAttributeName, VALUE_TO ); + return aValue; + } + + case nPropertyTypeRotate: + return pEffect->getTransformationProperty( AnimationTransformType::ROTATE, VALUE_BY); + + case nPropertyTypeTransparency: + return pEffect->getProperty( AnimationNodeType::SET, OUString(RTL_CONSTASCII_USTRINGPARAM("Opacity")), VALUE_TO ); + + case nPropertyTypeScale: + return pEffect->getTransformationProperty( AnimationTransformType::SCALE, VALUE_BY ); + + case nPropertyTypeCharDecoration: + { + Sequence< Any > aValues(3); + aValues[0] = pEffect->getProperty( AnimationNodeType::SET, OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeight")), VALUE_TO ); + aValues[1] = pEffect->getProperty( AnimationNodeType::SET, OUString(RTL_CONSTASCII_USTRINGPARAM("CharPosture")), VALUE_TO ); + aValues[2] = pEffect->getProperty( AnimationNodeType::SET, OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderline")), VALUE_TO ); + return makeAny( aValues ); + } + } + + Any aAny; + return aAny; +} + +bool CustomAnimationPane::setProperty1Value( sal_Int32 nType, CustomAnimationEffectPtr pEffect, const Any& rValue ) +{ + bool bEffectChanged = false; + switch( nType ) + { + case nPropertyTypeDirection: + case nPropertyTypeSpokes: + case nPropertyTypeZoom: + { + OUString aPresetSubType; + rValue >>= aPresetSubType; + if( aPresetSubType != pEffect->getPresetSubType() ) + { + getPresets().changePresetSubType( pEffect, aPresetSubType ); + bEffectChanged = true; + } + } + break; + + case nPropertyTypeFillColor: + case nPropertyTypeColor: + case nPropertyTypeFirstColor: + case nPropertyTypeSecondColor: + case nPropertyTypeCharColor: + case nPropertyTypeLineColor: + { + const sal_Int32 nIndex = (nPropertyTypeFirstColor == nType) ? 0 : 1; + Any aOldColor( pEffect->getColor( nIndex ) ); + if( aOldColor != rValue ) + { + pEffect->setColor( nIndex, rValue ); + bEffectChanged = true; + } + } + break; + + case nPropertyTypeFont: + bEffectChanged = pEffect->setProperty( AnimationNodeType::SET, OUString( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) ), VALUE_TO, rValue ); + break; + + case nPropertyTypeCharHeight: + { + const OUString aAttributeName( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) ); + bEffectChanged = pEffect->setProperty( AnimationNodeType::SET, aAttributeName, VALUE_TO, rValue ); + if( !bEffectChanged ) + bEffectChanged = pEffect->setProperty( AnimationNodeType::ANIMATE, aAttributeName, VALUE_TO, rValue ); + } + break; + case nPropertyTypeRotate: + bEffectChanged = pEffect->setTransformationProperty( AnimationTransformType::ROTATE, VALUE_BY , rValue ); + break; + + case nPropertyTypeTransparency: + bEffectChanged = pEffect->setProperty( AnimationNodeType::SET, OUString( RTL_CONSTASCII_USTRINGPARAM("Opacity") ), VALUE_TO, rValue ); + break; + + case nPropertyTypeScale: + bEffectChanged = pEffect->setTransformationProperty( AnimationTransformType::SCALE, VALUE_BY, rValue ); + break; + + case nPropertyTypeCharDecoration: + { + Sequence< Any > aValues(3); + rValue >>= aValues; + bEffectChanged = pEffect->setProperty( AnimationNodeType::SET, OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeight")), VALUE_TO, aValues[0] ); + bEffectChanged |= pEffect->setProperty( AnimationNodeType::SET, OUString(RTL_CONSTASCII_USTRINGPARAM("CharPosture")), VALUE_TO, aValues[1] ); + bEffectChanged |= pEffect->setProperty( AnimationNodeType::SET, OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderline")), VALUE_TO, aValues[2] ); + } + break; + + } + + return bEffectChanged; +} + +static sal_Bool hasVisibleShape( const Reference< XShape >& xShape ) +{ + try + { + const OUString sShapeType( xShape->getShapeType() ); + + if( sShapeType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.TitleTextShape") ) || + sShapeType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.OutlinerShape") ) || + sShapeType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.SubtitleShape") ) || + sShapeType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.TextShape") ) ) + { + const OUString sFillStyle( RTL_CONSTASCII_USTRINGPARAM("FillStyle" ) ); + const OUString sLineStyle( RTL_CONSTASCII_USTRINGPARAM("LineStyle" ) ); + Reference< XPropertySet > xSet( xShape, UNO_QUERY_THROW ); + + FillStyle eFillStyle; + xSet->getPropertyValue( sFillStyle ) >>= eFillStyle; + + ::com::sun::star::drawing::LineStyle eLineStyle; + xSet->getPropertyValue( sLineStyle ) >>= eLineStyle; + + return eFillStyle != FillStyle_NONE || eLineStyle != ::com::sun::star::drawing::LineStyle_NONE; + } + } + catch( Exception& e ) + { + (void)e; + } + return sal_True; +} + +STLPropertySet* CustomAnimationPane::createSelectionSet() +{ + STLPropertySet* pSet = CustomAnimationDialog::createDefaultSet(); + + pSet->setPropertyValue( nHandleCurrentPage, makeAny( mxCurrentPage ) ); + + sal_Int32 nMaxParaDepth = 0; + + // get options from selected effects + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + const CustomAnimationPresets& rPresets (getPresets()); + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + + EffectSequenceHelper* pEffectSequence = pEffect->getEffectSequence(); + if( !pEffectSequence ) + pEffectSequence = mpMainSequence.get(); + + if( pEffect->hasText() ) + { + sal_Int32 n = calcMaxParaDepth(pEffect->getTargetShape()); + if( n > nMaxParaDepth ) + nMaxParaDepth = n; + } + + addValue( pSet, nHandleHasAfterEffect, makeAny( pEffect->hasAfterEffect() ) ); + addValue( pSet, nHandleAfterEffectOnNextEffect, makeAny( pEffect->IsAfterEffectOnNext() ? sal_True : sal_False ) ); + addValue( pSet, nHandleDimColor, pEffect->getDimColor() ); + addValue( pSet, nHandleIterateType, makeAny( pEffect->getIterateType() ) ); + + // convert absolute time to percentage value + // This calculation is done in float to avoid some rounding artifacts. + float fIterateInterval = (float)pEffect->getIterateInterval(); + if( pEffect->getDuration() ) + fIterateInterval = (float)(fIterateInterval / pEffect->getDuration() ); + fIterateInterval *= 100.0; + addValue( pSet, nHandleIterateInterval, makeAny( (double)fIterateInterval ) ); + + addValue( pSet, nHandleBegin, makeAny( pEffect->getBegin() ) ); + addValue( pSet, nHandleDuration, makeAny( pEffect->getDuration() ) ); + addValue( pSet, nHandleStart, makeAny( pEffect->getNodeType() ) ); + addValue( pSet, nHandleRepeat, makeAny( pEffect->getRepeatCount() ) ); + addValue( pSet, nHandleEnd, pEffect->getEnd() ); + addValue( pSet, nHandleRewind, makeAny( pEffect->getFill() ) ); + + addValue( pSet, nHandlePresetId, makeAny( pEffect->getPresetId() ) ); + + addValue( pSet, nHandleHasText, makeAny( (sal_Bool)pEffect->hasText() ) ); + + addValue( pSet, nHandleHasVisibleShape, Any( hasVisibleShape( pEffect->getTargetShape() ) ) ); + + Any aSoundSource; + if( pEffect->getAudio().is() ) + { + aSoundSource = pEffect->getAudio()->getSource(); + addValue( pSet, nHandleSoundVolumne, makeAny( pEffect->getAudio()->getVolume() ) ); +// todo addValue( pSet, nHandleSoundEndAfterSlide, makeAny( pEffect->getAudio()->getEndAfterSlide() ) ); +// this is now stored at the XCommand parameter sequence + } + else if( pEffect->getCommand() == EffectCommands::STOPAUDIO ) + { + aSoundSource = makeAny( (sal_Bool)sal_True ); + } + addValue( pSet, nHandleSoundURL, aSoundSource ); + + sal_Int32 nGroupId = pEffect->getGroupId(); + CustomAnimationTextGroupPtr pTextGroup; + if( nGroupId != -1 ) + pTextGroup = pEffectSequence->findGroup( nGroupId ); + + addValue( pSet, nHandleTextGrouping, makeAny( pTextGroup.get() ? pTextGroup->getTextGrouping() : (sal_Int32)-1 ) ); + addValue( pSet, nHandleAnimateForm, makeAny( pTextGroup.get() ? (sal_Bool)pTextGroup->getAnimateForm() : sal_True ) ); + addValue( pSet, nHandleTextGroupingAuto, makeAny( pTextGroup.get() ? pTextGroup->getTextGroupingAuto() : (double)-1.0 ) ); + addValue( pSet, nHandleTextReverse, makeAny( pTextGroup.get() ? (sal_Bool)pTextGroup->getTextReverse() : sal_False ) ); + + if( pEffectSequence->getSequenceType() == EffectNodeType::INTERACTIVE_SEQUENCE ) + { + InteractiveSequence* pIS = static_cast< InteractiveSequence* >( pEffectSequence ); + addValue( pSet, nHandleTrigger, makeAny( pIS->getTriggerShape() ) ); + } + + // + + CustomAnimationPresetPtr pDescriptor = rPresets.getEffectDescriptor( pEffect->getPresetId() ); + if( pDescriptor.get() ) + { + sal_Int32 nType = nPropertyTypeNone; + + UStringList aProperties( pDescriptor->getProperties() ); + if( aProperties.size() >= 1 ) + nType = getPropertyType( aProperties.front() ); + + if( nType != nPropertyTypeNone ) + { + addValue( pSet, nHandleProperty1Type, makeAny( nType ) ); + addValue( pSet, nHandleProperty1Value, getProperty1Value( nType, pEffect ) ); + } + + if( pDescriptor->hasProperty( OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerate" ) ) ) ) + { + addValue( pSet, nHandleAccelerate, makeAny( pEffect->getAcceleration() ) ); + } + + if( pDescriptor->hasProperty( OUString( RTL_CONSTASCII_USTRINGPARAM( "Decelerate" ) ) ) ) + { + addValue( pSet, nHandleDecelerate, makeAny( pEffect->getDecelerate() ) ); + } + + if( pDescriptor->hasProperty( OUString( RTL_CONSTASCII_USTRINGPARAM( "AutoReverse" ) ) ) ) + { + addValue( pSet, nHandleAutoReverse, makeAny( pEffect->getAutoReverse() ) ); + } + } + } + + addValue( pSet, nHandleMaxParaDepth, makeAny( nMaxParaDepth ) ); + + return pSet; +} + +void CustomAnimationPane::changeSelection( STLPropertySet* pResultSet, STLPropertySet* pOldSet ) +{ + // change selected effect + bool bChanged = false; + + MainSequenceRebuildGuard aGuard( mpMainSequence ); + + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + + DBG_ASSERT( pEffect->getEffectSequence(), "sd::CustomAnimationPane::changeSelection(), dead effect in selection!" ); + if( !pEffect->getEffectSequence() ) + continue; + + double fDuration = 0.0; // we might need this for iterate-interval + if( pResultSet->getPropertyState( nHandleDuration ) == STLPropertyState_DIRECT ) + { + pResultSet->getPropertyValue( nHandleDuration ) >>= fDuration; + } + else + { + fDuration = pEffect->getDuration(); + } + + if( pResultSet->getPropertyState( nHandleIterateType ) == STLPropertyState_DIRECT ) + { + sal_Int16 nIterateType = 0; + pResultSet->getPropertyValue( nHandleIterateType ) >>= nIterateType; + if( pEffect->getIterateType() != nIterateType ) + { + pEffect->setIterateType( nIterateType ); + bChanged = true; + } + } + + if( pEffect->getIterateType() ) + { + if( pResultSet->getPropertyState( nHandleIterateInterval ) == STLPropertyState_DIRECT ) + { + double fIterateInterval = 0.0; + pResultSet->getPropertyValue( nHandleIterateInterval ) >>= fIterateInterval; + if( pEffect->getIterateInterval() != fIterateInterval ) + { + const double f = fIterateInterval * pEffect->getDuration() / 100; + pEffect->setIterateInterval( f ); + bChanged = true; + } + } + } + + if( pResultSet->getPropertyState( nHandleBegin ) == STLPropertyState_DIRECT ) + { + double fBegin = 0.0; + pResultSet->getPropertyValue( nHandleBegin ) >>= fBegin; + if( pEffect->getBegin() != fBegin ) + { + pEffect->setBegin( fBegin ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleDuration ) == STLPropertyState_DIRECT ) + { + if( pEffect->getDuration() != fDuration ) + { + pEffect->setDuration( fDuration ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleStart ) == STLPropertyState_DIRECT ) + { + sal_Int16 nNodeType = 0; + pResultSet->getPropertyValue( nHandleStart ) >>= nNodeType; + if( pEffect->getNodeType() != nNodeType ) + { + pEffect->setNodeType( nNodeType ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleRepeat ) == STLPropertyState_DIRECT ) + { + Any aRepeatCount( pResultSet->getPropertyValue( nHandleRepeat ) ); + if( aRepeatCount != pEffect->getRepeatCount() ) + { + pEffect->setRepeatCount( aRepeatCount ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleEnd ) == STLPropertyState_DIRECT ) + { + Any aEndValue( pResultSet->getPropertyValue( nHandleEnd ) ); + if( pEffect->getEnd() != aEndValue ) + { + pEffect->setEnd( aEndValue ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleRewind ) == STLPropertyState_DIRECT ) + { + sal_Int16 nFill = 0; + pResultSet->getPropertyValue( nHandleRewind ) >>= nFill; + if( pEffect->getFill() != nFill ) + { + pEffect->setFill( nFill ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleHasAfterEffect ) == STLPropertyState_DIRECT ) + { + sal_Bool bHasAfterEffect = sal_False; + if( pResultSet->getPropertyValue( nHandleHasAfterEffect ) >>= bHasAfterEffect ) + { + if( pEffect->hasAfterEffect() != bHasAfterEffect ) + { + pEffect->setHasAfterEffect( bHasAfterEffect ); + bChanged = true; + } + } + } + + if( pResultSet->getPropertyState( nHandleAfterEffectOnNextEffect ) == STLPropertyState_DIRECT ) + { + sal_Bool bAfterEffectOnNextEffect = sal_False; + if( (pResultSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bAfterEffectOnNextEffect) && ((pEffect->IsAfterEffectOnNext() ? sal_True : sal_False) != bAfterEffectOnNextEffect) ) + { + pEffect->setAfterEffectOnNext( bAfterEffectOnNextEffect ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleDimColor ) == STLPropertyState_DIRECT ) + { + Any aDimColor( pResultSet->getPropertyValue( nHandleDimColor ) ); + if( pEffect->getDimColor() != aDimColor ) + { + pEffect->setDimColor( aDimColor ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleAccelerate ) == STLPropertyState_DIRECT ) + { + double fAccelerate = 0.0; + pResultSet->getPropertyValue( nHandleAccelerate ) >>= fAccelerate; + if( pEffect->getAcceleration() != fAccelerate ) + { + pEffect->setAcceleration( fAccelerate ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleDecelerate ) == STLPropertyState_DIRECT ) + { + double fDecelerate = 0.0; + pResultSet->getPropertyValue( nHandleDecelerate ) >>= fDecelerate; + if( pEffect->getDecelerate() != fDecelerate ) + { + pEffect->setDecelerate( fDecelerate ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleAutoReverse ) == STLPropertyState_DIRECT ) + { + sal_Bool bAutoReverse = sal_False; + pResultSet->getPropertyValue( nHandleAutoReverse ) >>= bAutoReverse; + if( pEffect->getAutoReverse() != bAutoReverse ) + { + pEffect->setAutoReverse( bAutoReverse ); + bChanged = true; + } + } + + if( pResultSet->getPropertyState( nHandleProperty1Value ) == STLPropertyState_DIRECT ) + { + sal_Int32 nType = 0; + pOldSet->getPropertyValue( nHandleProperty1Type ) >>= nType; + + bChanged |= setProperty1Value( nType, pEffect, pResultSet->getPropertyValue( nHandleProperty1Value ) ); + } + + if( pResultSet->getPropertyState( nHandleSoundURL ) == STLPropertyState_DIRECT ) + { + const Any aSoundSource( pResultSet->getPropertyValue( nHandleSoundURL ) ); + + if( aSoundSource.getValueType() == ::getCppuType((const sal_Bool*)0) ) + { + pEffect->setStopAudio(); + bChanged = true; + } + else + { + OUString aSoundURL; + aSoundSource >>= aSoundURL; + + if( aSoundURL.getLength() ) + { + if( !pEffect->getAudio().is() ) + { + pEffect->createAudio( aSoundSource ); + bChanged = true; + } + else + { + if( pEffect->getAudio()->getSource() != aSoundSource ) + { + pEffect->getAudio()->setSource( aSoundSource ); + bChanged = true; + } + } + } + else + { + if( pEffect->getAudio().is() || pEffect->getStopAudio() ) + { + pEffect->removeAudio(); + bChanged = true; + } + } + } + } + + if( pResultSet->getPropertyState( nHandleTrigger ) == STLPropertyState_DIRECT ) + { + Reference< XShape > xTriggerShape; + pResultSet->getPropertyValue( nHandleTrigger ) >>= xTriggerShape; + bChanged |= mpMainSequence->setTrigger( pEffect, xTriggerShape ); + } + } + + const bool bHasTextGrouping = pResultSet->getPropertyState( nHandleTextGrouping ) == STLPropertyState_DIRECT; + const bool bHasAnimateForm = pResultSet->getPropertyState( nHandleAnimateForm ) == STLPropertyState_DIRECT; + const bool bHasTextGroupingAuto = pResultSet->getPropertyState( nHandleTextGroupingAuto ) == STLPropertyState_DIRECT; + const bool bHasTextReverse = pResultSet->getPropertyState( nHandleTextReverse ) == STLPropertyState_DIRECT; + + if( bHasTextGrouping || bHasAnimateForm || bHasTextGroupingAuto || bHasTextReverse ) + { + // we need to do a second pass for text grouping options + // since changing them can cause effects to be removed + // or replaced, we do this after we aplied all other options + // above + + sal_Int32 nTextGrouping = 0; + sal_Bool bAnimateForm = sal_True, bTextReverse = sal_False; + double fTextGroupingAuto = -1.0; + + if( bHasTextGrouping ) + pResultSet->getPropertyValue(nHandleTextGrouping) >>= nTextGrouping; + + if( bHasAnimateForm ) + pResultSet->getPropertyValue(nHandleAnimateForm) >>= bAnimateForm; + + if( bHasTextGroupingAuto ) + pResultSet->getPropertyValue(nHandleTextGroupingAuto) >>= fTextGroupingAuto; + + if( bHasTextReverse ) + pResultSet->getPropertyValue(nHandleTextReverse) >>= bTextReverse; + + EffectSequence const aSelectedEffects( maListSelection ); + EffectSequence::const_iterator iter( aSelectedEffects.begin() ); + const EffectSequence::const_iterator iEnd( aSelectedEffects.end() ); + while( iter != iEnd ) + { + CustomAnimationEffectPtr const& pEffect = (*iter++); + + EffectSequenceHelper* pEffectSequence = pEffect->getEffectSequence(); + if( !pEffectSequence ) + pEffectSequence = mpMainSequence.get(); + + sal_Int32 nGroupId = pEffect->getGroupId(); + CustomAnimationTextGroupPtr pTextGroup; + if( (nGroupId != -1) ) + { + // use existing group + pTextGroup = pEffectSequence->findGroup( nGroupId ); + } + else + { + // somethings changed so we need a group now + pTextGroup = pEffectSequence->createTextGroup( pEffect, nTextGrouping, fTextGroupingAuto, bAnimateForm, bTextReverse ); + bChanged = true; + } + + if( bHasTextGrouping ) + { + if( (pTextGroup->getTextGrouping() != nTextGrouping) ) + { + pEffectSequence->setTextGrouping( pTextGroup, nTextGrouping ); + bChanged = true; + } + } + + if( bHasAnimateForm ) + { + if( pTextGroup->getAnimateForm() != bAnimateForm ) + { + pEffectSequence->setAnimateForm( pTextGroup, bAnimateForm ); + bChanged = true; + } + } + + if( bHasTextGroupingAuto ) + { + if( pTextGroup->getTextGroupingAuto() != fTextGroupingAuto ) + { + pEffectSequence->setTextGroupingAuto( pTextGroup, fTextGroupingAuto ); + bChanged = true; + } + } + + if( bHasTextReverse ) + { + if( pTextGroup->getTextReverse() != bTextReverse ) + { + pEffectSequence->setTextReverse( pTextGroup, bTextReverse ); + bChanged = true; + } + } + } + } + + if( bChanged ) + { + mpMainSequence->rebuild(); + updateControls(); + mrBase.GetDocShell()->SetModified(); + } +} + +void CustomAnimationPane::showOptions( sal_uInt16 nPage /* = 0 */ ) +{ + STLPropertySet* pSet = createSelectionSet(); + + CustomAnimationDialog* pDlg = new CustomAnimationDialog( this, pSet, nPage ); + if( pDlg->Execute() ) + { + addUndo(); + changeSelection( pDlg->getResultSet(), pSet ); + updateControls(); + } + + delete pDlg; +} + +void CustomAnimationPane::onChangeCurrentPage() +{ + if( mxView.is() ) try + { + Reference< XDrawPage > xNewPage( mxView->getCurrentPage() ); + if( xNewPage != mxCurrentPage ) + { + mxCurrentPage = xNewPage; + SdPage* pPage = SdPage::getImplementation( mxCurrentPage ); + if( pPage ) + { + mpMainSequence = pPage->getMainSequence(); + mpCustomAnimationList->update( mpMainSequence ); + } + updateControls(); + } + } + catch( Exception& ) + { + DBG_ERROR( "sd::CustomAnimationPane::onChangeCurrentPage(), exception catched!" ); + } +} + +bool getTextSelection( const Any& rSelection, Reference< XShape >& xShape, std::list< sal_Int16 >& rParaList ) +{ + Reference< XTextRange > xSelectedText; + rSelection >>= xSelectedText; + if( xSelectedText.is() ) try + { + xShape.set( xSelectedText->getText(), UNO_QUERY_THROW ); + + Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW ); + Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW ); + Reference< XEnumeration > xParaEnum( xParaEnumAccess->createEnumeration(), UNO_QUERY_THROW ); + Reference< XTextRange > xRange; + Reference< XTextRange > xStart( xSelectedText->getStart() ); + Reference< XTextRange > xEnd( xSelectedText->getEnd() ); + + if( xTextRangeCompare->compareRegionEnds( xStart, xEnd ) < 0 ) + { + Reference< XTextRange > xTemp( xStart ); + xStart = xEnd; + xEnd = xTemp; + } + + sal_Int16 nPara = 0; + while( xParaEnum->hasMoreElements() ) + { + xParaEnum->nextElement() >>= xRange; + + // break if start of selection is prior to end of current paragraph + if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) ) + break; + + nPara++; + } + + while( xRange.is() ) + { + if( xRange.is() && xRange->getString().getLength() ) + rParaList.push_back( nPara ); + + // break if end of selection is before or at end of current paragraph + if( xRange.is() && xTextRangeCompare->compareRegionEnds( xEnd, xRange ) >= 0 ) + break; + + nPara++; + + if( xParaEnum->hasMoreElements() ) + xParaEnum->nextElement() >>= xRange; + else + xRange.clear(); + } + + return true; + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR( "sd::CustomAnimationPane::getTextSelection(), exception cought!" ); + } + + return false; +} + +void CustomAnimationPane::onChange( bool bCreate ) +{ + bool bHasText = true; + + // first create vector of targets for dialog preview + std::vector< Any > aTargets; + OUString sPresetId; + double fDuration = 2.0f; + + if( bCreate ) + { + // gather shapes from the selection + Reference< XSelectionSupplier > xSel( mxView, UNO_QUERY_THROW ); + maViewSelection = xSel->getSelection(); + + if( maViewSelection.getValueType() == ::getCppuType((const Reference< XShapes >*)0) ) + { + Reference< XIndexAccess > xShapes; + maViewSelection >>= xShapes; + + sal_Int32 nCount = xShapes->getCount(); + sal_Int32 nIndex; + for( nIndex = 0; nIndex < nCount; nIndex++ ) + { + Any aTarget( xShapes->getByIndex( nIndex ) ); + aTargets.push_back( aTarget ); + if( bHasText ) + { + Reference< XText > xText; + aTarget >>= xText; + if( !xText.is() || xText->getString().getLength() == 0 ) + bHasText = false; + } + } + } + else if ( maViewSelection.getValueType() == ::getCppuType((const Reference< XShape >*)0) ) + { + aTargets.push_back( maViewSelection ); + Reference< XText > xText; + maViewSelection >>= xText; + if( !xText.is() || xText->getString().getLength() == 0 ) + bHasText = false; + } + else if ( maViewSelection.getValueType() == ::getCppuType((const Reference< XTextCursor >*)0) ) + { + Reference< XShape > xShape; + std::list< sal_Int16 > aParaList; + if( getTextSelection( maViewSelection, xShape, aParaList ) ) + { + ParagraphTarget aParaTarget; + aParaTarget.Shape = xShape; + + std::list< sal_Int16 >::iterator aIter( aParaList.begin() ); + for( ; aIter != aParaList.end(); aIter++ ) + { + aParaTarget.Paragraph = (*aIter); + aTargets.push_back( makeAny( aParaTarget ) ); + } + } + } + else + { + DBG_ERROR("sd::CustomAnimationPane::onChange(), unknown view selection!" ); + return; + } + } + else + { + // get selected effect + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + while( aIter != aEnd ) + { + if( !bHasText || !(*aIter)->hasText() ) + bHasText = false; + + if( sPresetId.getLength() == 0 ) + { + sPresetId = (*aIter)->getPresetId(); + fDuration = (*aIter)->getDuration(); + } + + aTargets.push_back( (*aIter++)->getTarget() ); + } + } + + CustomAnimationCreateDialog* pDlg = new CustomAnimationCreateDialog( this, this, aTargets, bHasText, sPresetId, fDuration ); + if( pDlg->Execute() ) + { + addUndo(); + fDuration = pDlg->getSelectedDuration(); + CustomAnimationPresetPtr pDescriptor = pDlg->getSelectedPreset(); + if( pDescriptor.get() ) + { + if( bCreate ) + { + mpCustomAnimationList->SelectAll( sal_False ); + + // gather shapes from the selection + std::vector< Any >::iterator aIter( aTargets.begin() ); + const std::vector< Any >::iterator aEnd( aTargets.end() ); + bool bFirst = true; + for( ; aIter != aEnd; aIter++ ) + { + CustomAnimationEffectPtr pCreated = mpMainSequence->append( pDescriptor, (*aIter), fDuration ); + + // if only one shape with text and no fill or outline is selected, animate only by first level paragraphs + if( bHasText && (aTargets.size() == 1) ) + { + Reference< XShape > xShape( (*aIter), UNO_QUERY ); + if( xShape.is() && !hasVisibleShape( xShape ) ) + { + mpMainSequence->createTextGroup( pCreated, 1, -1.0, sal_False, sal_False ); + } + } + + if( bFirst ) + bFirst = false; + else + pCreated->setNodeType( EffectNodeType::WITH_PREVIOUS ); + + if( pCreated.get() ) + { + mpCustomAnimationList->select( pCreated ); + } + } + } + else + { + MainSequenceRebuildGuard aGuard( mpMainSequence ); + + // get selected effect + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + + EffectSequenceHelper* pEffectSequence = pEffect->getEffectSequence(); + if( !pEffectSequence ) + pEffectSequence = mpMainSequence.get(); + + pEffectSequence->replace( pEffect, pDescriptor, fDuration ); + } + } + } + else + { + PathKind eKind = pDlg->getCreatePathKind(); + if( eKind != NONE ) + createPath( eKind, aTargets, fDuration ); + } + mrBase.GetDocShell()->SetModified(); + } + + delete pDlg; + + updateControls(); + + // stop running preview from dialog + SlideShow::Stop( mrBase ); +} + +void CustomAnimationPane::createPath( PathKind eKind, std::vector< Any >& rTargets, double fDuration) +{ + sal_uInt16 nSID = 0; + + switch( eKind ) + { + case CURVE: nSID = SID_DRAW_BEZIER_NOFILL; break; + case POLYGON: nSID = SID_DRAW_POLYGON_NOFILL; break; + case FREEFORM: nSID = SID_DRAW_FREELINE_NOFILL; break; + default: break; + } + + if( nSID ) + { + DrawViewShell* pViewShell = dynamic_cast< DrawViewShell* >( + FrameworkHelper::Instance(mrBase)->GetViewShell(FrameworkHelper::msCenterPaneURL).get()); + + if( pViewShell ) + { + DrawView* pView = pViewShell->GetDrawView(); + if( pView ) + pView->UnmarkAllObj(); + + std::vector< Any > aTargets( 1, Any( fDuration ) ); + aTargets.insert( aTargets.end(), rTargets.begin(), rTargets.end() ); + Sequence< Any > aTargetSequence( comphelper::containerToSequence( aTargets ) ); + const SfxUnoAnyItem aItem( SID_ADD_MOTION_PATH, Any( aTargetSequence ) ); + pViewShell->GetViewFrame()->GetDispatcher()->Execute( nSID, SFX_CALLMODE_ASYNCHRON, &aItem, 0 ); + } + } +} + +void CustomAnimationPane::onRemove() +{ + if( maListSelection.size() ) + { + addUndo(); + + MainSequenceRebuildGuard aGuard( mpMainSequence ); + + EffectSequence aList( maListSelection ); + + EffectSequence::iterator aIter( aList.begin() ); + const EffectSequence::iterator aEnd( aList.end() ); + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + if( pEffect->getEffectSequence() ) + pEffect->getEffectSequence()->remove( pEffect ); + } + + maListSelection.clear(); + mrBase.GetDocShell()->SetModified(); + } +} + +void CustomAnimationPane::remove( CustomAnimationEffectPtr& pEffect ) +{ + if( pEffect->getEffectSequence() ) + { + addUndo(); + pEffect->getEffectSequence()->remove( pEffect ); + mrBase.GetDocShell()->SetModified(); + } +} + +void CustomAnimationPane::onChangeStart() +{ + if( mpLBStart->GetSelectEntryCount() == 1 ) + { + sal_Int16 nNodeType; + sal_uInt16 nPos= mpLBStart->GetSelectEntryPos(); + switch( nPos ) + { + case 0: nNodeType = EffectNodeType::ON_CLICK; break; + case 1: nNodeType = EffectNodeType::WITH_PREVIOUS; break; + case 2: nNodeType = EffectNodeType::AFTER_PREVIOUS; break; + default: + return; + } + + onChangeStart( nNodeType ); + } +} + +void CustomAnimationPane::onChangeStart( sal_Int16 nNodeType ) +{ + addUndo(); + + MainSequenceRebuildGuard aGuard( mpMainSequence ); + + bool bNeedRebuild = false; + + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + if( pEffect->getNodeType() != nNodeType ) + { + pEffect->setNodeType( nNodeType ); + bNeedRebuild = true; + } + } + + if( bNeedRebuild ) + { + mpMainSequence->rebuild(); + updateControls(); + mrBase.GetDocShell()->SetModified(); + } +} + +void CustomAnimationPane::onChangeProperty() +{ + if( mpLBProperty->getSubControl() ) + { + addUndo(); + + MainSequenceRebuildGuard aGuard( mpMainSequence ); + + const Any aValue( mpLBProperty->getSubControl()->getValue() ); + + bool bNeedUpdate = false; + + // change selected effect + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + + if( setProperty1Value( mnPropertyType, pEffect, aValue ) ) + bNeedUpdate = true; + } + + if( bNeedUpdate ) + { + mpMainSequence->rebuild(); + updateControls(); + mrBase.GetDocShell()->SetModified(); + } + + onPreview( false ); + } +} + +void CustomAnimationPane::onChangeSpeed() +{ + if( mpCBSpeed->GetSelectEntryCount() == 1 ) + { + addUndo(); + + MainSequenceRebuildGuard aGuard( mpMainSequence ); + + double fDuration; + + sal_uInt16 nPos= mpCBSpeed->GetSelectEntryPos(); + + switch( nPos ) + { + case 0: fDuration = 5.0; break; + case 1: fDuration = 3.0; break; + case 2: fDuration = 2.0; break; + case 3: fDuration = 1.0; break; + case 4: fDuration = 0.5; break; + default: + return; + } + + // change selected effect + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + pEffect->setDuration( fDuration ); + } + + mpMainSequence->rebuild(); + updateControls(); + mrBase.GetDocShell()->SetModified(); + + onPreview( false ); + } +} + +/// this link is called when the property box is modified by the user +IMPL_LINK( CustomAnimationPane, implPropertyHdl, Control*, EMPTYARG ) +{ + onChangeProperty(); + return 0; +} + +/// this link is called when one of the controls is modified +IMPL_LINK( CustomAnimationPane, implControlHdl, Control*, pControl ) +{ + if( pControl == mpPBAddEffect ) + onChange(true); + else if( pControl == mpPBChangeEffect ) + onChange(false); + else if( pControl == mpPBRemoveEffect ) + onRemove(); + else if( pControl == mpLBStart ) + onChangeStart(); + else if( pControl == mpCBSpeed ) + onChangeSpeed(); + else if( pControl == mpPBPropertyMore ) + showOptions(); + else if( pControl == mpPBMoveUp ) + moveSelection( true ); + else if( pControl == mpPBMoveDown ) + moveSelection( false ); + else if( pControl == mpPBPlay ) + onPreview( true ); + else if( pControl == mpPBSlideShow ) + { + mrBase.StartPresentation(); + } + else if( pControl == mpCBAutoPreview ) + { + SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS); + pOptions->SetPreviewChangedEffects( mpCBAutoPreview->IsChecked() ? sal_True : sal_False ); + } + + updateControls(); + + return 0; +} + +IMPL_LINK(CustomAnimationPane, lateInitCallback, Timer*, EMPTYARG ) +{ + // Call getPresets() to initiate the (expensive) construction of the + // presets list. + getPresets(); + + // update selection and control states + onSelectionChanged(); + + return 0; +} + +void CustomAnimationPane::moveSelection( bool bUp ) +{ + if( maListSelection.empty() ) + return; + + EffectSequenceHelper* pSequence = maListSelection.front()->getEffectSequence(); + if( pSequence == 0 ) + return; + + addUndo(); + + bool bChanged = false; + + MainSequenceRebuildGuard aGuard( mpMainSequence ); + EffectSequence& rEffectSequence = pSequence->getSequence(); + + if( bUp ) + { + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + + EffectSequence::iterator aEffectPos( pSequence->find( pEffect ) ); + if( aEffectPos != rEffectSequence.end() ) + { + EffectSequence::iterator aInsertPos( rEffectSequence.erase( aEffectPos ) ); + + if( aInsertPos != rEffectSequence.begin() ) + { + aInsertPos--; + while( (aInsertPos != rEffectSequence.begin()) && !mpCustomAnimationList->isExpanded(*aInsertPos)) + aInsertPos--; + + rEffectSequence.insert( aInsertPos, pEffect ); + } + else + { + rEffectSequence.push_front( pEffect ); + } + bChanged = true; + } + } + } + else + { + EffectSequence::reverse_iterator aIter( maListSelection.rbegin() ); + const EffectSequence::reverse_iterator aEnd( maListSelection.rend() ); + + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + + EffectSequence::iterator aEffectPos( pSequence->find( pEffect ) ); + if( aEffectPos != rEffectSequence.end() ) + { + EffectSequence::iterator aInsertPos( rEffectSequence.erase( aEffectPos ) ); + + if( aInsertPos != rEffectSequence.end() ) + { + aInsertPos++; + while( (aInsertPos != rEffectSequence.end()) && !mpCustomAnimationList->isExpanded(*aInsertPos)) + aInsertPos++; + + rEffectSequence.insert( aInsertPos, pEffect ); + } + else + { + rEffectSequence.push_back( pEffect ); + } + bChanged = true; + } + } + } + + if( bChanged ) + { + mpMainSequence->rebuild(); + updateControls(); + mrBase.GetDocShell()->SetModified(); + } +} + +void CustomAnimationPane::onPreview( bool bForcePreview ) +{ + if( !bForcePreview && !mpCBAutoPreview->IsChecked() ) + return; + + if( maListSelection.empty() ) + { + rtl::Reference< MotionPathTag > xMotionPathTag; + MotionPathTagVector::iterator aIter; + for( aIter = maMotionPathTags.begin(); aIter != maMotionPathTags.end(); aIter++ ) + { + if( (*aIter)->isSelected() ) + { + xMotionPathTag = (*aIter); + break; + } + } + + if( xMotionPathTag.is() ) + { + MainSequencePtr pSequence( new MainSequence() ); + pSequence->append( xMotionPathTag->getEffect()->clone() ); + preview( pSequence->getRootNode() ); + } + else + { + Reference< XAnimationNodeSupplier > xNodeSupplier( mxCurrentPage, UNO_QUERY ); + if( !xNodeSupplier.is() ) + return; + + preview( xNodeSupplier->getAnimationNode() ); + } + } + else + { + MainSequencePtr pSequence( new MainSequence() ); + + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + pSequence->append( pEffect->clone() ); + } + + preview( pSequence->getRootNode() ); + } +} + +void CustomAnimationPane::preview( const Reference< XAnimationNode >& xAnimationNode ) +{ + Reference< XTimeContainer > xRoot(::comphelper::getProcessServiceFactory()->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.ParallelTimeContainer"))), UNO_QUERY); + if( xRoot.is() ) + { + Sequence< ::com::sun::star::beans::NamedValue > aUserData( 1 ); + aUserData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) ); + aUserData[0].Value <<= ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT; + xRoot->setUserData( aUserData ); + xRoot->appendChild( xAnimationNode ); + + Reference< XAnimationNode > xNode( xRoot, UNO_QUERY ); + SlideShow::StartPreview( mrBase, mxCurrentPage, xNode ); + } +} + + +// ICustomAnimationListController +void CustomAnimationPane::onSelect() +{ + maListSelection = mpCustomAnimationList->getSelection(); + updateControls(); + markShapesFromSelectedEffects(); +} + + + + +const CustomAnimationPresets& CustomAnimationPane::getPresets (void) +{ + if (mpCustomAnimationPresets == NULL) + mpCustomAnimationPresets = &CustomAnimationPresets::getCustomAnimationPresets(); + return *mpCustomAnimationPresets; +} + + + +void CustomAnimationPane::markShapesFromSelectedEffects() +{ + if( !maSelectionLock.isLocked() ) + { + ScopeLockGuard aGuard( maSelectionLock ); + DrawViewShell* pViewShell = dynamic_cast< DrawViewShell* >( + FrameworkHelper::Instance(mrBase)->GetViewShell(FrameworkHelper::msCenterPaneURL).get()); + DrawView* pView = pViewShell ? pViewShell->GetDrawView() : NULL; + + if( pView ) + { + pView->UnmarkAllObj(); + EffectSequence::iterator aIter( maListSelection.begin() ); + const EffectSequence::iterator aEnd( maListSelection.end() ); + while( aIter != aEnd ) + { + CustomAnimationEffectPtr pEffect = (*aIter++); + + Reference< XShape > xShape( pEffect->getTargetShape() ); + SdrObject* pObj = GetSdrObjectFromXShape( xShape ); + if( pObj ) + pView->MarkObj(pObj, pView->GetSdrPageView(), sal_False, sal_False); + } + } + } +} + + +void CustomAnimationPane::updatePathFromMotionPathTag( const rtl::Reference< MotionPathTag >& xTag ) +{ + MainSequenceRebuildGuard aGuard( mpMainSequence ); + if( xTag.is() ) + { + SdrPathObj* pPathObj = xTag->getPathObj(); + CustomAnimationEffectPtr pEffect = xTag->getEffect(); + if( (pPathObj != 0) && pEffect.get() != 0 ) + { + ::svl::IUndoManager* pManager = mrBase.GetDocShell()->GetUndoManager(); + if( pManager ) + { + SdPage* pPage = SdPage::getImplementation( mxCurrentPage ); + if( pPage ) + pManager->AddUndoAction( new UndoAnimationPath( mrBase.GetDocShell()->GetDoc(), pPage, pEffect->getNode() ) ); + } + + pEffect->updatePathFromSdrPathObj( *pPathObj ); + } + } +} + +// ==================================================================== + +::Window * createCustomAnimationPanel( ::Window* pParent, ViewShellBase& rBase ) +{ + DialogListBox* pWindow = 0; + + DrawDocShell* pDocSh = rBase.GetDocShell(); + if( pDocSh ) + { + pWindow = new DialogListBox( pParent, WB_CLIPCHILDREN|WB_TABSTOP|WB_AUTOHSCROLL ); + + Size aMinSize( pWindow->LogicToPixel( Size( 80, 256 ), MAP_APPFONT ) ); + ::Window* pPaneWindow = new CustomAnimationPane( pWindow, rBase, aMinSize ); + pWindow->SetChildWindow( pPaneWindow, aMinSize ); + pWindow->SetText( pPaneWindow->GetText() ); + } + + return pWindow; +} + + + +} diff --git a/sd/source/ui/animations/CustomAnimationPane.hrc b/sd/source/ui/animations/CustomAnimationPane.hrc new file mode 100644 index 000000000000..0db342f7995f --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationPane.hrc @@ -0,0 +1,60 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_CUSTOMANIMATIONPANE_HRC +#define _SD_CUSTOMANIMATIONPANE_HRC + +#define CM_WITH_CLICK 1 +#define CM_WITH_PREVIOUS 2 +#define CM_AFTER_PREVIOUS 3 +#define CM_OPTIONS 4 +#define CM_DURATION 5 +#define CM_REMOVE 6 + +#define FL_EFFECT 1 +#define PB_ADD_EFFECT 2 +#define PB_CHANGE_EFFECT 3 +#define PB_REMOVE_EFFECT 4 +#define FL_MODIFY 5 +#define FT_START 6 +#define LB_START 7 +#define FT_PROPERTY 8 +#define LB_PROPERTY 9 +#define PB_PROPERTY_MORE 10 +#define FT_SPEED 12 +#define CB_SPEED 13 +#define CT_CUSTOM_ANIMATION_LIST 14 +#define FT_CHANGE_ORDER 15 +#define PB_MOVE_UP 16 +#define PB_MOVE_DOWN 17 +#define FL_SEPERATOR1 18 +#define PB_PLAY 19 +#define PB_SLIDE_SHOW 20 +#define FL_SEPERATOR2 21 +#define CB_AUTOPREVIEW 22 + +#endif // _SD_CUSTOMANIMATIONPANE_HXX diff --git a/sd/source/ui/animations/CustomAnimationPane.hxx b/sd/source/ui/animations/CustomAnimationPane.hxx new file mode 100755 index 000000000000..33dd25ebaf66 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationPane.hxx @@ -0,0 +1,190 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_CUSTOMANIMATIONPANE_HXX +#define _SD_CUSTOMANIMATIONPANE_HXX + +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <vcl/dialog.hxx> +#include "CustomAnimationPreset.hxx" +#include "CustomAnimationList.hxx" +#include "CustomAnimationCreateDialog.hxx" + +#include "motionpathtag.hxx" +#include "misc/scopelock.hxx" + +#include <vector> + +class PushButton; +class FixedLine; +class FixedText; +class ListBox; +class ComboBox; +class CheckBox; +class SdDrawDocument; + +namespace com { namespace sun { namespace star { namespace animations { + class XAnimationNode; +} } } } + +namespace sd { namespace tools { +class EventMultiplexerEvent; +} } + +namespace sd { + +class PropertyControl; +class STLPropertySet; +class ViewShellBase; + +typedef std::vector< rtl::Reference< MotionPathTag > > MotionPathTagVector; + +// -------------------------------------------------------------------- + +class CustomAnimationPane : public Control, public ICustomAnimationListController +{ + friend class MotionPathTag; +public: + CustomAnimationPane( ::Window* pParent, ViewShellBase& rBase, const Size& rMinSize ); + virtual ~CustomAnimationPane(); + + // callbacks + void onSelectionChanged(); + void onChangeCurrentPage(); + void onChange( bool bCreate ); + void onRemove(); + void onChangeStart(); + void onChangeStart( sal_Int16 nNodeType ); + void onChangeProperty(); + void onChangeSpeed(); + + // methods + void preview( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xAnimationNode ); + void remove( CustomAnimationEffectPtr& pEffect ); + + // Control + virtual void Resize(); + virtual void StateChanged( StateChangedType nStateChange ); + virtual void KeyInput( const KeyEvent& rKEvt ); + + // ICustomAnimationListController + virtual void onSelect(); + virtual void onDoubleClick(); + virtual void onContextMenu( sal_uInt16 nSelectedPopupEntry ); + + void addUndo(); + + void updatePathFromMotionPathTag( const rtl::Reference< MotionPathTag >& xTag ); + +private: + void addListener(); + void removeListener(); + void updateLayout(); + void updateControls(); + void updateMotionPathTags(); + void markShapesFromSelectedEffects(); + + void showOptions( sal_uInt16 nPage = 0 ); + void moveSelection( bool bUp ); + void onPreview( bool bForcePreview ); + + void createPath( PathKind eKind, std::vector< ::com::sun::star::uno::Any >& rTargets, double fDuration ); + + STLPropertySet* createSelectionSet(); + void changeSelection( STLPropertySet* pResultSet, STLPropertySet* pOldSet ); + + ::com::sun::star::uno::Any getProperty1Value( sal_Int32 nType, CustomAnimationEffectPtr pEffect ); + bool setProperty1Value( sal_Int32 nType, CustomAnimationEffectPtr pEffect, const ::com::sun::star::uno::Any& rValue ); + + DECL_LINK( implControlHdl, Control* ); + DECL_LINK( implPropertyHdl, Control* ); + DECL_LINK(EventMultiplexerListener, tools::EventMultiplexerEvent*); + DECL_LINK(lateInitCallback, Timer*); + +private: + ViewShellBase& mrBase; + + const CustomAnimationPresets* mpCustomAnimationPresets; + + FixedLine* mpFLModify; + PushButton* mpPBAddEffect; + PushButton* mpPBChangeEffect; + PushButton* mpPBRemoveEffect; + FixedLine* mpFLEffect; + FixedText* mpFTStart; + ListBox* mpLBStart; + FixedText* mpFTProperty; + PropertyControl* mpLBProperty; + PushButton* mpPBPropertyMore; + FixedText* mpFTSpeed; + ComboBox* mpCBSpeed; + CustomAnimationList* mpCustomAnimationList; + FixedText* mpFTChangeOrder; + PushButton* mpPBMoveUp; + PushButton* mpPBMoveDown; + FixedLine* mpFLSeperator1; + PushButton* mpPBPlay; + PushButton* mpPBSlideShow; + FixedLine* mpFLSeperator2; + CheckBox* mpCBAutoPreview; + + String maStrModify; + String maStrProperty; + + sal_Int32 mnPropertyType; + + Size maMinSize; + + EffectSequence maListSelection; + ::com::sun::star::uno::Any maViewSelection; + + MainSequencePtr mpMainSequence; + + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > mxCurrentPage; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawView > mxView; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxModel; + + /** The mpCustomAnimationPresets is initialized either on demand or + after a short time after the construction of a new object of this + class. This timer is responsible for the later. + */ + Timer maLateInitTimer; + + /** This method initializes the mpCustomAnimationPresets on demand and + returns a reference to the list. + */ + const CustomAnimationPresets& getPresets (void); + + MotionPathTagVector maMotionPathTags; + + ScopeLock maSelectionLock; +}; + +} + +#endif // _SD_CUSTOMANIMATIONPANE_HXX diff --git a/sd/source/ui/animations/CustomAnimationPane.src b/sd/source/ui/animations/CustomAnimationPane.src new file mode 100644 index 000000000000..267fe1269111 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationPane.src @@ -0,0 +1,225 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "CustomAnimationPane.hrc" +#include "CustomAnimation.hrc" +#include "helpids.h" + +Control DLG_CUSTOMANIMATIONPANE +{ + OutputSize = TRUE; + DialogControl = TRUE; + Border = FALSE; + + Size = MAP_APPFONT( 160, 300 ); + Text [ en-US ] = "Custom Animation"; + + FixedLine FL_EFFECT + { + OutputSize = TRUE; + Size = MAP_APPFONT( 260, 8 ); + + Text [ en-US ] = "Effect"; + }; + + PushButton PB_ADD_EFFECT + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_PB_ADD_EFFECT; + OutputSize = TRUE; + TabStop = TRUE; + Size = MAP_APPFONT( 50, 14 ); + + Text [ en-US ] = "~Add..."; + }; + + PushButton PB_CHANGE_EFFECT + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_PB_CHANGE_EFFECT; + OutputSize = TRUE; + TabStop = TRUE; + Size = MAP_APPFONT( 50, 14 ); + + Text [ en-US ] = "~Change..."; + }; + + PushButton PB_REMOVE_EFFECT + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_PB_REMOVE_EFFECT; + OutputSize = TRUE; + TabStop = TRUE; + Size = MAP_APPFONT( 50, 14 ); + + Text [ en-US ] = "~Remove"; + }; + + FixedLine FL_MODIFY + { + OutputSize = TRUE; + Size = MAP_APPFONT( 260, 8 ); + + Text [ en-US ] = "Modify effect"; + }; + + FixedText FT_START + { + OutputSize = TRUE; + Size = MAP_APPFONT( 42, 8 ); + + Text [ en-US ] = "~Start"; + }; + + ListBox LB_START + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_LB_START; + Size = MAP_APPFONT ( 120 , 48 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + + StringList [ en-US ] = + { + < "On click" ; > ; + < "With previous" ; > ; + < "After previous" ; > ; + }; + }; + + FixedText FT_PROPERTY + { + OutputSize = TRUE; + Size = MAP_APPFONT( 42, 8 ); + + Text [ en-US ] = "Property"; + }; + + ListBox LB_PROPERTY + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_LB_PROPERTY; + Size = MAP_APPFONT ( 120 , 48 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; + + PushButton PB_PROPERTY_MORE + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_PB_PROPERTY_MORE; + OutputSize = TRUE; + TabStop = TRUE; + Size = MAP_APPFONT( 16, 14 ); + + Text [ en-US ] = "~..."; + + QuickHelpText [en-US ] = "Effect Options"; + }; + + FixedText FT_SPEED + { + OutputSize = TRUE; + Size = MAP_APPFONT( 42, 8 ); + + Text [ en-US ] = "Sp~eed"; + }; + + ComboBox CB_SPEED + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_CB_SPEED; + Size = MAP_APPFONT ( 120 , 48 ); + TabStop = TRUE ; + Border = TRUE ; + DropDown = TRUE ; + }; + + Control CT_CUSTOM_ANIMATION_LIST + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_CT_CUSTOM_ANIMATION_LIST; + TabStop = TRUE; + Border = TRUE; + }; + + FixedText FT_CHANGE_ORDER + { + OutputSize = TRUE; + Size = MAP_APPFONT( 42, 8 ); + + Text [ en-US ] = "Change order:"; + }; + + PushButton PB_MOVE_UP + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_PB_MOVE_UP; + OutputSize = TRUE; + TabStop = TRUE; + Size = MAP_APPFONT( 16, 14 ); + }; + + PushButton PB_MOVE_DOWN + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_PB_MOVE_DOWN; + OutputSize = TRUE; + TabStop = TRUE; + Size = MAP_APPFONT( 16, 14 ); + }; + + FixedLine FL_SEPERATOR1 + { + OutputSize = TRUE; + Size = MAP_APPFONT( 8, 8 ); + }; + + PushButton PB_PLAY + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_PB_PLAY; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE; + + Text [ en-US ] = "~Play"; + }; + + PushButton PB_SLIDE_SHOW + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_PB_SLIDE_SHOW; + Size = MAP_APPFONT ( 80 , 14 ) ; + TabStop = TRUE; + + Text [ en-US ] = "Slide Sho~w"; + }; + + FixedLine FL_SEPERATOR2 + { + Size = MAP_APPFONT( 8, 8 ); + }; + + CheckBox CB_AUTOPREVIEW + { + HelpId = HID_SD_CUSTOMANIMATIONPANE_CB_AUTOPREVIEW; + Size = MAP_APPFONT ( 120 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Automatic pre~view" ; + }; +}; + diff --git a/sd/source/ui/animations/DialogListBox.cxx b/sd/source/ui/animations/DialogListBox.cxx new file mode 100755 index 000000000000..83e4cbdd4d65 --- /dev/null +++ b/sd/source/ui/animations/DialogListBox.cxx @@ -0,0 +1,340 @@ +/************************************************************************* + * + * 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 "DialogListBox.hxx" + +namespace sd +{ + +DialogListBox::DialogListBox( Window* pParent, WinBits nWinStyle ) : + Control( pParent, nWinStyle ), + mpChild( 0 ) +{ + mpVScrollBar = new ScrollBar( this, WB_VSCROLL | WB_DRAG ); + mpHScrollBar = new ScrollBar( this, WB_HSCROLL | WB_DRAG ); + mpScrollBarBox = new ScrollBarBox( this ); + + Link aLink( LINK( this, DialogListBox, ScrollBarHdl ) ); + mpVScrollBar->SetScrollHdl( aLink ); + mpHScrollBar->SetScrollHdl( aLink ); + + mbVScroll = false; + mbHScroll = false; + mbAutoHScroll = ( nWinStyle & WB_AUTOHSCROLL ) ? true : false; +} + +// ----------------------------------------------------------------------- + +DialogListBox::~DialogListBox() +{ + delete mpHScrollBar; + delete mpVScrollBar; + delete mpScrollBarBox; + delete mpChild; +} + +// ----------------------------------------------------------------------- + +void DialogListBox::SetChildWindow( Window* pChild, const Size& rMinSize ) +{ + if( mpChild ) + delete mpChild; + + mpChild = pChild; + maMinSize = rMinSize; + ImplResizeControls(); + ImplCheckScrollBars(); +} + +// ----------------------------------------------------------------------- + +void DialogListBox::GetFocus() +{ + if( mpChild ) + mpChild->GrabFocus(); +} + +// ----------------------------------------------------------------------- + +::Window* DialogListBox::GetPreferredKeyInputWindow() +{ + if( mpChild ) + return mpChild; + else + return this; +} + +// ----------------------------------------------------------------------- + +void DialogListBox::Resize() +{ + Control::Resize(); + ImplResizeControls(); + ImplCheckScrollBars(); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( DialogListBox, ScrollBarHdl, ScrollBar*, EMPTYARG ) +{ + ImplResizeChild(); + return 1; +} + +// ----------------------------------------------------------------------- + +void DialogListBox::ImplCheckScrollBars() +{ + bool bArrange = false; + + Size aOutSz = GetOutputSizePixel(); + + // vert. ScrollBar + if( aOutSz.Height() < maMinSize.Height() ) + { + if( !mbVScroll ) + bArrange = true; + mbVScroll = true; + } + else + { + if( mbVScroll ) + bArrange = true; + mbVScroll = false; + } + + // horz. ScrollBar + if( mbAutoHScroll ) + { + long nWidth = aOutSz.Width(); + if ( mbVScroll ) + nWidth -= mpVScrollBar->GetSizePixel().Width(); + if( nWidth < maMinSize.Width() ) + { + if( !mbHScroll ) + bArrange = true; + mbHScroll = true; + + if ( !mbVScroll ) + { + int nHeight = aOutSz.Height() - mpHScrollBar->GetSizePixel().Height(); + if( nHeight < maMinSize.Height() ) + { + if( !mbVScroll ) + bArrange = true; + mbVScroll = true; + } + } + } + else + { + if( mbHScroll ) + bArrange = true; + mbHScroll = false; + } + } + + if( bArrange ) + ImplResizeControls(); + + ImplInitScrollBars(); +} + +// ----------------------------------------------------------------------- + +void DialogListBox::ImplInitScrollBars() +{ + if( mpChild ) + { + Size aOutSize( GetOutputSizePixel() ); + if( mbHScroll ) aOutSize.Height() -= mpHScrollBar->GetSizePixel().Height(); + if( mbVScroll ) aOutSize.Width() -= mpVScrollBar->GetSizePixel().Width(); + + if ( mbVScroll ) + { + mpVScrollBar->SetRangeMax( maMinSize.Height() ); + mpVScrollBar->SetVisibleSize( aOutSize.Height() ); + mpVScrollBar->SetPageSize( 16 ); + } + + if ( mbHScroll ) + { + mpHScrollBar->SetRangeMax( maMinSize.Width() ); + mpHScrollBar->SetVisibleSize( aOutSize.Width() ); + mpHScrollBar->SetPageSize( 16 ); + } + } +} + +// ----------------------------------------------------------------------- + +void DialogListBox::ImplResizeControls() +{ + Size aOutSz( GetOutputSizePixel() ); + long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize(); + nSBWidth = CalcZoom( nSBWidth ); + + maInnerSize = aOutSz; + if ( mbVScroll ) + maInnerSize.Width() -= nSBWidth; + if ( mbHScroll ) + maInnerSize.Height() -= nSBWidth; + + // ScrollBarBox + if( mbVScroll && mbHScroll ) + { + Point aBoxPos( maInnerSize.Width(), maInnerSize.Height() ); + mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) ); + mpScrollBarBox->Show(); + } + else + { + mpScrollBarBox->Hide(); + } + + // vert. ScrollBar + if( mbVScroll ) + { + // Scrollbar on left or right side? + Point aVPos( aOutSz.Width() - nSBWidth, 0 ); + mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, maInnerSize.Height() ) ); + mpVScrollBar->Show(); + } + else + { + mpVScrollBar->Hide(); + } + + // horz. ScrollBar + if( mbHScroll ) + { + Point aHPos( 0, aOutSz.Height() - nSBWidth ); + mpHScrollBar->SetPosSizePixel( aHPos, Size( maInnerSize.Width(), nSBWidth ) ); + mpHScrollBar->Show(); + } + else + { + mpHScrollBar->Hide(); + } + + ImplResizeChild(); +} + +void DialogListBox::ImplResizeChild() +{ + Point aWinPos; + Size aSize( maInnerSize ); + + int nOffset; + if( mbHScroll ) + { + nOffset = mpHScrollBar->GetThumbPos(); + aWinPos.X() = -nOffset; + aSize.Width() += nOffset; + } + + if( mbVScroll ) + { + nOffset = mpVScrollBar->GetThumbPos(); + aWinPos.Y() = -nOffset; + aSize.Height() += nOffset; + } + + mpChild->SetPosSizePixel( aWinPos, aSize ); +} + +// ----------------------------------------------------------------------- + +void DialogListBox::StateChanged( StateChangedType nType ) +{ + if ( nType == STATE_CHANGE_INITSHOW ) + { + ImplCheckScrollBars(); + } + else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) ) + { + sal_Bool bUpdate = IsUpdateMode(); + mpChild->SetUpdateMode( bUpdate ); + if ( bUpdate && IsReallyVisible() ) + ImplCheckScrollBars(); + } + else if( nType == STATE_CHANGE_ENABLE ) + { + mpHScrollBar->Enable( IsEnabled() ); + mpVScrollBar->Enable( IsEnabled() ); + mpScrollBarBox->Enable( IsEnabled() ); + Invalidate(); + } + else if ( nType == STATE_CHANGE_ZOOM ) + { + mpChild->SetZoom( GetZoom() ); + Resize(); + } + else if ( nType == STATE_CHANGE_CONTROLFONT ) + { + mpChild->SetControlFont( GetControlFont() ); + } + else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) + { + mpChild->SetControlForeground( GetControlForeground() ); + } + else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) + { + mpChild->SetControlBackground( GetControlBackground() ); + } + else if( nType == STATE_CHANGE_VISIBLE ) + { + mpChild->Show( IsVisible() ); + } + + Control::StateChanged( nType ); +} + +// ----------------------------------------------------------------------- + +long DialogListBox::Notify( NotifyEvent& rNEvt ) +{ + long nDone = 0; + if ( rNEvt.GetType() == EVENT_COMMAND ) + { + const CommandEvent& rCEvt = *rNEvt.GetCommandEvent(); + if ( rCEvt.GetCommand() == COMMAND_WHEEL ) + { + const CommandWheelData* pData = rCEvt.GetWheelData(); + if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) ) + { + nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar ); + } + } + } + + return nDone ? nDone : Window::Notify( rNEvt ); +} + +} // namespace sd diff --git a/sd/source/ui/animations/STLPropertySet.cxx b/sd/source/ui/animations/STLPropertySet.cxx new file mode 100644 index 000000000000..3f72f581222e --- /dev/null +++ b/sd/source/ui/animations/STLPropertySet.cxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * 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 <tools/debug.hxx> +#include "STLPropertySet.hxx" + +using namespace com::sun::star::beans; + +using rtl::OUString; +using com::sun::star::uno::Any; + +namespace sd +{ + +STLPropertySet::STLPropertySet() +{ +} + +STLPropertySet::~STLPropertySet() +{ +} + +void STLPropertySet::setPropertyDefaultValue( sal_Int32 nHandle, const Any& rValue ) +{ + STLPropertyMapEntry aEntry( rValue, STLPropertyState_DEFAULT ); + maPropertyMap[ nHandle ] = aEntry; +} + +void STLPropertySet::setPropertyValue( sal_Int32 nHandle, const Any& rValue, sal_Int32 /* nState = STLPropertyState_DIRECT */ ) +{ + PropertyMapIter aIter; + if( findProperty( nHandle, aIter ) ) + { + (*aIter).second.mnState = STLPropertyState_DIRECT; + (*aIter).second.maValue = rValue; + } + else + { + DBG_ERROR( "sd::STLPropertySet::setPropertyValue(), unknown property!" ); + } +} + +Any STLPropertySet::getPropertyValue( sal_Int32 nHandle ) const +{ + PropertyMapConstIter aIter; + if( findProperty( nHandle, aIter ) ) + { + return (*aIter).second.maValue; + } + else + { + DBG_ERROR( "sd::STLPropertySet::setPropertyValue(), unknown property!" ); + + Any aAny; + return aAny; + } +} + +sal_Int32 STLPropertySet::getPropertyState( sal_Int32 nHandle ) const +{ + PropertyMapConstIter aIter; + if( findProperty( nHandle, aIter ) ) + { + return (*aIter).second.mnState; + } + else + { + DBG_ERROR( "sd::STLPropertySet::setPropertyState(), unknown property!" ); + return STLPropertyState_AMBIGUOUS; + } +} + +void STLPropertySet::setPropertyState( sal_Int32 nHandle, sal_Int32 nState ) +{ + PropertyMapIter aIter; + if( findProperty( nHandle, aIter ) ) + { + (*aIter).second.mnState = nState; + } + else + { + DBG_ERROR( "sd::STLPropertySet::setPropertyState(), unknown property!" ); + } +} + +bool STLPropertySet::findProperty( sal_Int32 nHandle, PropertyMapIter& rIter ) +{ + rIter = maPropertyMap.find(nHandle); + return( rIter != maPropertyMap.end() ); +} + +bool STLPropertySet::findProperty( sal_Int32 nHandle, PropertyMapConstIter& rIter ) const +{ + rIter = maPropertyMap.find(nHandle); + return( rIter != maPropertyMap.end() ); +} + +} diff --git a/sd/source/ui/animations/STLPropertySet.hxx b/sd/source/ui/animations/STLPropertySet.hxx new file mode 100644 index 000000000000..2d5d95b5d7f4 --- /dev/null +++ b/sd/source/ui/animations/STLPropertySet.hxx @@ -0,0 +1,86 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_STLPROPERTYSET_HXX +#define _SD_STLPROPERTYSET_HXX + +#include <com/sun/star/beans/PropertyValue.hpp> + +#ifndef _UTL_STLTYPES_HXX_ +#include <comphelper/stl_types.hxx> +#endif + +#include <list> +#include <map> + +namespace sd +{ + +const sal_Int32 STLPropertyState_DEFAULT = 0; +const sal_Int32 STLPropertyState_DIRECT = 1; +const sal_Int32 STLPropertyState_AMBIGUOUS = 3; + +struct STLPropertyMapEntry +{ + ::com::sun::star::uno::Any maValue; + sal_Int32 mnState; + + STLPropertyMapEntry() + : mnState( STLPropertyState_AMBIGUOUS ) {} + STLPropertyMapEntry( ::com::sun::star::uno::Any aValue, sal_Int32 nState = STLPropertyState_DEFAULT ) + : maValue( aValue ), mnState( nState ) {} + +}; + +typedef std::map<sal_Int32, STLPropertyMapEntry > PropertyMap; +typedef PropertyMap::iterator PropertyMapIter; +typedef PropertyMap::const_iterator PropertyMapConstIter; + +class STLPropertySet +{ +public: + STLPropertySet(); + ~STLPropertySet(); + + void setPropertyDefaultValue( sal_Int32 nHandle, const com::sun::star::uno::Any& rValue ); + void setPropertyValue( sal_Int32 nHandle, const com::sun::star::uno::Any& rValue, sal_Int32 nState = STLPropertyState_DIRECT ); + ::com::sun::star::uno::Any getPropertyValue( sal_Int32 nHandle ) const; + + sal_Int32 getPropertyState( sal_Int32 nHandle ) const; + void setPropertyState( sal_Int32 nHandle, sal_Int32 nState ); + +private: + bool findProperty( sal_Int32 nHandle, PropertyMapIter& rIter ); + bool findProperty( sal_Int32 nHandle, PropertyMapConstIter& rIter ) const; + +private: + PropertyMap maPropertyMap; +}; + +} + +#endif // _SD_STLPROPERTYSET_HXX diff --git a/sd/source/ui/animations/SlideTransitionPane.cxx b/sd/source/ui/animations/SlideTransitionPane.cxx new file mode 100755 index 000000000000..82b6a47c3735 --- /dev/null +++ b/sd/source/ui/animations/SlideTransitionPane.cxx @@ -0,0 +1,1321 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <com/sun/star/animations/XAnimationNode.hpp> + +#include "SlideTransitionPane.hxx" +#include "SlideTransitionPane.hrc" +#include "CustomAnimation.hrc" + +#include "TransitionPreset.hxx" +#include "sdresid.hxx" +#include "ViewShellBase.hxx" +#include "DrawDocShell.hxx" +#include "SlideSorterViewShell.hxx" +#include "drawdoc.hxx" +#include "filedlg.hxx" +#include "strings.hrc" +#include "DrawController.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> + +#ifndef _SVT_CONTROLDIMS_HRC_ +#include <svtools/controldims.hrc> +#endif +#include <svx/gallery.hxx> +#include <unotools/pathoptions.hxx> +#include <vcl/msgbox.hxx> +#include <tools/urlobj.hxx> +#include "DrawViewShell.hxx" +#include "slideshow.hxx" +#include "drawview.hxx" +#include "sdundogr.hxx" +#include "undoanim.hxx" +#include "optsitem.hxx" +#include "sddll.hxx" +#include "framework/FrameworkHelper.hxx" + +#include "DialogListBox.hxx" + +#include <algorithm> +#include <memory> + + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::rtl::OUString; +using ::com::sun::star::uno::RuntimeException; + +using ::sd::framework::FrameworkHelper; + +// ____________________________ +// +// ::sd::impl::TransitionEffect +// ____________________________ + +namespace sd +{ +namespace impl +{ +struct TransitionEffect +{ + TransitionEffect() : + mnType( 0 ), + mnSubType( 0 ), + mbDirection( sal_True ), + mnFadeColor( 0 ) + { + init(); + } + explicit TransitionEffect( const ::sd::TransitionPreset & rPreset ) : + mnType( rPreset.getTransition()), + mnSubType( rPreset.getSubtype()), + mbDirection( rPreset.getDirection()), + mnFadeColor( rPreset.getFadeColor()) + { + init(); + } + explicit TransitionEffect( sal_Int16 nType, sal_Int16 nSubType, + sal_Bool bDirection, sal_Int32 nFadeColor ) : + mnType( nType), + mnSubType( nSubType ), + mbDirection( bDirection ), + mnFadeColor( nFadeColor ) + { + init(); + } + explicit TransitionEffect( const SdPage & rPage ) : + mnType( rPage.getTransitionType() ), + mnSubType( rPage.getTransitionSubtype() ), + mbDirection( rPage.getTransitionDirection() ), + mnFadeColor( rPage.getTransitionFadeColor() ) + { + init(); + + mfDuration = rPage.getTransitionDuration(); + mnTime = rPage.GetTime(); + mePresChange = rPage.GetPresChange(); + mbSoundOn = rPage.IsSoundOn(); + maSound = rPage.GetSoundFile(); + mbLoopSound = rPage.IsLoopSound(); + mbStopSound = rPage.IsStopSound(); + } + + void init() + { + mfDuration = 2.0; + mnTime = 0; + mePresChange = PRESCHANGE_MANUAL; + mbSoundOn = sal_False; + mbLoopSound = sal_False; + mbStopSound = sal_False; + + mbEffectAmbiguous = false; + mbDurationAmbiguous = false; + mbTimeAmbiguous = false; + mbPresChangeAmbiguous = false; + mbSoundAmbiguous = false; + mbLoopSoundAmbiguous = false; + } + + void setAllAmbiguous() + { + mbEffectAmbiguous = true; + mbDurationAmbiguous = true; + mbTimeAmbiguous = true; + mbPresChangeAmbiguous = true; + mbSoundAmbiguous = true; + mbLoopSoundAmbiguous = true; + } + + bool operator == ( const ::sd::TransitionPreset & rPreset ) const + { + return + (mnType == rPreset.getTransition()) && + (mnSubType == rPreset.getSubtype()) && + (mbDirection == rPreset.getDirection()) && + (mnFadeColor == rPreset.getFadeColor()); + } + + void applyTo( SdPage & rOutPage ) const + { + if( ! mbEffectAmbiguous ) + { + rOutPage.setTransitionType( mnType ); + rOutPage.setTransitionSubtype( mnSubType ); + rOutPage.setTransitionDirection( mbDirection ); + rOutPage.setTransitionFadeColor( mnFadeColor ); + } + + if( ! mbDurationAmbiguous ) + rOutPage.setTransitionDuration( mfDuration ); + if( ! mbTimeAmbiguous ) + rOutPage.SetTime( mnTime ); + if( ! mbPresChangeAmbiguous ) + rOutPage.SetPresChange( mePresChange ); + if( ! mbSoundAmbiguous ) + { + if( mbStopSound ) + { + rOutPage.SetStopSound( sal_True ); + rOutPage.SetSound( sal_False ); + } + else + { + rOutPage.SetStopSound( sal_False ); + rOutPage.SetSound( mbSoundOn ); + rOutPage.SetSoundFile( maSound ); + } + } + if( ! mbLoopSoundAmbiguous ) + rOutPage.SetLoopSound( mbLoopSound ); + } + + void compareWith( const SdPage & rPage ) + { + TransitionEffect aOtherEffect( rPage ); + mbEffectAmbiguous = mbEffectAmbiguous || aOtherEffect.mbEffectAmbiguous + || (mnType != aOtherEffect.mnType) + || (mnSubType != aOtherEffect.mnSubType) + || (mbDirection != aOtherEffect.mbDirection) + || (mnFadeColor != aOtherEffect.mnFadeColor); + + mbDurationAmbiguous = mbDurationAmbiguous || aOtherEffect.mbDurationAmbiguous || mfDuration != aOtherEffect.mfDuration; + mbTimeAmbiguous = mbTimeAmbiguous || aOtherEffect.mbTimeAmbiguous || mnTime != aOtherEffect.mnTime; + mbPresChangeAmbiguous = mbPresChangeAmbiguous || aOtherEffect.mbPresChangeAmbiguous || mePresChange != aOtherEffect.mePresChange; + mbSoundAmbiguous = mbSoundAmbiguous || aOtherEffect.mbSoundAmbiguous || mbSoundOn != aOtherEffect.mbSoundOn; + (!mbStopSound && !aOtherEffect.mbStopSound && maSound != aOtherEffect.maSound) || (mbStopSound != aOtherEffect.mbStopSound); + mbLoopSoundAmbiguous = mbLoopSoundAmbiguous || aOtherEffect.mbLoopSoundAmbiguous || mbLoopSound != aOtherEffect.mbLoopSound; + } + + // effect + sal_Int16 mnType; + sal_Int16 mnSubType; + sal_Bool mbDirection; + sal_Int32 mnFadeColor; + + // other settings + double mfDuration; + sal_uLong mnTime; + PresChange mePresChange; + sal_Bool mbSoundOn; + String maSound; + bool mbLoopSound; + bool mbStopSound; + + bool mbEffectAmbiguous; + bool mbDurationAmbiguous; + bool mbTimeAmbiguous; + bool mbPresChangeAmbiguous; + bool mbSoundAmbiguous; + bool mbLoopSoundAmbiguous; +}; + +} // namespace impl +} // namespace sd + +// ______________________ +// +// Local Helper Functions +// ______________________ + +namespace +{ + +void lcl_ApplyToPages( + const ::sd::slidesorter::SharedPageSelection& rpPages, + const ::sd::impl::TransitionEffect & rEffect ) +{ + ::std::vector< SdPage * >::const_iterator aIt( rpPages->begin()); + const ::std::vector< SdPage * >::const_iterator aEndIt( rpPages->end()); + for( ; aIt != aEndIt; ++aIt ) + { + rEffect.applyTo( *(*aIt) ); + } +} + +void lcl_CreateUndoForPages( + const ::sd::slidesorter::SharedPageSelection& rpPages, + ::sd::ViewShellBase& rBase ) +{ + ::sd::DrawDocShell* pDocSh = rBase.GetDocShell(); + ::svl::IUndoManager* pManager = pDocSh->GetUndoManager(); + SdDrawDocument* pDoc = pDocSh->GetDoc(); + if( pManager && pDocSh && pDoc ) + { + String aComment( SdResId(STR_UNDO_SLIDE_PARAMS) ); + pManager->EnterListAction(aComment, aComment); + SdUndoGroup* pUndoGroup = new SdUndoGroup( pDoc ); + pUndoGroup->SetComment( aComment ); + + ::std::vector< SdPage * >::const_iterator aIt( rpPages->begin()); + const ::std::vector< SdPage * >::const_iterator aEndIt( rpPages->end()); + for( ; aIt != aEndIt; ++aIt ) + { + pUndoGroup->AddAction( new sd::UndoTransition( pDoc, (*aIt) ) ); + } + + pManager->AddUndoAction( pUndoGroup ); + pManager->LeaveListAction(); + } +} + +sal_uInt16 lcl_getTransitionEffectIndex( + SdDrawDocument * pDoc, + const ::sd::impl::TransitionEffect & rTransition ) +{ + // first entry: "<none>" + sal_uInt16 nResultIndex = LISTBOX_ENTRY_NOTFOUND; + + if( pDoc ) + { + sal_uInt16 nCurrentIndex = 0; + const ::sd::TransitionPresetList & rPresetList = ::sd::TransitionPreset::getTransitionPresetList(); + ::sd::TransitionPresetList::const_iterator aIt( rPresetList.begin()); + const ::sd::TransitionPresetList::const_iterator aEndIt( rPresetList.end()); + for( ; aIt != aEndIt; ++aIt, ++nCurrentIndex ) + { + if( rTransition.operator==( *(*aIt) )) + { + nResultIndex = nCurrentIndex; + break; + } + } + } + + return nResultIndex; +} + +::sd::TransitionPresetPtr lcl_getTransitionPresetByUIName( + SdDrawDocument * pDoc, + const OUString & rUIName ) +{ + ::sd::TransitionPresetPtr pResult; + if( pDoc ) + { + const ::sd::TransitionPresetList& rPresetList = ::sd::TransitionPreset::getTransitionPresetList(); + ::sd::TransitionPresetList::const_iterator aIter( rPresetList.begin() ); + const ::sd::TransitionPresetList::const_iterator aEnd( rPresetList.end() ); + for( ; aIter != aEnd; ++aIter ) + { + if( (*aIter)->getUIName().equals( rUIName )) + { + pResult = *aIter; + break; + } + } + } + + return pResult; +} + +struct lcl_EqualsSoundFileName : public ::std::unary_function< String, bool > +{ + explicit lcl_EqualsSoundFileName( const String & rStr ) : + maStr( rStr ) + {} + + bool operator() ( const String & rStr ) const + { + // note: formerly this was a case insensitive search for all + // platforms. It seems more sensible to do this platform-dependent +#if defined( WNT ) + return maStr.EqualsIgnoreCaseAscii( rStr ); +#else + return maStr.Equals( rStr ); +#endif + } + +private: + String maStr; +}; + +// returns -1 if no object was found +bool lcl_findSoundInList( const ::std::vector< String > & rSoundList, + const String & rFileName, + ::std::vector< String >::size_type & rOutPosition ) +{ + ::std::vector< String >::const_iterator aIt = + ::std::find_if( rSoundList.begin(), rSoundList.end(), + lcl_EqualsSoundFileName( rFileName )); + if( aIt != rSoundList.end()) + { + rOutPosition = ::std::distance( rSoundList.begin(), aIt ); + return true; + } + + return false; +} + +String lcl_getSoundFileURL( + const ::std::vector< String > & rSoundList, + const ListBox & rListBox ) +{ + String aResult; + + if( rListBox.GetSelectEntryCount() > 0 ) + { + sal_uInt16 nPos = rListBox.GetSelectEntryPos(); + // the first three entries are no actual sounds + if( nPos >= 3 ) + { + DBG_ASSERT( (sal_uInt32)(rListBox.GetEntryCount() - 3) == rSoundList.size(), + "Sound list-box is not synchronized to sound list" ); + nPos -= 3; + if( rSoundList.size() > nPos ) + aResult = rSoundList[ nPos ]; + } + } + + return aResult; +} + +struct lcl_AppendSoundToListBox : public ::std::unary_function< String, void > +{ + lcl_AppendSoundToListBox( ListBox & rListBox ) : + mrListBox( rListBox ) + {} + + void operator() ( const String & rString ) const + { + INetURLObject aURL( rString ); + mrListBox.InsertEntry( aURL.GetBase(), LISTBOX_APPEND ); + } + +private: + ListBox & mrListBox; +}; + +void lcl_FillSoundListBox( + const ::std::vector< String > & rSoundList, + ListBox & rOutListBox ) +{ + sal_uInt16 nCount = rOutListBox.GetEntryCount(); + + // keep first three entries + for( sal_uInt16 i=nCount - 1; i>=3; --i ) + rOutListBox.RemoveEntry( i ); + + ::std::for_each( rSoundList.begin(), rSoundList.end(), + lcl_AppendSoundToListBox( rOutListBox )); +} + +} // anonymous namespace + +namespace sd +{ + +// ___________________ +// +// SlideTransitionPane +// ___________________ + +SlideTransitionPane::SlideTransitionPane( + ::Window * pParent, + ViewShellBase & rBase, + const Size& rMinSize, + SdDrawDocument* pDoc ) : + Control( pParent, SdResId( DLG_SLIDE_TRANSITION_PANE ) ), + + mrBase( rBase ), + mpDrawDoc( pDoc ), + maMinSize( rMinSize ), + maFL_APPLY_TRANSITION( this, SdResId( FL_APPLY_TRANSITION ) ), + maLB_SLIDE_TRANSITIONS( this, SdResId( LB_SLIDE_TRANSITIONS ) ), + maFL_MODIFY_TRANSITION( this, SdResId( FL_MODIFY_TRANSITION ) ), + maFT_SPEED( this, SdResId( FT_SPEED ) ), + maLB_SPEED( this, SdResId( LB_SPEED ) ), + maFT_SOUND( this, SdResId( FT_SOUND ) ), + maLB_SOUND( this, SdResId( LB_SOUND ) ), + maCB_LOOP_SOUND( this, SdResId( CB_LOOP_SOUND ) ), + maFL_ADVANCE_SLIDE( this, SdResId( FL_ADVANCE_SLIDE ) ), + maRB_ADVANCE_ON_MOUSE( this, SdResId( RB_ADVANCE_ON_MOUSE ) ), + maRB_ADVANCE_AUTO( this, SdResId( RB_ADVANCE_AUTO ) ), + maMF_ADVANCE_AUTO_AFTER( this, SdResId( MF_ADVANCE_AUTO_AFTER ) ), + maFL_EMPTY1( this, SdResId( FL_EMPTY1 ) ), + maPB_APPLY_TO_ALL( this, SdResId( PB_APPLY_TO_ALL ) ), + maPB_PLAY( this, SdResId( PB_PLAY ) ), + maPB_SLIDE_SHOW( this, SdResId( PB_SLIDE_SHOW ) ), + maFL_EMPTY2( this, SdResId( FL_EMPTY2 ) ), + maCB_AUTO_PREVIEW( this, SdResId( CB_AUTO_PREVIEW ) ), + + maSTR_NO_TRANSITION( SdResId( STR_NO_TRANSITION ) ), + mbHasSelection( false ), + mbUpdatingControls( false ), + mbIsMainViewChangePending( false ), + maLateInitTimer() +{ + // use no resource ids from here on + FreeResource(); + + // use bold font for group headings (same font for all fixed lines): + Font font( maFL_APPLY_TRANSITION.GetFont() ); + font.SetWeight( WEIGHT_BOLD ); + maFL_APPLY_TRANSITION.SetFont( font ); + maFL_MODIFY_TRANSITION.SetFont( font ); + maFL_ADVANCE_SLIDE.SetFont( font ); + + if( pDoc ) + mxModel.set( pDoc->getUnoModel(), uno::UNO_QUERY ); + // TODO: get correct view + if( mxModel.is()) + mxView.set( mxModel->getCurrentController(), uno::UNO_QUERY ); + + // fill list box of slide transitions + maLB_SLIDE_TRANSITIONS.InsertEntry( maSTR_NO_TRANSITION ); + + // set defaults + maCB_AUTO_PREVIEW.Check(); // automatic preview on + + // update control states before adding handlers + updateLayout(); + // updateSoundList(); + updateControls(); + + // set handlers + maPB_APPLY_TO_ALL.SetClickHdl( LINK( this, SlideTransitionPane, ApplyToAllButtonClicked )); + maPB_PLAY.SetClickHdl( LINK( this, SlideTransitionPane, PlayButtonClicked )); + maPB_SLIDE_SHOW.SetClickHdl( LINK( this, SlideTransitionPane, SlideShowButtonClicked )); + + maLB_SLIDE_TRANSITIONS.SetSelectHdl( LINK( this, SlideTransitionPane, TransitionSelected )); + + maLB_SPEED.SetSelectHdl( LINK( this, SlideTransitionPane, SpeedListBoxSelected )); + maLB_SOUND.SetSelectHdl( LINK( this, SlideTransitionPane, SoundListBoxSelected )); + maCB_LOOP_SOUND.SetClickHdl( LINK( this, SlideTransitionPane, LoopSoundBoxChecked )); + + maRB_ADVANCE_ON_MOUSE.SetToggleHdl( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled )); + maRB_ADVANCE_AUTO.SetToggleHdl( LINK( this, SlideTransitionPane, AdvanceSlideRadioButtonToggled )); + maMF_ADVANCE_AUTO_AFTER.SetModifyHdl( LINK( this, SlideTransitionPane, AdvanceTimeModified )); + maCB_AUTO_PREVIEW.SetClickHdl( LINK( this, SlideTransitionPane, AutoPreviewClicked )); + addListener(); + + maLateInitTimer.SetTimeout(200); + maLateInitTimer.SetTimeoutHdl(LINK(this, SlideTransitionPane, LateInitCallback)); + maLateInitTimer.Start(); +} + +SlideTransitionPane::~SlideTransitionPane() +{ + maLateInitTimer.Stop(); + removeListener(); +} + +void SlideTransitionPane::Resize() +{ + updateLayout(); +} + +void SlideTransitionPane::onSelectionChanged() +{ + updateControls(); +} + +void SlideTransitionPane::onChangeCurrentPage() +{ + updateControls(); +} + +::sd::slidesorter::SharedPageSelection SlideTransitionPane::getSelectedPages (void) const +{ + ::sd::slidesorter::SlideSorterViewShell * pSlideSorterViewShell + = ::sd::slidesorter::SlideSorterViewShell::GetSlideSorter(mrBase); +// DBG_ASSERT( pSlideSorterViewShell, "No Slide-Sorter available" ); + ::boost::shared_ptr<sd::slidesorter::SlideSorterViewShell::PageSelection> pSelection; + + if( pSlideSorterViewShell ) + { + pSelection = pSlideSorterViewShell->GetPageSelection(); + } + else + { + pSelection.reset(new sd::slidesorter::SlideSorterViewShell::PageSelection()); + if( mxView.is() ) + { + SdPage* pPage = SdPage::getImplementation( mxView->getCurrentPage() ); + if( pPage ) + pSelection->push_back(pPage); + } + } + + return pSelection; +} + +void SlideTransitionPane::updateLayout() +{ + ::Size aPaneSize( GetSizePixel() ); + if( aPaneSize.Width() < maMinSize.Width() ) + aPaneSize.Width() = maMinSize.Width(); + + if( aPaneSize.Height() < maMinSize.Height() ) + aPaneSize.Height() = maMinSize.Height(); + + // start layouting elements from bottom to top. The remaining space is used + // for the topmost list box + ::Point aOffset( LogicToPixel( Point( 3, 3 ), MAP_APPFONT ) ); + long nOffsetX = aOffset.getX(); + long nOffsetY = aOffset.getY(); + long nOffsetBtnX = LogicToPixel( Point( 6, 1 ), MAP_APPFONT ).getX(); + + const long nMinCtrlWidth = LogicToPixel( ::Point( 32, 1 ), MAP_APPFONT ).getX(); + const long nTextIndent = LogicToPixel( ::Point( RSC_SP_CHK_TEXTINDENT, 1 ), MAP_APPFONT ).getX(); + + ::Point aUpperLeft( nOffsetX, aPaneSize.getHeight() - nOffsetY ); + long nMaxWidth = aPaneSize.getWidth() - 2 * nOffsetX; + + // auto preview check-box + ::Size aCtrlSize = maCB_AUTO_PREVIEW.GetSizePixel(); + aCtrlSize.setWidth( maCB_AUTO_PREVIEW.CalcMinimumSize( nMaxWidth ).getWidth()); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight()); + maCB_AUTO_PREVIEW.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + // fixed line above check-box + aCtrlSize = maFL_EMPTY2.GetSizePixel(); + aCtrlSize.setWidth( nMaxWidth ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight()); + maFL_EMPTY2.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + // buttons "Play" and "Slide Show" + long nPlayButtonWidth = maPB_PLAY.CalcMinimumSize().getWidth() + 2 * nOffsetBtnX; + long nSlideShowButtonWidth = maPB_SLIDE_SHOW.CalcMinimumSize().getWidth() + 2 * nOffsetBtnX; + + if( (nPlayButtonWidth + nSlideShowButtonWidth + nOffsetX) <= nMaxWidth ) + { + // place buttons side by side + aCtrlSize = maPB_PLAY.GetSizePixel(); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight()); + aCtrlSize.setWidth( nPlayButtonWidth ); + maPB_PLAY.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + aUpperLeft.setX( aUpperLeft.getX() + nPlayButtonWidth + nOffsetX ); + aCtrlSize.setWidth( nSlideShowButtonWidth ); + maPB_SLIDE_SHOW.SetPosSizePixel( aUpperLeft, aCtrlSize ); + aUpperLeft.setX( nOffsetX ); + } + else + { + // place buttons on top of each other + aCtrlSize = maPB_SLIDE_SHOW.GetSizePixel(); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight()); + aCtrlSize.setWidth( nSlideShowButtonWidth ); + maPB_SLIDE_SHOW.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + aCtrlSize = maPB_PLAY.GetSizePixel(); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + aCtrlSize.setWidth( nPlayButtonWidth ); + maPB_PLAY.SetPosSizePixel( aUpperLeft, aCtrlSize ); + } + + // "Apply to All Slides" button + aCtrlSize = maPB_APPLY_TO_ALL.GetSizePixel(); + aCtrlSize.setWidth( maPB_APPLY_TO_ALL.CalcMinimumSize( nMaxWidth ).getWidth() + 2 * nOffsetBtnX ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + maPB_APPLY_TO_ALL.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + // fixed line above "Apply to All Slides" button + aCtrlSize = maFL_EMPTY1.GetSizePixel(); + aCtrlSize.setWidth( nMaxWidth ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight()); + maFL_EMPTY1.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + // advance automatically after ... seconds + long nItemWidth = maRB_ADVANCE_AUTO.CalcMinimumSize().getWidth(); + + if( (nItemWidth + nMinCtrlWidth + nOffsetX) <= nMaxWidth ) + { + long nBase = aUpperLeft.getY(); + + // place controls side by side + aCtrlSize = maRB_ADVANCE_AUTO.GetSizePixel(); + aUpperLeft.setY( nBase - aCtrlSize.getHeight()); + aCtrlSize.setWidth( nItemWidth ); + maRB_ADVANCE_AUTO.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + aCtrlSize = maMF_ADVANCE_AUTO_AFTER.GetSizePixel(); + aUpperLeft.setY( nBase - aCtrlSize.getHeight() ); + aUpperLeft.setX( aUpperLeft.getX() + nItemWidth + nOffsetX ); + aCtrlSize.setWidth( nMinCtrlWidth ); + maMF_ADVANCE_AUTO_AFTER.SetPosSizePixel( aUpperLeft, aCtrlSize ); + aUpperLeft.setX( nOffsetX ); + } + else + { + // place controls on top of each other + aCtrlSize = maMF_ADVANCE_AUTO_AFTER.GetSizePixel(); + aUpperLeft.setX( nOffsetX + nTextIndent ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight()); + aCtrlSize.setWidth( nMinCtrlWidth ); + maMF_ADVANCE_AUTO_AFTER.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + aCtrlSize = maRB_ADVANCE_AUTO.GetSizePixel(); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + aUpperLeft.setX( nOffsetX ); + aCtrlSize.setWidth( nItemWidth ); + maRB_ADVANCE_AUTO.SetPosSizePixel( aUpperLeft, aCtrlSize ); + aUpperLeft.setX( nOffsetX ); + } + + // check box "On mouse click" + aCtrlSize = maRB_ADVANCE_ON_MOUSE.GetSizePixel(); + aCtrlSize.setWidth( nMaxWidth ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + maRB_ADVANCE_ON_MOUSE.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + // fixed line "Advance slide" + aCtrlSize = maFL_ADVANCE_SLIDE.GetSizePixel(); + aCtrlSize.setWidth( nMaxWidth ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + maFL_ADVANCE_SLIDE.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + // check box "Loop until next sound" + long nFTSpeedWidth = maFT_SPEED.CalcMinimumSize().getWidth() + 2 * nOffsetX; + long nFTSoundWidth = maFT_SOUND.CalcMinimumSize().getWidth() + 2 * nOffsetX; + long nIndent = ::std::max( nFTSoundWidth, nFTSpeedWidth ); + + bool bStack = ( (nIndent + nMinCtrlWidth + nOffsetX) > nMaxWidth ); + + if( bStack ) + nIndent = nTextIndent; + + aCtrlSize = maCB_LOOP_SOUND.GetSizePixel(); + aCtrlSize.setWidth( nMaxWidth - nIndent ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + aUpperLeft.setX( nIndent ); + maCB_LOOP_SOUND.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + aCtrlSize = maLB_SOUND.GetSizePixel(); + aCtrlSize.setWidth( ::std::max( nMaxWidth - nIndent, nMinCtrlWidth ) ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + maLB_SOUND.SetPosSizePixel( aUpperLeft, aCtrlSize ); + maLB_SOUND.SetDropDownLineCount( 8 ); + aUpperLeft.setX( nOffsetX ); + + aCtrlSize = maFT_SOUND.GetSizePixel(); + if( bStack ) + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight()); + aCtrlSize.setWidth( nFTSoundWidth ); + maFT_SOUND.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + aUpperLeft.setX( nIndent ); + aCtrlSize = maLB_SPEED.GetSizePixel(); + aCtrlSize.setWidth( ::std::max( nMaxWidth - nIndent, nMinCtrlWidth ) ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + maLB_SPEED.SetPosSizePixel( aUpperLeft, aCtrlSize ); + maLB_SPEED.SetDropDownLineCount( 3 ); + aUpperLeft.setX( nOffsetX ); + + aCtrlSize = maFT_SPEED.GetSizePixel(); + if( bStack ) + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight()); + aCtrlSize.setWidth( nFTSpeedWidth ); + maFT_SPEED.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + // fixed line "Modify Transition" + aCtrlSize = maFL_MODIFY_TRANSITION.GetSizePixel(); + aCtrlSize.setWidth( nMaxWidth ); + aUpperLeft.setY( aUpperLeft.getY() - aCtrlSize.getHeight() - nOffsetY ); + maFL_MODIFY_TRANSITION.SetPosSizePixel( aUpperLeft, aCtrlSize ); + + // fixed line "Apply to selected slides" + aCtrlSize = maFL_APPLY_TRANSITION.GetSizePixel(); + aCtrlSize.setWidth( nMaxWidth ); + ::Point aUpperLeftCorner( nOffsetX, nOffsetY ); + maFL_APPLY_TRANSITION.SetPosSizePixel( aUpperLeftCorner, aCtrlSize ); + aUpperLeftCorner.setY( aUpperLeftCorner.getY() + aCtrlSize.getHeight() + nOffsetY ); + aUpperLeft.setY( aUpperLeft.getY() - nOffsetY ); + + // list box slide transitions + aCtrlSize.setWidth( nMaxWidth ); + aCtrlSize.setHeight( aUpperLeft.getY() - aUpperLeftCorner.getY() ); + maLB_SLIDE_TRANSITIONS.SetPosSizePixel( aUpperLeftCorner, aCtrlSize ); +} + +void SlideTransitionPane::updateControls() +{ + ::sd::slidesorter::SharedPageSelection pSelectedPages(getSelectedPages()); + if( pSelectedPages->empty()) + { + mbHasSelection = false; + return; + } + mbHasSelection = true; + + DBG_ASSERT( ! mbUpdatingControls, "Multiple Control Updates" ); + mbUpdatingControls = true; + + // get model data for first page + SdPage * pFirstPage = pSelectedPages->front(); + DBG_ASSERT( pFirstPage, "Invalid Page" ); + + impl::TransitionEffect aEffect( *pFirstPage ); + + // merge with other pages + ::sd::slidesorter::SlideSorterViewShell::PageSelection::const_iterator aIt( + pSelectedPages->begin()); + ::sd::slidesorter::SlideSorterViewShell::PageSelection::const_iterator aEndIt( + pSelectedPages->end()); + + // start with second page (note aIt != aEndIt, because ! aSelectedPages.empty()) + for( ++aIt ;aIt != aEndIt; ++aIt ) + { + if( *aIt ) + aEffect.compareWith( *(*aIt) ); + } + + // detect current slide effect + if( aEffect.mbEffectAmbiguous ) + maLB_SLIDE_TRANSITIONS.SetNoSelection(); + else + { + // ToDo: That 0 is "no transition" is documented nowhere except in the + // CTOR of sdpage + if( aEffect.mnType == 0 ) + maLB_SLIDE_TRANSITIONS.SelectEntryPos( 0 ); + else + { + sal_uInt16 nEntry = lcl_getTransitionEffectIndex( mpDrawDoc, aEffect ); + if( nEntry == LISTBOX_ENTRY_NOTFOUND ) + maLB_SLIDE_TRANSITIONS.SetNoSelection(); + else + { + // first entry in list is "none", so add 1 after translation + if( m_aPresetIndexes.find( nEntry ) != m_aPresetIndexes.end()) + maLB_SLIDE_TRANSITIONS.SelectEntryPos( m_aPresetIndexes[ nEntry ] + 1 ); + else + maLB_SLIDE_TRANSITIONS.SetNoSelection(); + } + } + } + + if( aEffect.mbDurationAmbiguous ) + maLB_SPEED.SetNoSelection(); + else + maLB_SPEED.SelectEntryPos( + (aEffect.mfDuration > 2.0 ) + ? 0 : (aEffect.mfDuration < 2.0) + ? 2 : 1 ); // else FADE_SPEED_FAST + + if( aEffect.mbSoundAmbiguous ) + { + maLB_SOUND.SetNoSelection(); + maCurrentSoundFile.Erase(); + } + else + { + maCurrentSoundFile.Erase(); + if( aEffect.mbStopSound ) + { + maLB_SOUND.SelectEntryPos( 1 ); + } + else if( aEffect.mbSoundOn && aEffect.maSound.Len() > 0 ) + { + tSoundListType::size_type nPos = 0; + if( lcl_findSoundInList( maSoundList, aEffect.maSound, nPos )) + { + // skip first three entries + maLB_SOUND.SelectEntryPos( (sal_uInt16)nPos + 3 ); + maCurrentSoundFile = aEffect.maSound; + } + } + else + { + maLB_SOUND.SelectEntryPos( 0 ); + } + } + + if( aEffect.mbLoopSoundAmbiguous ) + { + maCB_LOOP_SOUND.SetState( STATE_DONTKNOW ); + } + else + { + maCB_LOOP_SOUND.Check( aEffect.mbLoopSound ); + } + + if( aEffect.mbPresChangeAmbiguous ) + { + maRB_ADVANCE_ON_MOUSE.Check( sal_False ); + maRB_ADVANCE_AUTO.Check( sal_False ); + } + else + { + maRB_ADVANCE_ON_MOUSE.Check( aEffect.mePresChange == PRESCHANGE_MANUAL ); + maRB_ADVANCE_AUTO.Check( aEffect.mePresChange == PRESCHANGE_AUTO ); + maMF_ADVANCE_AUTO_AFTER.SetValue( aEffect.mnTime ); + } + + SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS); + maCB_AUTO_PREVIEW.Check( pOptions->IsPreviewTransitions() == sal_True ); + + mbUpdatingControls = false; + + updateControlState(); +} + +void SlideTransitionPane::updateControlState() +{ + maLB_SLIDE_TRANSITIONS.Enable( mbHasSelection ); + maLB_SPEED.Enable( mbHasSelection ); + maLB_SOUND.Enable( mbHasSelection ); + maCB_LOOP_SOUND.Enable( mbHasSelection && (maLB_SOUND.GetSelectEntryPos() > 2)); + maRB_ADVANCE_ON_MOUSE.Enable( mbHasSelection ); + maRB_ADVANCE_AUTO.Enable( mbHasSelection ); + maMF_ADVANCE_AUTO_AFTER.Enable( mbHasSelection && maRB_ADVANCE_AUTO.IsChecked()); + + maPB_APPLY_TO_ALL.Enable( mbHasSelection ); + maPB_PLAY.Enable( mbHasSelection ); +// maPB_SLIDE_SHOW.Enable( sal_True ); + maCB_AUTO_PREVIEW.Enable( mbHasSelection ); +} + +void SlideTransitionPane::updateSoundList() +{ + List aSoundList; + + GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, aSoundList ); + GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, aSoundList ); + + sal_uInt32 nCount = aSoundList.Count(); + maSoundList.clear(); + maSoundList.reserve( nCount ); + for( sal_uInt32 i=0; i<nCount; ++i ) + { + String * pEntry = reinterpret_cast< String * >( aSoundList.GetObject( i )); + if( pEntry ) + { + // store copy of string in member list + maSoundList.push_back( *pEntry ); + // delete pointer in temporary List + delete pEntry; + } + } + + lcl_FillSoundListBox( maSoundList, maLB_SOUND ); +} + +void SlideTransitionPane::openSoundFileDialog() +{ + if( ! maLB_SOUND.IsEnabled()) + return; + + SdOpenSoundFileDialog aFileDialog; + + String aFile; + DBG_ASSERT( maLB_SOUND.GetSelectEntryPos() == 2, + "Dialog should only open when \"Other sound\" is selected" ); + aFile = SvtPathOptions().GetGraphicPath(); + + aFileDialog.SetPath( aFile ); + + bool bValidSoundFile( false ); + bool bQuitLoop( false ); + + while( ! bQuitLoop && + aFileDialog.Execute() == ERRCODE_NONE ) + { + aFile = aFileDialog.GetPath(); + tSoundListType::size_type nPos = 0; + bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos ); + + if( bValidSoundFile ) + { + bQuitLoop = true; + } + else // not in sound list + { + // try to insert into gallery + if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile, SGA_FORMAT_SOUND ) ) + { + updateSoundList(); + bValidSoundFile = lcl_findSoundInList( maSoundList, aFile, nPos ); + DBG_ASSERT( bValidSoundFile, "Adding sound to gallery failed" ); + + bQuitLoop = true; + } + else + { + String aStrWarning(SdResId(STR_WARNING_NOSOUNDFILE)); + String 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); + + bValidSoundFile = false; + } + } + + if( bValidSoundFile ) + // skip first three entries in list + maLB_SOUND.SelectEntryPos( (sal_uInt16)nPos + 3 ); + } + + if( ! bValidSoundFile ) + { + if( maCurrentSoundFile.Len() > 0 ) + { + tSoundListType::size_type nPos = 0; + if( lcl_findSoundInList( maSoundList, maCurrentSoundFile, nPos )) + maLB_SOUND.SelectEntryPos( (sal_uInt16)nPos + 3 ); + else + maLB_SOUND.SelectEntryPos( 0 ); // NONE + } + else + maLB_SOUND.SelectEntryPos( 0 ); // NONE + } +} + +impl::TransitionEffect SlideTransitionPane::getTransitionEffectFromControls() const +{ + impl::TransitionEffect aResult; + aResult.setAllAmbiguous(); + + // check first (aResult might be overwritten) + if( maLB_SLIDE_TRANSITIONS.IsEnabled() && + maLB_SLIDE_TRANSITIONS.GetSelectEntryCount() > 0 ) + { + TransitionPresetPtr pPreset = lcl_getTransitionPresetByUIName( + mpDrawDoc, OUString( maLB_SLIDE_TRANSITIONS.GetSelectEntry())); + + if( pPreset.get()) + { + aResult = impl::TransitionEffect( *pPreset ); + aResult.setAllAmbiguous(); + } + else + { + aResult.mnType = 0; + } + aResult.mbEffectAmbiguous = false; + } + + // speed + if( maLB_SPEED.IsEnabled() && + maLB_SPEED.GetSelectEntryCount() > 0 ) + { + sal_uInt16 nPos = maLB_SPEED.GetSelectEntryPos(); + aResult.mfDuration = (nPos == 0) + ? 3.0 + : (nPos == 1) + ? 2.0 + : 1.0; // nPos == 2 + DBG_ASSERT( aResult.mfDuration != 1.0 || nPos == 2, "Invalid Listbox Entry" ); + + aResult.mbDurationAmbiguous = false; + } + + // slide-advance mode + if( maRB_ADVANCE_ON_MOUSE.IsEnabled() && maRB_ADVANCE_AUTO.IsEnabled() && + (maRB_ADVANCE_ON_MOUSE.IsChecked() || maRB_ADVANCE_AUTO.IsChecked())) + { + if( maRB_ADVANCE_ON_MOUSE.IsChecked()) + aResult.mePresChange = PRESCHANGE_MANUAL; + else + { + aResult.mePresChange = PRESCHANGE_AUTO; + if( maMF_ADVANCE_AUTO_AFTER.IsEnabled()) + { +// sal_uInt16 nDigits = maMF_ADVANCE_AUTO_AFTER.GetDecimalDigits(); + aResult.mnTime = static_cast<long>(maMF_ADVANCE_AUTO_AFTER.GetValue()); + // / static_cast< sal_uInt16 >( pow( 10.0, static_cast< double >( nDigits ))); + aResult.mbTimeAmbiguous = false; + } + } + + aResult.mbPresChangeAmbiguous = false; + } + + // sound + if( maLB_SOUND.IsEnabled()) + { + maCurrentSoundFile.Erase(); + if( maLB_SOUND.GetSelectEntryCount() > 0 ) + { + sal_uInt16 nPos = maLB_SOUND.GetSelectEntryPos(); + aResult.mbStopSound = nPos == 1; + aResult.mbSoundOn = nPos > 1; + if( aResult.mbStopSound ) + { + aResult.maSound = OUString(); + aResult.mbSoundAmbiguous = false; + } + else + { + aResult.maSound = lcl_getSoundFileURL( maSoundList, maLB_SOUND ); + aResult.mbSoundAmbiguous = false; + maCurrentSoundFile = aResult.maSound; + } + } + } + + // sound loop + if( maCB_LOOP_SOUND.IsEnabled() ) + { + aResult.mbLoopSound = maCB_LOOP_SOUND.IsChecked(); + aResult.mbLoopSoundAmbiguous = false; + } + + return aResult; +} + +void SlideTransitionPane::applyToSelectedPages() +{ + if( ! mbUpdatingControls ) + { + ::sd::slidesorter::SharedPageSelection pSelectedPages( getSelectedPages()); + if( ! pSelectedPages->empty()) + { + lcl_CreateUndoForPages( pSelectedPages, mrBase ); + lcl_ApplyToPages( pSelectedPages, getTransitionEffectFromControls() ); + mrBase.GetDocShell()->SetModified(); + } + if( maCB_AUTO_PREVIEW.IsEnabled() && + maCB_AUTO_PREVIEW.IsChecked()) + { + playCurrentEffect(); + } + } +} + +void SlideTransitionPane::playCurrentEffect() +{ + if( mxView.is() ) + { + + Reference< ::com::sun::star::animations::XAnimationNode > xNode; + SlideShow::StartPreview( mrBase, mxView->getCurrentPage(), xNode ); + } +} + +void SlideTransitionPane::addListener() +{ + Link aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) ); + mrBase.GetEventMultiplexer()->AddEventListener ( + aLink, + tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION + | tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION + | tools::EventMultiplexerEvent::EID_CURRENT_PAGE + | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED + | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED + | tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED); +} + +void SlideTransitionPane::removeListener() +{ + Link aLink( LINK(this,SlideTransitionPane,EventMultiplexerListener) ); + mrBase.GetEventMultiplexer()->RemoveEventListener( aLink ); +} + +IMPL_LINK(SlideTransitionPane,EventMultiplexerListener, + tools::EventMultiplexerEvent*,pEvent) +{ + switch (pEvent->meEventId) + { + case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION: + onSelectionChanged(); + break; + + case tools::EventMultiplexerEvent::EID_CURRENT_PAGE: + case tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION: + onChangeCurrentPage(); + break; + + case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED: + mxView = Reference<drawing::XDrawView>(); + onSelectionChanged(); + onChangeCurrentPage(); + break; + + case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED: + mbIsMainViewChangePending = true; + break; + + case tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED: + if (mbIsMainViewChangePending) + { + mbIsMainViewChangePending = false; + + // At this moment the controller may not yet been set at + // model or ViewShellBase. Take it from the view shell + // passed with the event. + if (mrBase.GetMainViewShell() != NULL) + { + mxView = Reference<drawing::XDrawView>::query(mrBase.GetController()); + onSelectionChanged(); + onChangeCurrentPage(); + } + } + break; + + default: + break; + } + return 0; +} + +IMPL_LINK( SlideTransitionPane, ApplyToAllButtonClicked, void *, EMPTYARG ) +{ + DBG_ASSERT( mpDrawDoc, "Invalid Draw Document!" ); + if( !mpDrawDoc ) + return 0; + + ::sd::slidesorter::SharedPageSelection pPages ( + new ::sd::slidesorter::SlideSorterViewShell::PageSelection()); + + sal_uInt16 nPageCount = mpDrawDoc->GetSdPageCount( PK_STANDARD ); + pPages->reserve( nPageCount ); + for( sal_uInt16 i=0; i<nPageCount; ++i ) + { + SdPage * pPage = mpDrawDoc->GetSdPage( i, PK_STANDARD ); + if( pPage ) + pPages->push_back( pPage ); + } + + if( ! pPages->empty()) + { + lcl_CreateUndoForPages( pPages, mrBase ); + lcl_ApplyToPages( pPages, getTransitionEffectFromControls() ); + } + + return 0; +} + + +IMPL_LINK( SlideTransitionPane, PlayButtonClicked, void *, EMPTYARG ) +{ + playCurrentEffect(); + return 0; +} + +IMPL_LINK( SlideTransitionPane, SlideShowButtonClicked, void *, EMPTYARG ) +{ + mrBase.StartPresentation(); + return 0; +} + +IMPL_LINK( SlideTransitionPane, TransitionSelected, void *, EMPTYARG ) +{ + applyToSelectedPages(); + return 0; +} + +IMPL_LINK( SlideTransitionPane, AdvanceSlideRadioButtonToggled, void *, EMPTYARG ) +{ + updateControlState(); + applyToSelectedPages(); + return 0; +} + +IMPL_LINK( SlideTransitionPane, AdvanceTimeModified, void *, EMPTYARG ) +{ + applyToSelectedPages(); + return 0; +} + +IMPL_LINK( SlideTransitionPane, SpeedListBoxSelected, void *, EMPTYARG ) +{ + applyToSelectedPages(); + return 0; +} + +IMPL_LINK( SlideTransitionPane, SoundListBoxSelected, void *, EMPTYARG ) +{ + if( maLB_SOUND.GetSelectEntryCount() ) + { + sal_uInt16 nPos = maLB_SOUND.GetSelectEntryPos(); + if( nPos == 2 ) + { + // other sound ... + openSoundFileDialog(); + } + } + updateControlState(); + applyToSelectedPages(); + return 0; +} + +IMPL_LINK( SlideTransitionPane, LoopSoundBoxChecked, void *, EMPTYARG ) +{ + applyToSelectedPages(); + return 0; +} + +IMPL_LINK( SlideTransitionPane, AutoPreviewClicked, void *, EMPTYARG ) +{ + SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS); + pOptions->SetPreviewTransitions( maCB_AUTO_PREVIEW.IsChecked() ? sal_True : sal_False ); + return 0; +} + +IMPL_LINK( SlideTransitionPane, LateInitCallback, Timer*, EMPTYARG ) +{ + const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList(); + TransitionPresetList::const_iterator aIter( rPresetList.begin() ); + const TransitionPresetList::const_iterator aEnd( rPresetList.end() ); + sal_uInt16 nIndex = 0; + ::std::size_t nUIIndex = 0; + while( aIter != aEnd ) + { + TransitionPresetPtr pPreset = (*aIter++); + const OUString aUIName( pPreset->getUIName() ); + if( aUIName.getLength() ) + { + maLB_SLIDE_TRANSITIONS.InsertEntry( aUIName ); + m_aPresetIndexes[ nIndex ] = (sal_uInt16)nUIIndex; + ++nUIIndex; + } + ++nIndex; + } + + updateSoundList(); + updateControls(); + + return 0; +} + +::Window * createSlideTransitionPanel( ::Window* pParent, ViewShellBase& rBase ) +{ + DialogListBox* pWindow = 0; + + DrawDocShell* pDocSh = rBase.GetDocShell(); + if( pDocSh ) + { + pWindow = new DialogListBox( pParent, WB_CLIPCHILDREN|WB_TABSTOP|WB_AUTOHSCROLL ); + + Size aMinSize( pWindow->LogicToPixel( Size( 72, 216 ), MAP_APPFONT ) ); + ::Window* pPaneWindow = new SlideTransitionPane( pWindow, rBase, aMinSize, pDocSh->GetDoc() ); + pWindow->SetChildWindow( pPaneWindow, aMinSize ); + pWindow->SetText( pPaneWindow->GetText() ); + } + + return pWindow; +} + + +} // namespace sd diff --git a/sd/source/ui/animations/SlideTransitionPane.hrc b/sd/source/ui/animations/SlideTransitionPane.hrc new file mode 100644 index 000000000000..cce878a547d2 --- /dev/null +++ b/sd/source/ui/animations/SlideTransitionPane.hrc @@ -0,0 +1,68 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_SLIDETRANSITIONPANE_HRC +#define _SD_SLIDETRANSITIONPANE_HRC + +#define FL_APPLY_TRANSITION 1 +// spec: 1 +#define LB_SLIDE_TRANSITIONS 2 + +#define FL_MODIFY_TRANSITION 3 +#define FT_SPEED 4 +// spec: 2 +#define LB_SPEED 5 +#define FT_SOUND 6 +// spec: 3 +#define LB_SOUND 7 +// spec: 4 +#define CB_LOOP_SOUND 8 + +#define FL_ADVANCE_SLIDE 9 +// spec: 5 +#define RB_ADVANCE_ON_MOUSE 10 +// spec: 6 +#define RB_ADVANCE_AUTO 11 +// spec: 7 +#define MF_ADVANCE_AUTO_AFTER 12 + +#define FL_EMPTY1 13 +// spec: 8 +#define PB_APPLY_TO_ALL 14 +// spec: 9 +#define PB_PLAY 15 +// spec: 10 +#define PB_SLIDE_SHOW 16 + +#define FL_EMPTY2 17 +// spec: 11 +#define CB_AUTO_PREVIEW 18 + +#define STR_NO_TRANSITION 19 + + +#endif // _SD_SLIDETRANSITIONPANE_HRC diff --git a/sd/source/ui/animations/SlideTransitionPane.hxx b/sd/source/ui/animations/SlideTransitionPane.hxx new file mode 100644 index 000000000000..965f286ac40e --- /dev/null +++ b/sd/source/ui/animations/SlideTransitionPane.hxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SD_SLIDETRANSITIONPANE_HXX +#define SD_SLIDETRANSITIONPANE_HXX + +#include "EventMultiplexer.hxx" + +#include "SlideSorterViewShell.hxx" + +#include <vcl/ctrl.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/fixed.hxx> +#include <vcl/button.hxx> +#include <vcl/field.hxx> +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/frame/XModel.hpp> + +#include <vector> +#include <map> + +class SdDrawDocument; +class SdPage; + +namespace sd +{ + +class ViewShellBase; + +namespace impl +{ + struct TransitionEffect; +} + +class SlideTransitionPane : public Control +{ +public: + explicit SlideTransitionPane( + ::Window * pParent, + ViewShellBase & rBase, + const Size& rMinSize, + SdDrawDocument* pDoc ); + virtual ~SlideTransitionPane(); + + virtual void Resize(); + + void onSelectionChanged(); + void onChangeCurrentPage(); + +private: + void updateLayout(); + void updateControls(); + void updateControlState(); + + void updateSoundList(); + void openSoundFileDialog(); + + impl::TransitionEffect getTransitionEffectFromControls() const; + + void applyToSelectedPages(); + void playCurrentEffect(); + + void addListener(); + void removeListener(); + + ::sd::slidesorter::SharedPageSelection getSelectedPages (void) const; + + DECL_LINK( ApplyToAllButtonClicked, void * ); + DECL_LINK( PlayButtonClicked, void * ); + DECL_LINK( SlideShowButtonClicked, void * ); + DECL_LINK( AutoPreviewClicked, void * ); + + DECL_LINK( TransitionSelected, void * ); + DECL_LINK( AdvanceSlideRadioButtonToggled, void * ); + DECL_LINK( AdvanceTimeModified, void * ); + DECL_LINK( SpeedListBoxSelected, void * ); + DECL_LINK( SoundListBoxSelected, void * ); + DECL_LINK( LoopSoundBoxChecked, void * ); + DECL_LINK(EventMultiplexerListener, tools::EventMultiplexerEvent*); + DECL_LINK(LateInitCallback, Timer*); + +private: + ViewShellBase & mrBase; + SdDrawDocument * mpDrawDoc; + Size maMinSize; + + FixedLine maFL_APPLY_TRANSITION; + ListBox maLB_SLIDE_TRANSITIONS; + FixedLine maFL_MODIFY_TRANSITION; + FixedText maFT_SPEED; + ListBox maLB_SPEED; + FixedText maFT_SOUND; + ListBox maLB_SOUND; + CheckBox maCB_LOOP_SOUND; + FixedLine maFL_ADVANCE_SLIDE; + RadioButton maRB_ADVANCE_ON_MOUSE; + RadioButton maRB_ADVANCE_AUTO; + MetricField maMF_ADVANCE_AUTO_AFTER; + FixedLine maFL_EMPTY1; + PushButton maPB_APPLY_TO_ALL; + PushButton maPB_PLAY; + PushButton maPB_SLIDE_SHOW; + FixedLine maFL_EMPTY2; + CheckBox maCB_AUTO_PREVIEW; + + String maSTR_NO_TRANSITION; + + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawView > mxView; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxModel; + + bool mbHasSelection; + bool mbUpdatingControls; + bool mbIsMainViewChangePending; + + typedef ::std::vector< String > tSoundListType; + tSoundListType maSoundList; + mutable String maCurrentSoundFile; + + typedef ::std::map< sal_uInt16, sal_uInt16 > tPresetIndexesType; + tPresetIndexesType m_aPresetIndexes; + + Timer maLateInitTimer; +}; + +} // namespace sd + +// SD_SLIDETRANSITIONPANE_HXX +#endif diff --git a/sd/source/ui/animations/SlideTransitionPane.src b/sd/source/ui/animations/SlideTransitionPane.src new file mode 100644 index 000000000000..7cf1cec805d3 --- /dev/null +++ b/sd/source/ui/animations/SlideTransitionPane.src @@ -0,0 +1,220 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "CustomAnimation.hrc" +#include "SlideTransitionPane.hrc" +#include "helpids.h" + +#ifndef _SVT_CONTROLDIMS_HRC_ +#include <svtools/controldims.hrc> +#endif + +// Note: Sizes of 1 usually mean they are auto-calculated + +Control DLG_SLIDE_TRANSITION_PANE +{ + OutputSize = TRUE; + DialogControl = TRUE; + Size = MAP_APPFONT( 1, 1 ); + + Text [ en-US ] = "Slide Transition"; + + FixedLine FL_APPLY_TRANSITION + { + Size = MAP_APPFONT( 1, RSC_CD_FIXEDLINE_HEIGHT ); + Text [ en-US ] = "Apply to selected slides"; + }; + + ListBox LB_SLIDE_TRANSITIONS + { + HelpId = HID_SD_SLIDETRANSITIONPANE_LB_SLIDE_TRANSITIONS; + Border = TRUE ; + TabStop = TRUE ; + AutoHScroll = TRUE ; + + Size = MAP_APPFONT( 1, 1 ); + }; + + Fixedline FL_MODIFY_TRANSITION + { + Size = MAP_APPFONT( 1, RSC_CD_FIXEDLINE_HEIGHT ); + Text [ en-US ] = "Modify transition"; + }; + + FixedText FT_SPEED + { + Size = MAP_APPFONT( 1, RSC_CD_FIXEDTEXT_HEIGHT ); + Text [ en-US ] = "Speed"; + }; + + ListBox LB_SPEED + { + HelpId = HID_SD_SLIDETRANSITIONPANE_LB_SPEED; + Border = TRUE ; + DropDown = TRUE ; + TabStop = TRUE ; + + Size = MAP_APPFONT( 1, RSC_CD_DROPDOWN_HEIGHT ); + StringList [ en-US ] = + { + < "Slow" ; > ; + < "Medium" ; > ; + < "Fast" ; > ; + }; + }; + + FixedText FT_SOUND + { + Size = MAP_APPFONT( 1, RSC_CD_FIXEDTEXT_HEIGHT ); + Text [ en-US ] = "Sound"; + }; + + ListBox LB_SOUND + { + HelpId = HID_SD_SLIDETRANSITIONPANE_LB_SOUND; + Border = TRUE ; + DropDown = TRUE ; + TabStop = TRUE ; + + Size = MAP_APPFONT( 1, RSC_CD_DROPDOWN_HEIGHT ); + + StringList [ en-US ] = + { + < "<No Sound>" ; > ; + < "<Stop Previous Sound>" ; > ; + < "Other Sound..." ; > ; + }; + }; + + Checkbox CB_LOOP_SOUND + { + HelpId = HID_SD_SLIDETRANSITIONPANE_CB_LOOP_SOUND; + Size = MAP_APPFONT( 1, RSC_CD_CHECKBOX_HEIGHT ); + TabStop = TRUE ; + + Text [ en-US ] = "Loop until next sound"; + }; + + Fixedline FL_ADVANCE_SLIDE + { + Size = MAP_APPFONT( 1, RSC_CD_FIXEDLINE_HEIGHT ); + Text [ en-US ] = "Advance slide"; + }; + + RadioButton RB_ADVANCE_ON_MOUSE + { + HelpId = HID_SD_SLIDETRANSITIONPANE_RB_ADVANCE_ON_MOUSE; + Size = MAP_APPFONT( 1, RSC_CD_RADIOBUTTON_HEIGHT ); + TabStop = TRUE ; + + Text [ en-US ] = "On mouse click"; + }; + + RadioButton RB_ADVANCE_AUTO + { + HelpId = HID_SD_SLIDETRANSITIONPANE_RB_ADVANCE_AUTO; + Size = MAP_APPFONT( 1, RSC_CD_RADIOBUTTON_HEIGHT ); + TabStop = TRUE ; + + Text [ en-US ] = "Automatically after"; + }; + + MetricField MF_ADVANCE_AUTO_AFTER + { + HelpId = HID_SD_SLIDETRANSITIONPANE_MF_ADVANCE_AUTO_AFTER; + Size = MAP_APPFONT( 1, RSC_CD_TEXTBOX_HEIGHT ); + + Border = TRUE ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Minimum = 0 ; + Maximum = 999 ; + // decimal digits should be 1, but for now the model only supports whole seconds + DecimalDigits = 0 ; + // spin size (increment value) should be 5 if digits are 1 + SpinSize = 1 ; + + Unit = FUNIT_CUSTOM ; + CustomUnitText [ en-US ] = "sec"; + }; + + FixedLine FL_EMPTY1 + { + Size = MAP_APPFONT( 1, RSC_CD_FIXEDLINE_HEIGHT ); + }; + + PushButton PB_APPLY_TO_ALL + { + HelpId = HID_SD_SLIDETRANSITIONPANE_PB_APPLY_TO_ALL; + Size = MAP_APPFONT( 1, RSC_CD_PUSHBUTTON_HEIGHT ); + TabStop = TRUE ; + + Text [ en-US ] = "Apply to All Slides"; + }; + + + PushButton PB_PLAY + { + HelpId = HID_SD_SLIDETRANSITIONPANE_PB_PLAY; + Size = MAP_APPFONT( 1, RSC_CD_PUSHBUTTON_HEIGHT ); + TabStop = TRUE ; + + Text [ en-US ] = "Play"; + }; + + PushButton PB_SLIDE_SHOW + { + HelpId = HID_SD_SLIDETRANSITIONPANE_PB_SLIDE_SHOW; + Size = MAP_APPFONT( 1, RSC_CD_PUSHBUTTON_HEIGHT ); + TabStop = TRUE ; + + Text [ en-US ] = "Slide Show"; + }; + + FixedLine FL_EMPTY2 + { + Size = MAP_APPFONT( 1, RSC_CD_FIXEDLINE_HEIGHT ); + }; + + Checkbox CB_AUTO_PREVIEW + { + HelpId = HID_SD_SLIDETRANSITIONPANE_CB_AUTO_PREVIEW; + Size = MAP_APPFONT( 1, RSC_CD_CHECKBOX_HEIGHT ); + TabStop = TRUE ; + + Text [ en-US ] = "Automatic preview"; + }; + + // -------------------- + + String STR_NO_TRANSITION + { + Text [ en-US ] = "No Transition"; + }; +}; + diff --git a/sd/source/ui/animations/makefile.mk b/sd/source/ui/animations/makefile.mk new file mode 100755 index 000000000000..db010bf4ef23 --- /dev/null +++ b/sd/source/ui/animations/makefile.mk @@ -0,0 +1,65 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PROJECTPCH=sd +PROJECTPCHSOURCE=$(PRJ)$/util$/sd +PRJNAME=sd +TARGET=animui +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SRS1NAME=$(TARGET) +SRC1FILES =\ + CustomAnimationPane.src\ + CustomAnimationDialog.src\ + CustomAnimationCreateDialog.src\ + SlideTransitionPane.src\ + CustomAnimation.src + +SLOFILES = \ + $(SLO)$/CustomAnimationCreateDialog.obj\ + $(SLO)$/CustomAnimationDialog.obj\ + $(SLO)$/CustomAnimationPane.obj \ + $(SLO)$/CustomAnimationList.obj \ + $(SLO)$/DialogListBox.obj \ + $(SLO)$/SlideTransitionPane.obj \ + $(SLO)$/STLPropertySet.obj \ + $(SLO)$/motionpathtag.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + + diff --git a/sd/source/ui/animations/motionpathtag.cxx b/sd/source/ui/animations/motionpathtag.cxx new file mode 100755 index 000000000000..c6105919e645 --- /dev/null +++ b/sd/source/ui/animations/motionpathtag.cxx @@ -0,0 +1,1327 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + + +#include <com/sun/star/util/XChangesNotifier.hpp> + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +#include <sfx2/viewfrm.hxx> +#include <sfx2/dispatch.hxx> + +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <svx/sdr/overlay/overlaypolypolygon.hxx> +#include <svx/svdpagv.hxx> +#include <svx/sdrpagewindow.hxx> +#include <svx/sdrpaintwindow.hxx> +#include <svx/svdopath.hxx> +#include <svx/xlndsit.hxx> +#include <svx/xlnclit.hxx> +#include <svx/xlnstit.hxx> +#include <svx/xlnedit.hxx> +#include <svx/xlnstwit.hxx> +#include <svx/xlnedwit.hxx> +#include <svx/xlnstcit.hxx> +#include <svx/xlnedcit.hxx> +#include <svx/xlntrit.hxx> +#include <svx/svxids.hrc> +#include <svx/polypolygoneditor.hxx> +#include <svx/svddrgmt.hxx> + +#include "CustomAnimationPane.hxx" +#include "View.hxx" +#include "motionpathtag.hxx" +#include "sdpage.hxx" +#include "ViewShell.hxx" +#include "app.hrc" +#include "Window.hxx" + +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx> + +using ::rtl::OUString; +using ::sdr::PolyPolygonEditor; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::drawing; + +namespace sd +{ + +const sal_uInt32 SMART_TAG_HDL_NUM = SAL_MAX_UINT32; +static const int DRGPIX = 2; // Drag MinMove in Pixel + +// -------------------------------------------------------------------- + +class PathDragMove : public SdrDragMove +{ +private: + basegfx::B2DPolyPolygon maPathPolyPolygon; + +protected: + virtual void createSdrDragEntries(); + +public: + PathDragMove(SdrDragView& rNewView, + const rtl::Reference <MotionPathTag >& xTag, + const basegfx::B2DPolyPolygon& rPathPolyPolygon) + : SdrDragMove(rNewView), + maPathPolyPolygon(rPathPolyPolygon), + mxTag( xTag ) + {} + + PathDragMove(SdrDragView& rNewView, + const rtl::Reference <MotionPathTag >& xTag) + : SdrDragMove(rNewView), + maPathPolyPolygon(), + mxTag( xTag ) + {} + + virtual bool BeginSdrDrag(); + virtual bool EndSdrDrag(bool bCopy); + + rtl::Reference <MotionPathTag > mxTag; +}; + +void PathDragMove::createSdrDragEntries() +{ + // call parent + SdrDragMove::createSdrDragEntries(); + + if(maPathPolyPolygon.count()) + { + addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon)); + } +} + +bool PathDragMove::BeginSdrDrag() +{ + if( mxTag.is() ) + { + SdrPathObj* pPathObj = mxTag->getPathObj(); + if( pPathObj ) + { + DragStat().SetActionRect(pPathObj->GetCurrentBoundRect()); + } + } + Show(); + return sal_True; +} + +bool PathDragMove::EndSdrDrag(bool /*bCopy*/) +{ + Hide(); + if( mxTag.is() ) + mxTag->MovePath( DragStat().GetDX(), DragStat().GetDY() ); + return sal_True; +} +// -------------------------------------------------------------------- + +class PathDragResize : public SdrDragResize +{ +private: + basegfx::B2DPolyPolygon maPathPolyPolygon; + +protected: + virtual void createSdrDragEntries(); + +public: + PathDragResize(SdrDragView& rNewView, + const rtl::Reference <MotionPathTag >& xTag, + const basegfx::B2DPolyPolygon& rPathPolyPolygon) + : SdrDragResize(rNewView), + maPathPolyPolygon(rPathPolyPolygon), + mxTag( xTag ) + {} + + PathDragResize(SdrDragView& rNewView, + const rtl::Reference <MotionPathTag >& xTag) + : SdrDragResize(rNewView), + maPathPolyPolygon(), + mxTag( xTag ) + {} + + virtual bool EndSdrDrag(bool bCopy); + rtl::Reference <MotionPathTag > mxTag; +}; + +void PathDragResize::createSdrDragEntries() +{ + // call parent + SdrDragResize::createSdrDragEntries(); + + if(maPathPolyPolygon.count()) + { + addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon)); + } +} + +bool PathDragResize::EndSdrDrag(bool /*bCopy*/) +{ + Hide(); + if( mxTag.is() ) + { + SdrPathObj* pPathObj = mxTag->getPathObj(); + if( pPathObj ) + { + const Point aRef( DragStat().Ref1() ); + basegfx::B2DHomMatrix aTrans(basegfx::tools::createTranslateB2DHomMatrix(-aRef.X(), -aRef.Y())); + aTrans.scale(double(aXFact), double(aYFact)); + aTrans.translate(aRef.X(), aRef.Y()); + basegfx::B2DPolyPolygon aDragPoly(pPathObj->GetPathPoly()); + aDragPoly.transform(aTrans); + pPathObj->SetPathPoly( aDragPoly ); + } + } + return sal_True; +} + +// -------------------------------------------------------------------- + +class PathDragObjOwn : public SdrDragObjOwn +{ +private: + basegfx::B2DPolyPolygon maPathPolyPolygon; + +protected: + virtual void createSdrDragEntries(); + +public: + PathDragObjOwn(SdrDragView& rNewView, + const basegfx::B2DPolyPolygon& rPathPolyPolygon) + : SdrDragObjOwn(rNewView), + maPathPolyPolygon(rPathPolyPolygon) + {} + + PathDragObjOwn(SdrDragView& rNewView) + : SdrDragObjOwn(rNewView), + maPathPolyPolygon() + {} + + virtual bool EndSdrDrag(bool bCopy); +}; + +void PathDragObjOwn::createSdrDragEntries() +{ + // call parent + SdrDragObjOwn::createSdrDragEntries(); + + if(maPathPolyPolygon.count()) + { + addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon)); + } +} + +bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/) +{ + Hide(); + + SdrObject* pObj = GetDragObj(); + + if(pObj) + { + return pObj->applySpecialDrag(DragStat()); + } + else + { + return false; + } +} + +// -------------------------------------------------------------------- + +class SdPathHdl : public SmartHdl +{ +public: + SdPathHdl( const SmartTagReference& xTag, SdrPathObj* mpPathObj ); + virtual ~SdPathHdl(); + virtual void CreateB2dIAObject(); + virtual sal_Bool IsFocusHdl() const; + virtual Pointer GetSdrDragPointer() const; + virtual bool isMarkable() const; + +private: + SdrPathObj* mpPathObj; + rtl::Reference< MotionPathTag > mxTag; +}; + +// -------------------------------------------------------------------- + +SdPathHdl::SdPathHdl( const SmartTagReference& xTag, SdrPathObj* pPathObj ) +: SmartHdl( xTag, pPathObj->GetCurrentBoundRect().TopLeft() ) +, mpPathObj( pPathObj ) +, mxTag( dynamic_cast< MotionPathTag* >( xTag.get() ) ) +{ +} + +// -------------------------------------------------------------------- + +SdPathHdl::~SdPathHdl() +{ +} + +// -------------------------------------------------------------------- + +void SdPathHdl::CreateB2dIAObject() +{ + // first throw away old one + GetRidOfIAObject(); + + if(pHdlList) + { + SdrMarkView* pView = pHdlList->GetView(); + + if(pView && !pView->areMarkHandlesHidden()) + { + SdrPageView* pPageView = pView->GetSdrPageView(); + + if(pPageView) + { + for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) + { + const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); + + if(rPageWindow.GetPaintWindow().OutputToWindow()) + { + if(rPageWindow.GetOverlayManager() && mpPathObj) + { + const sdr::contact::ViewContact& rVC = mpPathObj->GetViewContact(); + const drawinglayer::primitive2d::Primitive2DSequence aSequence = rVC.getViewIndependentPrimitive2DSequence(); + sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence); + + rPageWindow.GetOverlayManager()->add(*pNew); + maOverlayGroup.append(*pNew); + } + } + } + } + } + } +} + +// -------------------------------------------------------------------- + +sal_Bool SdPathHdl::IsFocusHdl() const +{ + return sal_False; +} + +// -------------------------------------------------------------------- + +bool SdPathHdl::isMarkable() const +{ + return false; +} + +// -------------------------------------------------------------------- + +Pointer SdPathHdl::GetSdrDragPointer() const +{ + PointerStyle eStyle = POINTER_NOTALLOWED; + if( mxTag.is() ) + { + if( mxTag->isSelected() ) + { + if( !mxTag->getView().IsFrameDragSingles() && mxTag->getView().IsInsObjPointMode() ) + eStyle = POINTER_CROSS; + else + eStyle = POINTER_MOVE; + } + else + { + eStyle = POINTER_ARROW; + + } + } + return Pointer( eStyle ); +} + +// ==================================================================== + +MotionPathTag::MotionPathTag( CustomAnimationPane& rPane, ::sd::View& rView, const CustomAnimationEffectPtr& pEffect ) +: SmartTag( rView ) +, mrPane( rPane ) +, mpEffect( pEffect ) +, mxOrigin( pEffect->getTargetShape() ) +, msLastPath( pEffect->getPath() ) +, mbInUpdatePath( false ) +{ + mpPathObj = mpEffect->createSdrPathObjFromPath(); + mxPolyPoly = mpPathObj->GetPathPoly(); + maOriginPos = mxOrigin->getPosition(); + + SdrPage* pPage = mrView.GetSdrPageView()->GetPage(); + if( pPage ) + { + mpPathObj->SetPage( pPage ); + mpPathObj->SetObjList( pPage ); + } + + XDash aDash( XDASH_RECT, 1, 80, 1, 80, 80); + String aEmpty( RTL_CONSTASCII_USTRINGPARAM("?") ); + mpPathObj->SetMergedItem( XLineDashItem( aEmpty, aDash ) ); + mpPathObj->SetMergedItem( XLineStyleItem( XLINE_DASH ) ); + mpPathObj->SetMergedItem( XLineColorItem(aEmpty, ::Color(COL_GRAY)) ); + mpPathObj->SetMergedItem( XFillStyleItem( XFILL_NONE ) ); + + ::basegfx::B2DPolygon aStartArrow; + aStartArrow.append(::basegfx::B2DPoint(20.0, 0.0)); + aStartArrow.append(::basegfx::B2DPoint(0.0, 0.0)); + aStartArrow.append(::basegfx::B2DPoint(10.0, 30.0)); + aStartArrow.setClosed(true); + mpPathObj->SetMergedItem(XLineStartItem(aEmpty,::basegfx::B2DPolyPolygon(aStartArrow))); + mpPathObj->SetMergedItem(XLineStartWidthItem(400)); + mpPathObj->SetMergedItem(XLineStartCenterItem(sal_True)); + + updatePathAttributes(); + + mpPathObj->SetMergedItem(XLineTransparenceItem(50)); + + mpMark = new SdrMark( mpPathObj, mrView.GetSdrPageView() ); + + mpPathObj->AddListener( *this ); + + Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY ); + if( xNotifier.is() ) + { + Reference< XChangesListener > xListener( this ); + xNotifier->addChangesListener( this ); + } +} + +// -------------------------------------------------------------------- + +MotionPathTag::~MotionPathTag() +{ + DBG_ASSERT( mpPathObj == 0, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" ); + Dispose(); +} + +// -------------------------------------------------------------------- + +void MotionPathTag::updatePathAttributes() +{ + String aEmpty( RTL_CONSTASCII_USTRINGPARAM("?") ); + + ::basegfx::B2DPolygon aCandidate; + if( mxPolyPoly.count() ) + { + aCandidate = mxPolyPoly.getB2DPolygon(0); + ::basegfx::tools::checkClosed( aCandidate ); + } + + if( !aCandidate.isClosed() ) + { + ::basegfx::B2DPolygon aEndArrow; + aEndArrow.append(::basegfx::B2DPoint(10.0, 0.0)); + aEndArrow.append(::basegfx::B2DPoint(0.0, 30.0)); + aEndArrow.append(::basegfx::B2DPoint(20.0, 30.0)); + aEndArrow.setClosed(true); + mpPathObj->SetMergedItem(XLineEndItem(aEmpty,::basegfx::B2DPolyPolygon(aEndArrow))); + mpPathObj->SetMergedItem(XLineEndWidthItem(400)); + mpPathObj->SetMergedItem(XLineEndCenterItem(sal_True)); + } + else + { + mpPathObj->SetMergedItem(XLineEndItem()); + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) +{ + if( mpPathObj && !mbInUpdatePath && dynamic_cast< const SdrHint* >( &rHint ) && (mpEffect.get() != 0) ) + { + if( mxPolyPoly != mpPathObj->GetPathPoly() ) + { + mbInUpdatePath = true; + mxPolyPoly = mpPathObj->GetPathPoly(); + rtl::Reference< MotionPathTag > xTag( this ); + mrPane.updatePathFromMotionPathTag( xTag ); + msLastPath = mpEffect->getPath(); + updatePathAttributes(); + mbInUpdatePath = false; + } + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::MovePath( int nDX, int nDY ) +{ + if( mpPathObj ) + { + mpPathObj->Move( Size( nDX, nDY ) ); + mrView.updateHandles(); + } +} + +// -------------------------------------------------------------------- + +/** returns true if the MotionPathTag handled the event. */ +bool MotionPathTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& rHdl ) +{ + if( !mpPathObj ) + return false; + + if( !isSelected() ) + { + SmartTagReference xTag( this ); + mrView.getSmartTags().select( xTag ); + selectionChanged(); + return true; + } + else + { + if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) ) + { + mrView.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT, SFX_CALLMODE_ASYNCHRON); + return true; + } + else if( rMEvt.IsLeft() ) + { + OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow(); + Point aMDPos( pOut->PixelToLogic( rMEvt.GetPosPixel() ) ); + + if( !mrView.IsFrameDragSingles() && mrView.IsInsObjPointMode() && (rHdl.GetObjHdlNum() == SMART_TAG_HDL_NUM) ) + { + // insert a point in edit mode + const bool bNewObj = rMEvt.IsMod1(); + + mrView.BrkAction(); + + Point aPt(aMDPos); // - pMarkedPV->GetOffset()); + + if(bNewObj) + aPt = mrView.GetSnapPos(aPt,mrView.GetSdrPageView()); + + sal_Bool bClosed0(mpPathObj->IsClosedObj()); + + sal_uInt32 nInsPointNum = mpPathObj->NbcInsPointOld(aPt, bNewObj, sal_True); + + if(bClosed0 != mpPathObj->IsClosedObj()) + { + // Obj was closed implicit + // object changed + mpPathObj->SetChanged(); + mpPathObj->BroadcastObjectChange(); + } + + if(0xffffffff != nInsPointNum) + { + mrView.UnmarkAllPoints(); + mrView.updateHandles(); + + bool bRet = mrView.BegDragObj(aMDPos, pOut, mrView.GetHdl(nInsPointNum+1), 0, new PathDragObjOwn( mrView ) ); + + if (bRet) + { + const_cast< SdrDragStat* >( &mrView.GetDragStat() )->SetMinMoved(); + mrView.MovDragObj(aMDPos); + } + } + return true; + } + else + { + SmartHdl* pHdl = &rHdl; + if (!mrView.IsPointMarked(*pHdl) || rMEvt.IsShift()) + { + if (!rMEvt.IsShift()) + { + mrView.UnmarkAllPoints(); + pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) ); + } + else + { + if (mrView.IsPointMarked(*pHdl) ) + { + mrView.UnmarkPoint(*pHdl); + pHdl = NULL; + } + else + { + pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) ); + } + } + + if (pHdl) + mrView.MarkPoint(*pHdl); + } + + + if( pHdl && !rMEvt.IsRight() ) + { + mrView.BrkAction(); + const sal_uInt16 nDrgLog = (sal_uInt16)pOut->PixelToLogic(Size(DRGPIX,0)).Width(); + + rtl::Reference< MotionPathTag > xTag( this ); + SdrDragMethod* pDragMethod; + + // #i95646# add DragPoly as geometry to each local SdrDragMethod to be able + // to create the needed local SdrDragEntry for it in createSdrDragEntries() + const basegfx::B2DPolyPolygon aDragPoly(mpPathObj->GetPathPoly()); + + if( (pHdl->GetKind() == HDL_MOVE) || (pHdl->GetKind() == HDL_SMARTTAG) ) + { + pDragMethod = new PathDragMove( mrView, xTag, aDragPoly ); + pHdl->SetPos( aMDPos ); + } + else if( pHdl->GetKind() == HDL_POLY ) + { + pDragMethod = new PathDragObjOwn( mrView, aDragPoly ); + } + else + { + pDragMethod = new PathDragResize( mrView, xTag, aDragPoly ); + } + + mrView.BegDragObj(aMDPos, NULL, pHdl, nDrgLog, pDragMethod ); + } + return true; + } + } + } + + return false; +} + +// -------------------------------------------------------------------- + +/** returns true if the SmartTag consumes this event. */ +bool MotionPathTag::KeyInput( const KeyEvent& rKEvt ) +{ + if( !mpPathObj ) + return false; + + sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); + switch( nCode ) + { + case KEY_DELETE: + return OnDelete(); + + case KEY_DOWN: + case KEY_UP: + case KEY_LEFT: + case KEY_RIGHT: + return OnMove( rKEvt ); + + case KEY_ESCAPE: + { + SmartTagReference xThis( this ); + mrView.getSmartTags().deselect(); + return true; + } + + case KEY_TAB: + return OnTabHandles( rKEvt ); + + case KEY_SPACE: + return OnMarkHandle( rKEvt ); + + default: + break; + } + return false; +} + +bool MotionPathTag::OnDelete() +{ + mrPane.remove( mpEffect ); + return true; +} + +bool MotionPathTag::OnTabHandles( const KeyEvent& rKEvt ) +{ + if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2()) + { + const SdrHdlList& rHdlList = mrView.GetHdlList(); + sal_Bool bForward(!rKEvt.GetKeyCode().IsShift()); + + ((SdrHdlList&)rHdlList).TravelFocusHdl(bForward); + + // guarantee visibility of focused handle + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if(pHdl) + { + Window* pWindow = mrView.GetViewShell()->GetActiveWindow(); + if( pWindow ) + { + Point aHdlPosition(pHdl->GetPos()); + Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200)); + mrView.MakeVisible(aVisRect, *pWindow); + } + } + + return true; + } + + return false; +} + +bool MotionPathTag::OnMarkHandle( const KeyEvent& rKEvt ) +{ + const SdrHdlList& rHdlList = mrView.GetHdlList(); + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if(pHdl && pHdl->GetKind() == HDL_POLY ) + { + // rescue ID of point with focus + sal_uInt32 nPol(pHdl->GetPolyNum()); + sal_uInt32 nPnt(pHdl->GetPointNum()); + + if(mrView.IsPointMarked(*pHdl)) + { + if(rKEvt.GetKeyCode().IsShift()) + { + mrView.UnmarkPoint(*pHdl); + } + } + else + { + if(!rKEvt.GetKeyCode().IsShift()) + { + mrView.UnmarkAllPoints(); + } + mrView.MarkPoint(*pHdl); + } + + if(0L == rHdlList.GetFocusHdl()) + { + // restore point with focus + SdrHdl* pNewOne = 0L; + + for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++) + { + SdrHdl* pAct = rHdlList.GetHdl(a); + + if(pAct && pAct->GetKind() == HDL_POLY && pAct->GetPolyNum() == nPol && pAct->GetPointNum() == nPnt) + pNewOne = pAct; + } + + if(pNewOne) + ((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne); + } + } + + return true; +} + +bool MotionPathTag::OnMove( const KeyEvent& rKEvt ) +{ + long nX = 0; + long nY = 0; + + switch( rKEvt.GetKeyCode().GetCode() ) + { + case KEY_UP: nY = -1; break; + case KEY_DOWN: nY = 1; break; + case KEY_LEFT: nX = -1; break; + case KEY_RIGHT: nX = 1; break; + default: break; + } + + if(rKEvt.GetKeyCode().IsMod2()) + { + OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow(); + Size aLogicSizeOnePixel = (pOut) ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100); + nX *= aLogicSizeOnePixel.Width(); + nY *= aLogicSizeOnePixel.Height(); + } + else + { + // old, fixed move distance + nX *= 100; + nY *= 100; + } + + if( nX || nY ) + { + // in point edit mode move the handle with the focus + const SdrHdlList& rHdlList = mrView.GetHdlList(); + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if(pHdl) + { + // now move the Handle (nX, nY) + Point aStartPoint(pHdl->GetPos()); + Point aEndPoint(pHdl->GetPos() + Point(nX, nY)); + + // start dragging + rtl::Reference< MotionPathTag > xTag( this ); + SdrDragMethod* pDragMethod = 0; + if( (pHdl->GetKind() == HDL_MOVE) || (pHdl->GetKind() == HDL_SMARTTAG) ) + { + pDragMethod = new PathDragMove( mrView, xTag ); + } + else if( pHdl->GetKind() == HDL_POLY ) + { + pDragMethod = new PathDragObjOwn( mrView ); + } + else if( pHdl->GetKind() != HDL_BWGT ) + { + pDragMethod = new PathDragResize( mrView, xTag ); + } + mrView.BegDragObj(aStartPoint, 0, pHdl, 0, pDragMethod); + + if(mrView.IsDragObj()) + { + FASTBOOL bWasNoSnap = mrView.GetDragStat().IsNoSnap(); + sal_Bool bWasSnapEnabled = mrView.IsSnapEnabled(); + + // switch snapping off + if(!bWasNoSnap) + ((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(sal_True); + if(bWasSnapEnabled) + mrView.SetSnapEnabled(sal_False); + + mrView.MovAction(aEndPoint); + mrView.EndDragObj(); + + // restore snap + if(!bWasNoSnap) + ((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(bWasNoSnap); + if(bWasSnapEnabled) + mrView.SetSnapEnabled(bWasSnapEnabled); + } + } + else + { + // move the path + MovePath( nX, nY ); + } + } + + return true; +} + +// -------------------------------------------------------------------- + +sal_uLong MotionPathTag::GetMarkablePointCount() const +{ + if( mpPathObj && isSelected() ) + { + return mpPathObj->GetPointCount(); + } + else + { + return 0; + } +} + +// -------------------------------------------------------------------- + +sal_uLong MotionPathTag::GetMarkedPointCount() const +{ + if( mpMark ) + { + const SdrUShortCont* pPts=mpMark->GetMarkedPoints(); + return pPts ? pPts->GetCount() : 0; + } + else + { + return 0; + } +} + +// -------------------------------------------------------------------- + +sal_Bool MotionPathTag::MarkPoint(SdrHdl& rHdl, sal_Bool bUnmark ) +{ + sal_Bool bRet=sal_False; + if( mpPathObj && mrView.IsPointMarkable( rHdl ) && (rHdl.GetKind() != HDL_SMARTTAG) ) + { + SmartHdl* pSmartHdl = dynamic_cast< SmartHdl* >( &rHdl ); + if( pSmartHdl && pSmartHdl->getTag().get() == this ) + { + SdrUShortCont* pPts=mpMark->ForceMarkedPoints(); + pPts->ForceSort(); + if (mrView.MarkPointHelper(&rHdl,mpMark,bUnmark)) + { + pPts->ForceSort(); + mrView.MarkListHasChanged(); + bRet=sal_True; + } + } + } + return bRet; +} + +// -------------------------------------------------------------------- + +sal_Bool MotionPathTag::MarkPoints(const Rectangle* pRect, sal_Bool bUnmark ) +{ + sal_Bool bChgd=sal_False; + + if( mpPathObj && isSelected() ) + { + sal_Int32 nHdlNum = mrView.GetHdlList().GetHdlCount() - 1; + while( nHdlNum > 0 ) + { + SmartHdl* pHdl = dynamic_cast< SmartHdl* >( mrView.GetHdl( sal::static_int_cast< sal_uLong >( nHdlNum-- ) ) ); + + if( pHdl && (pHdl->getTag().get() == this) && mrView.IsPointMarkable(*pHdl) && pHdl->IsSelected()==bUnmark) + { + Point aPos(pHdl->GetPos()); + if( pRect==NULL || pRect->IsInside(aPos)) + { + if( mrView.MarkPointHelper(pHdl,mpMark,bUnmark) ) + bChgd=sal_True; + } + } + } + + if(bChgd) + mrView.MarkListHasChanged(); + } + + return bChgd; +} + +// -------------------------------------------------------------------- + +bool MotionPathTag::getContext( SdrViewContext& rContext ) +{ + if( mpPathObj && isSelected() && !mrView.IsFrameDragSingles() ) + { + rContext = SDRCONTEXT_POINTEDIT; + return true; + } + else + { + return false; + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::CheckPossibilities() +{ + if( mpPathObj ) + { + if( isSelected() ) + { + mrView.SetMoveAllowed( true ); + mrView.SetMoveProtected( false ); + mrView.SetResizeFreeAllowed( true ); + mrView.SetResizePropAllowed( true ); + mrView.SetResizeProtected( false ); + + if( !mrView.IsFrameDragSingles() ) + { + bool b1stSmooth(true); + bool b1stSegm(true); + bool bCurve(false); + bool bSmoothFuz(false); + bool bSegmFuz(false); + basegfx::B2VectorContinuity eSmooth = basegfx::CONTINUITY_NONE; + + mrView.CheckPolyPossibilitiesHelper( mpMark, b1stSmooth, b1stSegm, bCurve, bSmoothFuz, bSegmFuz, eSmooth ); + } + } + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::addCustomHandles( SdrHdlList& rHandlerList ) +{ + if( mpPathObj ) + { + ::com::sun::star::awt::Point aPos( mxOrigin->getPosition() ); + if( (aPos.X != maOriginPos.X) || (aPos.Y != maOriginPos.Y) ) + { + const basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( + aPos.X - maOriginPos.X, aPos.Y - maOriginPos.Y)); + mxPolyPoly.transform( aTransform ); + mpPathObj->SetPathPoly( mxPolyPoly ); + maOriginPos = aPos; + } + + SmartTagReference xThis( this ); + SdPathHdl* pHdl = new SdPathHdl( xThis, mpPathObj ); + pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM ); + pHdl->SetPageView( mrView.GetSdrPageView() ); + + + pHdl->SetObj(mpPathObj); + rHandlerList.AddHdl( pHdl ); + + if( isSelected() ) + { + mrView.GetSdrPageView()->SetHasMarkedObj(sal_True); + + if( !mrView.IsFrameDragSingles() ) + { + SdrHdlList aTemp( rHandlerList.GetView() ); + mpPathObj->AddToHdlList( aTemp ); + const SdrUShortCont* pMrkPnts=mpMark->GetMarkedPoints(); + + sal_uInt32 nHandle; + for( nHandle = 0; nHandle < aTemp.GetHdlCount(); ++nHandle ) + { + SdrHdl* pTempHdl = aTemp.GetHdl( nHandle ); + + SmartHdl* pSmartHdl = new SmartHdl( xThis, mpPathObj, pTempHdl->GetPos(), pTempHdl->GetKind() ); + pSmartHdl->SetObjHdlNum( nHandle ); + pSmartHdl->SetPolyNum( pTempHdl->GetPolyNum() ); + pSmartHdl->SetPointNum( pTempHdl->GetPointNum() ); + pSmartHdl->SetPlusHdl( pTempHdl->IsPlusHdl() ); + pSmartHdl->SetSourceHdlNum( pTempHdl->GetSourceHdlNum() ); + pSmartHdl->SetPageView( mrView.GetSdrPageView() ); + + rHandlerList.AddHdl( pSmartHdl ); + + const bool bSelected= pMrkPnts && pMrkPnts->Exist(sal::static_int_cast< sal_uInt16 >(nHandle)); + pSmartHdl->SetSelected(bSelected); + + if( mrView.IsPlusHandlesAlwaysVisible() || bSelected ) + { + sal_uInt32 nPlusAnz=mpPathObj->GetPlusHdlCount(*pSmartHdl); + for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++) + { + SdrHdl* pPlusHdl = mpPathObj->GetPlusHdl(*pSmartHdl,nPlusNum); + if (pPlusHdl!=NULL) + { + pPlusHdl->SetObj(mpPathObj); + pPlusHdl->SetPageView(mrView.GetSdrPageView()); + pPlusHdl->SetPlusHdl(sal_True); + rHandlerList.AddHdl(pPlusHdl); + } + } + } + } + } + else + { + Rectangle aRect(mpPathObj->GetCurrentBoundRect()); + + if(!aRect.IsEmpty()) + { + sal_uLong nCount = rHandlerList.GetHdlCount(); + + sal_Bool bWdt0=aRect.Left()==aRect.Right(); + sal_Bool bHgt0=aRect.Top()==aRect.Bottom(); + if (bWdt0 && bHgt0) + { + rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft(),HDL_UPLFT)); + } + else if (bWdt0 || bHgt0) + { + rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft() ,HDL_UPLFT)); + rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomRight(),HDL_LWRGT)); + } + else + { + if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft() ,HDL_UPLFT)); + if ( !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopCenter() ,HDL_UPPER)); + if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopRight() ,HDL_UPRGT)); + if (!bWdt0 ) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.LeftCenter() ,HDL_LEFT )); + if (!bWdt0 ) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.RightCenter() ,HDL_RIGHT)); + if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomLeft() ,HDL_LWLFT)); + if ( !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomCenter(),HDL_LOWER)); + if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomRight() ,HDL_LWRGT)); + } + + while( nCount < rHandlerList.GetHdlCount() ) + { + rHandlerList.GetHdl(nCount++)->SetPageView( mrView.GetSdrPageView() ); + } + } + } + } + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::disposing() +{ + Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY ); + if( xNotifier.is() ) + { + Reference< XChangesListener > xListener( this ); + xNotifier->removeChangesListener( this ); + } + + if( mpPathObj ) + { + SdrPathObj* pPathObj = mpPathObj; + mpPathObj = 0; + mrView.updateHandles(); + delete pPathObj; + } + + if( mpMark ) + { + delete mpMark; + mpMark = 0; + } + + SmartTag::disposing(); +} + +// -------------------------------------------------------------------- + +void MotionPathTag::deselect() +{ + SmartTag::deselect(); + + if( mpMark ) + { + SdrUShortCont* pPts = mpMark->GetMarkedPoints(); + + if( pPts ) + pPts->Clear(); + } + + selectionChanged(); +} + +void MotionPathTag::selectionChanged() +{ + if( mrView.GetViewShell() && mrView.GetViewShell()->GetViewFrame() ) + { + SfxBindings& rBindings = mrView.GetViewShell()->GetViewFrame()->GetBindings(); + rBindings.InvalidateAll(sal_True); + } +} +// -------------------------------------------------------------------- +// IPolyPolygonEditorController +// -------------------------------------------------------------------- + +void MotionPathTag::DeleteMarkedPoints() +{ + if( mpPathObj && IsDeleteMarkedPointsPossible() ) + { + mrView.BrkAction(); + + // Description +// BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_DELETE); + + SdrUShortCont* pPts = mpMark->GetMarkedPoints(); + + if( pPts ) + { + PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() ); + if( aEditor.DeletePoints( pPts->getContainer() ) ) + { + if( aEditor.GetPolyPolygon().count() ) + { +// AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath )); + mpPathObj->SetPathPoly( aEditor.GetPolyPolygon() ); + } + else + { +// AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pPath ) ); +// pM->GetPageView()->GetObjList()->RemoveObject(pObj->GetOrdNum()); + } + + mrView.UnmarkAllPoints(); + mrView.MarkListHasChanged(); + mrView.updateHandles(); + } + } + +// EndUndo(); + } +} + +sal_Bool MotionPathTag::IsDeleteMarkedPointsPossible() const +{ + return mpPathObj && isSelected() && (GetMarkedPointCount() != 0); +} + +void MotionPathTag::RipUpAtMarkedPoints() +{ + // not supported for motion path +} + +bool MotionPathTag::IsRipUpAtMarkedPointsPossible() const +{ + // not supported for motion path + return false; +} + +sal_Bool MotionPathTag::IsSetMarkedSegmentsKindPossible() const +{ + if( mpPathObj ) + return mrView.IsSetMarkedSegmentsKindPossible(); + else + return sal_False; +} + +SdrPathSegmentKind MotionPathTag::GetMarkedSegmentsKind() const +{ + if( mpPathObj ) + return mrView.GetMarkedSegmentsKind(); + else + return SDRPATHSEGMENT_LINE; +} + +void MotionPathTag::SetMarkedSegmentsKind(SdrPathSegmentKind eKind) +{ + if(mpPathObj && isSelected() && (GetMarkedPointCount() != 0)) + { + SdrUShortCont* pPts = mpMark->GetMarkedPoints(); + if(pPts) + { + PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() ); + if(aEditor.SetSegmentsKind( eKind, pPts->getContainer()) ) + { +// AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath)); + mpPathObj->SetPathPoly(aEditor.GetPolyPolygon()); + mrView.MarkListHasChanged(); + mrView.updateHandles(); + } + } + } +} + +sal_Bool MotionPathTag::IsSetMarkedPointsSmoothPossible() const +{ + if( mpPathObj ) + return mrView.IsSetMarkedPointsSmoothPossible(); + else + return sal_False; +} + +SdrPathSmoothKind MotionPathTag::GetMarkedPointsSmooth() const +{ + if( mpPathObj ) + return mrView.GetMarkedPointsSmooth(); + else + return SDRPATHSMOOTH_ANGULAR; +} + +void MotionPathTag::SetMarkedPointsSmooth(SdrPathSmoothKind eKind) +{ + basegfx::B2VectorContinuity eFlags; + + if(SDRPATHSMOOTH_ANGULAR == eKind) + { + eFlags = basegfx::CONTINUITY_NONE; + } + else if(SDRPATHSMOOTH_ASYMMETRIC == eKind) + { + eFlags = basegfx::CONTINUITY_C1; + } + else if(SDRPATHSMOOTH_SYMMETRIC == eKind) + { + eFlags = basegfx::CONTINUITY_C2; + } + else + { + return; + } + + if(mpPathObj && mpMark && isSelected() && (GetMarkedPointCount() != 0)) + { + SdrUShortCont* pPts = mpMark->GetMarkedPoints(); + if(pPts) + { + PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() ); + if(aEditor.SetPointsSmooth( eFlags, pPts->getContainer() ) ) + { +// AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath)); + mpPathObj->SetPathPoly(aEditor.GetPolyPolygon()); + mrView.MarkListHasChanged(); + mrView.updateHandles(); + } + } + } +} + +void MotionPathTag::CloseMarkedObjects(sal_Bool /*bToggle*/, sal_Bool /*bOpen*/ ) +{ + // not supported for motion path +} + +bool MotionPathTag::IsOpenCloseMarkedObjectsPossible() const +{ + // not supported for motion path + return false; +} + +SdrObjClosedKind MotionPathTag::GetMarkedObjectsClosedState() const +{ + // not supported for motion path + return SDROBJCLOSED_OPEN; +} + +// XChangesListener +void SAL_CALL MotionPathTag::changesOccurred( const ChangesEvent& /*Event*/ ) throw (RuntimeException) +{ + if( mpPathObj && !mbInUpdatePath && (mpEffect->getPath() != msLastPath) ) + { + mbInUpdatePath =true; + msLastPath = mpEffect->getPath(); + mpEffect->updateSdrPathObjFromPath( *mpPathObj ); + mbInUpdatePath = false; + updatePathAttributes(); + mrView.updateHandles(); + } +} + +void SAL_CALL MotionPathTag::disposing( const EventObject& /*Source*/ ) throw (RuntimeException) +{ + if( mpPathObj ) + Dispose(); +} + +Any SAL_CALL MotionPathTag::queryInterface( const ::com::sun::star::uno::Type& aType ) throw (RuntimeException) +{ + if( aType == XChangesListener::static_type() ) + return Any( Reference< XChangesListener >( this ) ); + if( aType == XEventListener::static_type() ) + return Any( Reference< XEventListener >( this ) ); + if( aType == XInterface::static_type() ) + return Any( Reference< XInterface >( this ) ); + + return Any(); +} + +void SAL_CALL MotionPathTag::acquire() throw () +{ + SimpleReferenceComponent::acquire(); +} + +void SAL_CALL MotionPathTag::release( ) throw () +{ + SimpleReferenceComponent::release(); +} + +} // end of namespace sd + diff --git a/sd/source/ui/animations/motionpathtag.hxx b/sd/source/ui/animations/motionpathtag.hxx new file mode 100755 index 000000000000..1e286e0e760e --- /dev/null +++ b/sd/source/ui/animations/motionpathtag.hxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_MOTIONPATHTAG_HXX_ +#define _SD_MOTIONPATHTAG_HXX_ + +#include <com/sun/star/util/XChangesListener.hpp> +#include <com/sun/star/util/XChangesListener.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include "smarttag.hxx" +#include "CustomAnimationEffect.hxx" + +class SdrPathObj; + +namespace sd { + +class View; +class CustomAnimationPane; + +/************************************************************************* +|* +|* Basisklasse fuer alle Funktionen +|* +\************************************************************************/ + +class MotionPathTag : public SmartTag, public IPolyPolygonEditorController, public SfxListener, public ::com::sun::star::util::XChangesListener +{ +public: + MotionPathTag( CustomAnimationPane& rPane, ::sd::View& rView, const CustomAnimationEffectPtr& pEffect ); + virtual ~MotionPathTag(); + + SdrPathObj* getPathObj() const { return mpPathObj; } + + /** returns true if the SmartTag handled the event. */ + virtual bool MouseButtonDown( const MouseEvent&, SmartHdl& ); + + /** returns true if the SmartTag consumes this event. */ + virtual bool KeyInput( const KeyEvent& rKEvt ); + + // callbacks from sdr view + virtual sal_uLong GetMarkablePointCount() const; + virtual sal_uLong GetMarkedPointCount() const; + virtual sal_Bool MarkPoint(SdrHdl& rHdl, sal_Bool bUnmark=sal_False); + virtual void CheckPossibilities(); + virtual sal_Bool MarkPoints(const Rectangle* pRect, sal_Bool bUnmark); + + const CustomAnimationEffectPtr& getEffect() const { return mpEffect; } + + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + + // IPolyPolygonEditorController + virtual void DeleteMarkedPoints(); + virtual sal_Bool IsDeleteMarkedPointsPossible() const; + + virtual void RipUpAtMarkedPoints(); + virtual bool IsRipUpAtMarkedPointsPossible() const; + + virtual sal_Bool IsSetMarkedSegmentsKindPossible() const; + virtual SdrPathSegmentKind GetMarkedSegmentsKind() const; + virtual void SetMarkedSegmentsKind(SdrPathSegmentKind eKind); + + virtual sal_Bool IsSetMarkedPointsSmoothPossible() const; + virtual SdrPathSmoothKind GetMarkedPointsSmooth() const; + virtual void SetMarkedPointsSmooth(SdrPathSmoothKind eKind); + + virtual void CloseMarkedObjects(sal_Bool bToggle, sal_Bool bOpen ); + virtual bool IsOpenCloseMarkedObjectsPossible() const; + virtual SdrObjClosedKind GetMarkedObjectsClosedState() const; + + void MovePath( int nDX, int nDY ); + bool OnDelete(); + bool OnTabHandles( const KeyEvent& rKEvt ); + bool OnMarkHandle( const KeyEvent& rKEvt ); + bool OnMove( const KeyEvent& rKEvt ); + + // XChangesListener + virtual void SAL_CALL changesOccurred( const ::com::sun::star::util::ChangesEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire( ) throw (); + virtual void SAL_CALL release( ) throw (); + +protected: + virtual void addCustomHandles( SdrHdlList& rHandlerList ); + virtual bool getContext( SdrViewContext& rContext ); + virtual void disposing(); + virtual void deselect(); + + void updatePathAttributes(); + void selectionChanged(); + +private: + CustomAnimationPane& mrPane; + CustomAnimationEffectPtr mpEffect; + ::basegfx::B2DPolyPolygon mxPolyPoly; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mxOrigin; + SdrPathObj* mpPathObj; + ::com::sun::star::awt::Point maOriginPos; + SdrMark* mpMark; + rtl::OUString msLastPath; + bool mbInUpdatePath; +}; + +} // end of namespace sd + +#endif // _SD_MOTIONPATHTAG_HXX_ + |