diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sd/source/ui/animations/CustomAnimationDialog.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sd/source/ui/animations/CustomAnimationDialog.cxx')
-rw-r--r-- | sd/source/ui/animations/CustomAnimationDialog.cxx | 2090 |
1 files changed, 2090 insertions, 0 deletions
diff --git a/sd/source/ui/animations/CustomAnimationDialog.cxx b/sd/source/ui/animations/CustomAnimationDialog.cxx new file mode 100644 index 000000000..7490a62c5 --- /dev/null +++ b/sd/source/ui/animations/CustomAnimationDialog.cxx @@ -0,0 +1,2090 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <config_features.h> + +#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/XPlayer.hpp> + +#include <memory> + +#include <comphelper/lok.hxx> +#include <i18nutil/unicode.hxx> +#include <vcl/svapp.hxx> +#include <vcl/stdtext.hxx> +#include <vcl/weld.hxx> +#include <vcl/settings.hxx> + +#include <svtools/ctrltool.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/viewsh.hxx> +#include <tools/debug.hxx> +#include <tools/urlobj.hxx> +#include <tools/diagnose_ex.h> + +#include <editeng/flstitem.hxx> + +#include <svx/colorbox.hxx> +#include <svx/gallery.hxx> + +#include <editeng/editids.hrc> +#include <sdresid.hxx> + +#include "CustomAnimationDialog.hxx" +#include <CustomAnimationPane.hxx> +#include "STLPropertySet.hxx" +#include <CustomAnimationPreset.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 ::com::sun::star::uno::UNO_QUERY; +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::drawing::XShape; +using ::com::sun::star::drawing::XDrawPage; +using ::com::sun::star::beans::XPropertySet; + +namespace sd { + +SdPropertySubControl::SdPropertySubControl(weld::Container* pParent) + : mxBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/customanimationfragment.ui", + false, reinterpret_cast<sal_uInt64>(SfxViewShell::Current()))) + , mxContainer(mxBuilder->weld_container("EffectFragment")) + , mpParent(pParent) +{ +} + +SdPropertySubControl::~SdPropertySubControl() +{ + mpParent->move(mxContainer.get(), nullptr); +} + +namespace { + +class SdPresetPropertyBox : public SdPropertySubControl +{ +public: + SdPresetPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const OUString& aPresetId, const Link<LinkParamNone*,void>& rModifyHdl); + + virtual Any getValue() override; + virtual void setValue( const Any& rValue, const OUString& rPresetId ) override; + +private: + std::vector<OUString> maPropertyValues; + Link<LinkParamNone*,void> maModifyLink; + std::unique_ptr<weld::ComboBox> mxControl; + + DECL_LINK(OnSelect, weld::ComboBox&, void); +}; + +} + +SdPresetPropertyBox::SdPresetPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const OUString& aPresetId, const Link<LinkParamNone*,void>& rModifyHdl) + : SdPropertySubControl(pParent) + , maModifyLink(rModifyHdl) + , mxControl(mxBuilder->weld_combo_box("combo")) +{ + mxControl->connect_changed(LINK(this, SdPresetPropertyBox, OnSelect)); + mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_PRESETPROPERTYBOX); + mxControl->show(); + pLabel->set_mnemonic_widget(mxControl.get()); + setValue(rValue, aPresetId); +} + +IMPL_LINK_NOARG(SdPresetPropertyBox, OnSelect, weld::ComboBox&, void) +{ + maModifyLink.Call(nullptr); +} + +void SdPresetPropertyBox::setValue( const Any& rValue, const OUString& rPresetId ) +{ + if (!mxControl) + return; + + mxControl->freeze(); + mxControl->clear(); + maPropertyValues.clear(); + int nPos = -1; + + const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets(); + CustomAnimationPresetPtr pDescriptor = rPresets.getEffectDescriptor( rPresetId ); + if( pDescriptor ) + { + + OUString aPropertyValue; + rValue >>= aPropertyValue; + + std::vector<OUString> aSubTypes( pDescriptor->getSubTypes() ); + + mxControl->set_sensitive(!aSubTypes.empty()); + + for( const auto& aSubType : aSubTypes ) + { + mxControl->append_text(rPresets.getUINameForProperty(aSubType)); + maPropertyValues.push_back(aSubType); + if (aSubType == aPropertyValue) + nPos = maPropertyValues.size() - 1; + } + } + else + { + mxControl->set_sensitive(false); + } + mxControl->thaw(); + if (nPos != -1) + mxControl->set_active(nPos); +} + +Any SdPresetPropertyBox::getValue() +{ + const int nIndex = mxControl->get_active(); + if (nIndex == -1) + return Any(); + return Any(maPropertyValues[nIndex]); +} + +namespace { + +class SdColorPropertyBox : public SdPropertySubControl +{ +public: + SdColorPropertyBox(weld::Label* pLabel, weld::Container* pParent, weld::Window* pTopLevel, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl); + + virtual Any getValue() override; + virtual void setValue( const Any& rValue, const OUString& rPresetId ) override; + +private: + Link<LinkParamNone*,void> maModifyLink; + std::unique_ptr<ColorListBox> mxControl; + + DECL_LINK(OnSelect, ColorListBox&, void); +}; + +} + +SdColorPropertyBox::SdColorPropertyBox(weld::Label* pLabel, weld::Container* pParent, weld::Window* pTopLevel, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl) + : SdPropertySubControl(pParent) + , maModifyLink(rModifyHdl) + , mxControl(new ColorListBox(mxBuilder->weld_menu_button("color"), [pTopLevel]{ return pTopLevel; })) +{ + mxControl->SetSelectHdl(LINK(this, SdColorPropertyBox, OnSelect)); + mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_COLORPROPERTYBOX); + pLabel->set_mnemonic_widget(&mxControl->get_widget()); + mxControl->show(); + + Color nColor; + rValue >>= nColor; + mxControl->SelectEntry(nColor); +} + +IMPL_LINK_NOARG(SdColorPropertyBox, OnSelect, ColorListBox&, void) +{ + maModifyLink.Call(nullptr); +} + +void SdColorPropertyBox::setValue( const Any& rValue, const OUString& ) +{ + if (mxControl) + { + Color nColor; + rValue >>= nColor; + + mxControl->SetNoSelection(); + mxControl->SelectEntry(nColor); + } +} + +Any SdColorPropertyBox::getValue() +{ + return Any(sal_Int32(mxControl->GetSelectEntryColor().GetRGBColor())); +} + +namespace { + +class SdFontPropertyBox : public SdPropertySubControl +{ +public: + SdFontPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl); + + virtual Any getValue() override; + virtual void setValue(const Any& rValue, const OUString& rPresetId) override; + +private: + Link<LinkParamNone*,void> maModifyHdl; + std::unique_ptr<weld::ComboBox> mxControl; + + DECL_LINK(ControlSelectHdl, weld::ComboBox&, void); +}; + +} + +SdFontPropertyBox::SdFontPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl) + : SdPropertySubControl(pParent) + , maModifyHdl(rModifyHdl) + , mxControl(mxBuilder->weld_combo_box("fontname")) +{ + mxControl->connect_changed(LINK(this, SdFontPropertyBox, ControlSelectHdl)); + mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTPROPERTYBOX); + mxControl->show(); + pLabel->set_mnemonic_widget(mxControl.get()); + + const FontList* pFontList = nullptr; + bool bMustDelete = false; + + if (SfxObjectShell* pDocSh = SfxObjectShell::Current()) + { + auto pItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST ); + if (pItem) + pFontList = static_cast<const SvxFontListItem*>(pItem)->GetFontList(); + } + + if (!pFontList) + { + pFontList = new FontList(Application::GetDefaultDevice(), nullptr); + bMustDelete = true; + } + + mxControl->freeze(); + + sal_uInt16 nFontCount = pFontList->GetFontNameCount(); + for (sal_uInt16 i = 0; i < nFontCount; ++i) + { + const FontMetric& rFontMetric = pFontList->GetFontName(i); + mxControl->append_text(rFontMetric.GetFamilyName()); + } + + mxControl->thaw(); + + if( bMustDelete ) + delete pFontList; + + setValue( rValue, OUString() ); +} + +IMPL_LINK_NOARG(SdFontPropertyBox, ControlSelectHdl, weld::ComboBox&, void) +{ + maModifyHdl.Call(nullptr); +} + +void SdFontPropertyBox::setValue( const Any& rValue, const OUString& ) +{ + if (mxControl) + { + OUString aFontName; + rValue >>= aFontName; + mxControl->set_entry_text(aFontName); + } +} + +Any SdFontPropertyBox::getValue() +{ + OUString aFontName(mxControl->get_active_text()); + return Any(aFontName); +} + +namespace { + +class SdCharHeightPropertyBox : public SdPropertySubControl +{ +public: + SdCharHeightPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl); + + virtual Any getValue() override; + virtual void setValue( const Any& rValue, const OUString& ) override; + + DECL_LINK(implMenuSelectHdl, const OString& rIdent, void); + +private: + Link<LinkParamNone*,void> maModifyHdl; + std::unique_ptr<weld::MetricSpinButton> mxMetric; + std::unique_ptr<weld::MenuButton> mxControl; + + DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void); +}; + +} + +SdCharHeightPropertyBox::SdCharHeightPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl) + : SdPropertySubControl(pParent) + , maModifyHdl(rModifyHdl) + , mxMetric(mxBuilder->weld_metric_spin_button("fontsize", FieldUnit::PERCENT)) + , mxControl(mxBuilder->weld_menu_button("fontsizemenu")) +{ + mxMetric->connect_value_changed(LINK(this, SdCharHeightPropertyBox, EditModifyHdl)); + mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_CHARHEIGHTPROPERTYBOX); + mxMetric->show(); + pLabel->set_mnemonic_widget(&mxMetric->get_widget()); + + mxControl->connect_selected(LINK(this, SdCharHeightPropertyBox, implMenuSelectHdl)); + mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_CHARHEIGHTPROPERTYBOX); + mxControl->show(); + + setValue(rValue, OUString()); +} + +IMPL_LINK_NOARG(SdCharHeightPropertyBox, EditModifyHdl, weld::MetricSpinButton&, void) +{ + maModifyHdl.Call(nullptr); +} + +IMPL_LINK(SdCharHeightPropertyBox, implMenuSelectHdl, const OString&, rIdent, void) +{ + sal_Int32 nValue = rIdent.toInt32(); + mxMetric->set_value(nValue, FieldUnit::PERCENT); + EditModifyHdl(*mxMetric); +} + +void SdCharHeightPropertyBox::setValue( const Any& rValue, const OUString& ) +{ + if (mxMetric) + { + double fValue = 0.0; + rValue >>= fValue; + mxMetric->set_value(static_cast<::tools::Long>(fValue * 100.0), FieldUnit::PERCENT); + } +} + +Any SdCharHeightPropertyBox::getValue() +{ + return Any(static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0); +} + +namespace { + +class SdTransparencyPropertyBox : public SdPropertySubControl +{ +public: + SdTransparencyPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl); + + virtual Any getValue() override; + virtual void setValue( const Any& rValue, const OUString& rPresetId ) override; + + DECL_LINK(implMenuSelectHdl, const OString&, void); + DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void); + + void updateMenu(); + +private: + Link<LinkParamNone*,void> maModifyHdl; + + std::unique_ptr<weld::MetricSpinButton> mxMetric; + std::unique_ptr<weld::MenuButton> mxControl; +}; + +} + +SdTransparencyPropertyBox::SdTransparencyPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl) + : SdPropertySubControl(pParent) + , maModifyHdl(rModifyHdl) + , mxMetric(mxBuilder->weld_metric_spin_button("transparent", FieldUnit::PERCENT)) + , mxControl(mxBuilder->weld_menu_button("transparentmenu")) +{ + for (sal_Int32 i = 25; i < 101; i += 25) + { + OUString aStr(unicode::formatPercent(i, + Application::GetSettings().GetUILanguageTag())); + mxControl->append_item_check(OUString::number(i), aStr); + } + + mxControl->connect_selected(LINK(this, SdTransparencyPropertyBox, implMenuSelectHdl)); + mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_TRANSPARENCYPROPERTYBOX); + mxControl->show(); + + mxMetric->connect_value_changed(LINK(this, SdTransparencyPropertyBox, implModifyHdl)); + mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_TRANSPARENCYPROPERTYBOX); + mxMetric->show(); + pLabel->set_mnemonic_widget(&mxMetric->get_widget()); + + setValue(rValue, OUString()); +} + +void SdTransparencyPropertyBox::updateMenu() +{ + sal_Int64 nValue = mxMetric->get_value(FieldUnit::PERCENT); + for (sal_uInt16 i = 25; i < 101; i += 25) + mxControl->set_item_active(OString::number(i), nValue == i); +} + +IMPL_LINK_NOARG(SdTransparencyPropertyBox, implModifyHdl, weld::MetricSpinButton&, void) +{ + updateMenu(); + maModifyHdl.Call(nullptr); +} + +IMPL_LINK(SdTransparencyPropertyBox, implMenuSelectHdl, const OString&, rIdent, void) +{ + auto nValue = rIdent.toInt32(); + if (nValue != mxMetric->get_value(FieldUnit::PERCENT)) + { + mxMetric->set_value(nValue, FieldUnit::PERCENT); + implModifyHdl(*mxMetric); + } +} + +void SdTransparencyPropertyBox::setValue(const Any& rValue, const OUString&) +{ + if (mxMetric) + { + double fValue = 0.0; + rValue >>= fValue; + ::tools::Long nValue = static_cast<::tools::Long>(fValue * 100); + mxMetric->set_value(nValue, FieldUnit::PERCENT); + updateMenu(); + } +} + +Any SdTransparencyPropertyBox::getValue() +{ + return Any(static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0); +} + +namespace { + +class SdRotationPropertyBox : public SdPropertySubControl +{ +public: + SdRotationPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl); + + virtual Any getValue() override; + virtual void setValue( const Any& rValue, const OUString& ) override; + + DECL_LINK(implMenuSelectHdl, const OString&, void); + DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void); + + void updateMenu(); + +private: + Link<LinkParamNone*,void> maModifyHdl; + + std::unique_ptr<weld::MetricSpinButton> mxMetric; + std::unique_ptr<weld::MenuButton> mxControl; +}; + +} + +SdRotationPropertyBox::SdRotationPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl) + : SdPropertySubControl(pParent) + , maModifyHdl(rModifyHdl) + , mxMetric(mxBuilder->weld_metric_spin_button("rotate", FieldUnit::DEGREE)) + , mxControl(mxBuilder->weld_menu_button("rotatemenu")) +{ + mxMetric->connect_value_changed(LINK( this, SdRotationPropertyBox, implModifyHdl)); + mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_ROTATIONPROPERTYBOX); + mxMetric->show(); + pLabel->set_mnemonic_widget(&mxMetric->get_widget()); + + mxControl->connect_selected(LINK(this, SdRotationPropertyBox, implMenuSelectHdl)); + mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_ROTATIONPROPERTYBOX); + mxControl->show(); + + setValue(rValue, OUString()); +} + +void SdRotationPropertyBox::updateMenu() +{ + sal_Int64 nValue = mxMetric->get_value(FieldUnit::DEGREE); + bool bDirection = nValue >= 0; + nValue = (nValue < 0 ? -nValue : nValue); + + mxControl->set_item_active("90", nValue == 90); + mxControl->set_item_active("180", nValue == 180); + mxControl->set_item_active("360", nValue == 360); + mxControl->set_item_active("720", nValue == 720); + + mxControl->set_item_active("closewise", bDirection); + mxControl->set_item_active("counterclock", !bDirection); +} + +IMPL_LINK_NOARG(SdRotationPropertyBox, implModifyHdl, weld::MetricSpinButton&, void) +{ + updateMenu(); + maModifyHdl.Call(nullptr); +} + +IMPL_LINK(SdRotationPropertyBox, implMenuSelectHdl, const OString&, rIdent, void) +{ + auto nValue = mxMetric->get_value(FieldUnit::DEGREE); + bool bDirection = nValue >= 0; + nValue = (nValue < 0 ? -nValue : nValue); + + if (rIdent == "clockwise") + bDirection = true; + else if (rIdent == "counterclock") + bDirection = false; + else + nValue = rIdent.toInt32(); + + if( !bDirection ) + nValue = -nValue; + + if (nValue != mxMetric->get_value(FieldUnit::DEGREE)) + { + mxMetric->set_value(nValue, FieldUnit::DEGREE); + implModifyHdl(*mxMetric); + } +} + +void SdRotationPropertyBox::setValue( const Any& rValue, const OUString& ) +{ + if (mxMetric) + { + double fValue = 0.0; + rValue >>= fValue; + ::tools::Long nValue = static_cast<::tools::Long>(fValue); + mxMetric->set_value(nValue, FieldUnit::DEGREE); + updateMenu(); + } +} + +Any SdRotationPropertyBox::getValue() +{ + return Any(static_cast<double>(mxMetric->get_value(FieldUnit::DEGREE))); +} + +namespace { + +class SdScalePropertyBox : public SdPropertySubControl +{ +public: + SdScalePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl); + + virtual Any getValue() override; + virtual void setValue( const Any& rValue, const OUString& ) override; + + DECL_LINK(implMenuSelectHdl, const OString&, void); + DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void); + + void updateMenu(); + +private: + Link<LinkParamNone*,void> maModifyHdl; + int mnDirection; + + std::unique_ptr<weld::MetricSpinButton> mxMetric; + std::unique_ptr<weld::MenuButton> mxControl; +}; + +} + +SdScalePropertyBox::SdScalePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl) + : SdPropertySubControl(pParent) + , maModifyHdl( rModifyHdl ) + , mxMetric(mxBuilder->weld_metric_spin_button("scale", FieldUnit::PERCENT)) + , mxControl(mxBuilder->weld_menu_button("scalemenu")) +{ + mxControl->connect_selected(LINK(this, SdScalePropertyBox, implMenuSelectHdl)); + mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_SCALEPROPERTYBOX); + mxControl->show(); + + mxMetric->connect_value_changed(LINK(this, SdScalePropertyBox, implModifyHdl)); + mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_SCALEPROPERTYBOX); + mxMetric->show(); + pLabel->set_mnemonic_widget(&mxMetric->get_widget()); + + setValue(rValue, OUString()); +} + +void SdScalePropertyBox::updateMenu() +{ + auto nValue = mxMetric->get_value(FieldUnit::PERCENT); + + mxControl->set_item_active("25scale", nValue == 25); + mxControl->set_item_active("50scale", nValue == 50); + mxControl->set_item_active("150scale", nValue == 150); + mxControl->set_item_active("400scale", nValue == 400); + + mxControl->set_item_active("hori", mnDirection == 1); + mxControl->set_item_active("vert", mnDirection == 2); + mxControl->set_item_active("both", mnDirection == 3); +} + +IMPL_LINK_NOARG(SdScalePropertyBox, implModifyHdl, weld::MetricSpinButton&, void) +{ + updateMenu(); + maModifyHdl.Call(nullptr); +} + +IMPL_LINK(SdScalePropertyBox, implMenuSelectHdl, const OString&, rIdent, void) +{ + auto nValue = mxMetric->get_value(FieldUnit::PERCENT); + + int nDirection = mnDirection; + + if (rIdent == "hori") + nDirection = 1; + else if (rIdent == "vert") + nDirection = 2; + else if (rIdent == "both") + nDirection = 3; + else + nValue = rIdent.toInt32(); // Getting here indicates a UI bug and should be handled better + + bool bModified = false; + + if( nDirection != mnDirection ) + { + mnDirection = nDirection; + bModified = true; + } + + if (nValue != mxMetric->get_value(FieldUnit::PERCENT)) + { + mxMetric->set_value(nValue, FieldUnit::PERCENT); + bModified = true; + } + + if(bModified) + { + implModifyHdl(*mxMetric); + updateMenu(); + } +} + +void SdScalePropertyBox::setValue(const Any& rValue, const OUString&) +{ + if (!mxMetric) + return; + + ValuePair aValues; + rValue >>= aValues; + + double fValue1 = 0.0; + double fValue2 = 0.0; + + aValues.First >>= fValue1; + aValues.Second >>= fValue2; + + // 'Size' drop down menu set by mnDirection when loading Grow and Shrink Animation + // Shouldn't compare a float directly to zero... should be fixed with delta epsilon compare + // Might be better to just have a flag in the content.xml for this + if( (fValue1 == 0.0) && (fValue2 == 0.0) ) + mnDirection = 3; // assume 'Both' scaling option when both are zero + else if( (fValue1 != 0.0) && (fValue2 == 0.0) ) + mnDirection = 1; + else if( (fValue1 == 0.0) && (fValue2 != 0.0) ) + mnDirection = 2; + else + mnDirection = 3; + + // Grow and Shrink Animation is a relative change with value stored in content.xml under tag + // smil:by=*,* + // An offset of 1 must be added to properly translate from content.xml to UI value displayed + // e.g. if in content.xml smil:by=0.5,0.5 then 1 + (0.5,0.5) = (1.5,1.5) => grow by 150% of the + // size horizontal and vertical + // e.g. if in content.xml smil:by=-0.5,-0.5 then 1 + (-0.5,-0.5) = (0.5,0.5) => shrink by 50% + // of the size horizontal and vertical + fValue1 += 1; + fValue2 += 1; + + // Determine value from file for UI 'Size' field based on determined mnDirection + ::tools::Long nValue; + if( mnDirection == 1 ) + nValue = static_cast<::tools::Long>(fValue1 * 100.0); + else if( mnDirection == 2 ) + nValue = static_cast<::tools::Long>(fValue2 * 100.0); + else if( mnDirection == 3 ){ + if (fValue1 >= fValue2) + nValue = static_cast<::tools::Long>(fValue1 * 100.0); + else + nValue = static_cast<::tools::Long>(fValue2 * 100.0); + } + else + nValue = static_cast<::tools::Long>(100.0); // default to 100% in UI if something goes wrong + + mxMetric->set_value(nValue, FieldUnit::PERCENT); + updateMenu(); +} + +Any SdScalePropertyBox::getValue() +{ + double fValue1 = static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0; + + // Grow and Shrink Animation is a relative change with value stored in content.xml under tag + // smil:by=*,* + // An offset of 1 must be subtracted to properly translate UI value displayed and save to + // content.xml + // e.g. if UI value is 150% then 1.5 - 1 = 0.5 and is set to smil:by=0.5,0.5 in content.xml + // e.g. if UI value is 50% then 0.5 - 1 = -0.5 and is set to smil:by=-0.5,-0.5 in content.xml + fValue1 -= 1; + + double fValue2 = fValue1; + + // mnDirection set by 'Size' drop down menu and used to zero out either horizontal or vertical + // scaling depending on what option is selected + if( mnDirection == 1 ) + fValue2 = 0.0; + else if( mnDirection == 2 ) + fValue1 = 0.0; + + ValuePair aValues; + aValues.First <<= fValue1; + aValues.Second <<= fValue2; + + return Any( aValues ); +} + +namespace { + +class SdFontStylePropertyBox : public SdPropertySubControl +{ +public: + SdFontStylePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl); + + virtual Any getValue() override; + virtual void setValue( const Any& rValue, const OUString& ) override; + + DECL_LINK(implMenuSelectHdl, const OString&, void); + + void update(); + +private: + float mfFontWeight; + awt::FontSlant meFontSlant; + sal_Int16 mnFontUnderline; + Link<LinkParamNone*,void> maModifyHdl; + + std::unique_ptr<weld::Entry> mxEdit; + std::unique_ptr<weld::MenuButton> mxControl; +}; + +} + +SdFontStylePropertyBox::SdFontStylePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl ) + : SdPropertySubControl(pParent) + , maModifyHdl( rModifyHdl ) + , mxEdit(mxBuilder->weld_entry("entry")) + , mxControl(mxBuilder->weld_menu_button("entrymenu")) +{ + mxEdit->set_text(SdResId(STR_CUSTOMANIMATION_SAMPLE)); + mxEdit->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTSTYLEPROPERTYBOX); + pLabel->set_mnemonic_widget(mxEdit.get()); + mxEdit->show(); + + mxControl->connect_selected(LINK(this, SdFontStylePropertyBox, implMenuSelectHdl)); + mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTSTYLEPROPERTYBOX); + mxControl->show(); + + setValue(rValue, OUString()); +} + +void SdFontStylePropertyBox::update() +{ + // update menu + mxControl->set_item_active("bold", mfFontWeight == awt::FontWeight::BOLD); + mxControl->set_item_active("italic", meFontSlant == awt::FontSlant_ITALIC); + mxControl->set_item_active("underline", mnFontUnderline != awt::FontUnderline::NONE ); + + // update sample edit + vcl::Font aFont(mxEdit->get_font()); + 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 ? LINESTYLE_NONE : LINESTYLE_SINGLE); + mxEdit->set_font(aFont); +} + +IMPL_LINK(SdFontStylePropertyBox, implMenuSelectHdl, const OString&, rIdent, void) +{ + if (rIdent == "bold") + { + if( mfFontWeight == awt::FontWeight::BOLD ) + mfFontWeight = awt::FontWeight::NORMAL; + else + mfFontWeight = awt::FontWeight::BOLD; + } + else if (rIdent == "italic") + { + if( meFontSlant == awt::FontSlant_ITALIC ) + meFontSlant = awt::FontSlant_NONE; + else + meFontSlant = awt::FontSlant_ITALIC; + } + else if (rIdent == "underline") + { + if( mnFontUnderline == awt::FontUnderline::SINGLE ) + mnFontUnderline = awt::FontUnderline::NONE; + else + mnFontUnderline = awt::FontUnderline::SINGLE; + } + + update(); + maModifyHdl.Call(nullptr); +} + +void SdFontStylePropertyBox::setValue( const Any& rValue, const OUString& ) +{ + Sequence<Any> aValues; + rValue >>= aValues; + + aValues[0] >>= mfFontWeight; + aValues[1] >>= meFontSlant; + aValues[2] >>= mnFontUnderline; + + update(); +} + +Any SdFontStylePropertyBox::getValue() +{ + Sequence<Any> aValues{ Any(mfFontWeight), Any(meFontSlant), Any(mnFontUnderline) }; + return Any( aValues ); +} + +class CustomAnimationEffectTabPage +{ +public: + CustomAnimationEffectTabPage(weld::Container* pParent, weld::Window* pDialog, const STLPropertySet* pSet); + + void update( STLPropertySet* pSet ); + DECL_LINK(implSelectHdl, weld::ComboBox&, void); + DECL_LINK(implClickHdl, weld::Button&, void); + void implHdl(const weld::Widget*); + +private: + void updateControlStates(); + void fillSoundListBox(); + void clearSoundListBox(); + sal_Int32 getSoundObject( std::u16string_view rStr ); + void openSoundFileDialog(); + void onSoundPreview(); + weld::Window* GetFrameWeld() const { return mpDialog; } + +private: + ::std::vector< OUString > maSoundList; + bool mbHasText; + const STLPropertySet* mpSet; + css::uno::Reference<css::media::XPlayer> mxPlayer; + + weld::Window* mpDialog; + std::unique_ptr<weld::Builder> mxBuilder; + std::unique_ptr<weld::Container> mxContainer; + std::unique_ptr<weld::Widget> mxSettings; + std::unique_ptr<weld::Label> mxFTProperty1; + std::unique_ptr<weld::Container> mxPlaceholderBox; + std::unique_ptr<weld::CheckButton> mxCBSmoothStart; + std::unique_ptr<weld::CheckButton> mxCBSmoothEnd; + std::unique_ptr<weld::Label> mxFTSound; + std::unique_ptr<weld::ComboBox> mxLBSound; + std::unique_ptr<weld::Button> mxPBSoundPreview; + std::unique_ptr<weld::Label> mxFTAfterEffect; + std::unique_ptr<weld::ComboBox> mxLBAfterEffect; + std::unique_ptr<weld::Label> mxFTDimColor; + std::unique_ptr<ColorListBox> mxCLBDimColor; + std::unique_ptr<weld::Label> mxFTTextAnim; + std::unique_ptr<weld::ComboBox> mxLBTextAnim; + std::unique_ptr<weld::MetricSpinButton> mxMFTextDelay; + std::unique_ptr<weld::Label> mxFTTextDelay; + std::unique_ptr<SdPropertySubControl> mxLBSubControl; +}; + +CustomAnimationEffectTabPage::CustomAnimationEffectTabPage(weld::Container* pParent, weld::Window* pDialog, const STLPropertySet* pSet) + : mbHasText(false) + , mpSet(pSet) + , mpDialog(pDialog) + , mxBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/customanimationeffecttab.ui")) + , mxContainer(mxBuilder->weld_container("EffectTab")) + , mxSettings(mxBuilder->weld_widget("settings")) + , mxFTProperty1(mxBuilder->weld_label("prop_label1")) + , mxPlaceholderBox(mxBuilder->weld_container("placeholder")) + , mxCBSmoothStart(mxBuilder->weld_check_button("smooth_start")) + , mxCBSmoothEnd(mxBuilder->weld_check_button("smooth_end")) + , mxFTSound(mxBuilder->weld_label("sound_label")) + , mxLBSound(mxBuilder->weld_combo_box("sound_list")) + , mxPBSoundPreview(mxBuilder->weld_button("sound_preview")) + , mxFTAfterEffect(mxBuilder->weld_label("aeffect_label")) + , mxLBAfterEffect(mxBuilder->weld_combo_box("aeffect_list")) + , mxFTDimColor(mxBuilder->weld_label("dim_color_label")) + , mxCLBDimColor(new ColorListBox(mxBuilder->weld_menu_button("dim_color_list"), [pDialog]{ return pDialog; })) + , mxFTTextAnim(mxBuilder->weld_label("text_animation_label")) + , mxLBTextAnim(mxBuilder->weld_combo_box("text_animation_list")) + , mxMFTextDelay(mxBuilder->weld_metric_spin_button("text_delay", FieldUnit::PERCENT)) + , mxFTTextDelay(mxBuilder->weld_label("text_delay_label")) +{ + mxCLBDimColor->SelectEntry(COL_BLACK); + + // fill the soundbox + fillSoundListBox(); + + mxLBSound->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl)); + mxPBSoundPreview->connect_clicked(LINK(this, CustomAnimationEffectTabPage, implClickHdl)); + + // 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.isEmpty() ) + { + mxSettings->show(); + mxFTProperty1->set_label(aPropertyName); + } + + // get property value + const Any aValue( pSet->getPropertyValue( nHandleProperty1Value ) ); + + // create property sub control + mxLBSubControl = SdPropertySubControl::create(nType, mxFTProperty1.get(), mxPlaceholderBox.get(), mpDialog, aValue, aPresetId, Link<LinkParamNone*,void>()); + } + } + + mxFTProperty1->set_sensitive(mxPlaceholderBox->get_sensitive()); + + // accelerate & decelerate + + if( pSet->getPropertyState( nHandleAccelerate ) == STLPropertyState::Direct ) + { + mxCBSmoothStart->show(); + mxCBSmoothEnd->show(); + + double fTemp = 0.0; + pSet->getPropertyValue( nHandleAccelerate ) >>= fTemp; + mxCBSmoothStart->set_active( fTemp > 0.0 ); + + pSet->getPropertyValue( nHandleDecelerate ) >>= fTemp; + mxCBSmoothEnd->set_active( fTemp > 0.0 ); + } + } + + // init after effect controls + + mxLBAfterEffect->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl)); + mxLBTextAnim->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl)); + + if( (pSet->getPropertyState( nHandleHasAfterEffect ) != STLPropertyState::Ambiguous) && + (pSet->getPropertyState( nHandleAfterEffectOnNextEffect ) != STLPropertyState::Ambiguous) && + (pSet->getPropertyState( nHandleDimColor ) != STLPropertyState::Ambiguous)) + { + bool bHasAfterEffect = false; + pSet->getPropertyValue( nHandleHasAfterEffect ) >>= bHasAfterEffect; + + sal_Int32 nPos = 0; + if( bHasAfterEffect ) + { + nPos++; + + bool bAfterEffectOnNextClick = false; + pSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bAfterEffectOnNextClick; + Any aDimColor( pSet->getPropertyValue( nHandleDimColor ) ); + + if( aDimColor.hasValue() ) + { + Color aColor; + aDimColor >>= aColor; + mxCLBDimColor->SelectEntry(aColor); + } + else + { + nPos++; + if( bAfterEffectOnNextClick ) + nPos++; + } + } + + mxLBAfterEffect->set_active(nPos); + } + + if( pSet->getPropertyState( nHandleHasText ) != STLPropertyState::Ambiguous ) + pSet->getPropertyValue( nHandleHasText ) >>= mbHasText; + + if( mbHasText ) + { + if( pSet->getPropertyState( nHandleIterateType ) != STLPropertyState::Ambiguous) + { + int nPos = -1; + + 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; + } + + mxLBTextAnim->set_active(nPos); + } + + if( pSet->getPropertyState( nHandleIterateInterval ) != STLPropertyState::Default ) + { + double fIterateInterval = 0.0; + pSet->getPropertyValue( nHandleIterateInterval ) >>= fIterateInterval; + mxMFTextDelay->set_value(static_cast<::tools::Long>(fIterateInterval*10), FieldUnit::NONE); + } + } + else + { + mxFTTextAnim->set_sensitive(false); + mxLBTextAnim->set_sensitive(false); + mxMFTextDelay->set_sensitive(false); + mxFTTextDelay->set_sensitive(false); + + } + + if( pSet->getPropertyState( nHandleSoundURL ) != STLPropertyState::Ambiguous ) + { + sal_Int32 nPos = 0; + + const Any aValue( pSet->getPropertyValue( nHandleSoundURL ) ); + + if( aValue.getValueType() == ::cppu::UnoType<sal_Bool>::get() ) + { + nPos = 1; + } + else + { + OUString aSoundURL; + aValue >>= aSoundURL; + + if( !aSoundURL.isEmpty() ) + { + sal_uLong i; + for( i = 0; i < maSoundList.size(); i++ ) + { + OUString aString = maSoundList[ i ]; + if( aString == aSoundURL ) + { + nPos = static_cast<sal_Int32>(i)+2; + break; + } + } + + if( nPos == 0 ) + { + nPos = static_cast<sal_Int32>(maSoundList.size())+2; + maSoundList.push_back( aSoundURL ); + INetURLObject aURL( aSoundURL ); + mxLBSound->insert_text(nPos, aURL.GetBase()); + } + } + } + + if( nPos != -1) + mxLBSound->set_active(nPos); + } + + updateControlStates(); + +} + +void CustomAnimationEffectTabPage::updateControlStates() +{ + auto nPos = mxLBAfterEffect->get_active(); + mxCLBDimColor->set_sensitive( nPos == 1 ); + mxFTDimColor->set_sensitive( nPos == 1 ); + + if( mbHasText ) + { + nPos = mxLBTextAnim->get_active(); + mxMFTextDelay->set_sensitive( nPos != 0 ); + mxFTTextDelay->set_sensitive( nPos != 0 ); + } + + if (comphelper::LibreOfficeKit::isActive()) + { + mxFTSound->hide(); + mxLBSound->hide(); + mxPBSoundPreview->hide(); + } + else + { + nPos = mxLBSound->get_active(); + mxPBSoundPreview->set_sensitive( nPos >= 2 ); + } + +} + +IMPL_LINK(CustomAnimationEffectTabPage, implClickHdl, weld::Button&, rBtn, void) +{ + implHdl(&rBtn); +} + +IMPL_LINK(CustomAnimationEffectTabPage, implSelectHdl, weld::ComboBox&, rListBox, void) +{ + implHdl(&rListBox); +} + +void CustomAnimationEffectTabPage::implHdl(const weld::Widget* pControl) +{ + if (pControl == mxLBTextAnim.get()) + { + if (mxMFTextDelay->get_value(FieldUnit::NONE) == 0) + mxMFTextDelay->set_value(100, FieldUnit::NONE); + } + else if (pControl == mxLBSound.get()) + { + auto nPos = mxLBSound->get_active(); + if (nPos == (mxLBSound->get_count() - 1)) + { + openSoundFileDialog(); + } + } + else if (pControl == mxPBSoundPreview.get()) + { + onSoundPreview(); + } + + updateControlStates(); +} + +void CustomAnimationEffectTabPage::update( STLPropertySet* pSet ) +{ + if (mxLBSubControl) + { + Any aNewValue(mxLBSubControl->getValue()); + Any aOldValue; + if( mpSet->getPropertyState( nHandleProperty1Value ) != STLPropertyState::Ambiguous) + aOldValue = mpSet->getPropertyValue( nHandleProperty1Value ); + + if( aOldValue != aNewValue ) + pSet->setPropertyValue( nHandleProperty1Value, aNewValue ); + } + + if (mxCBSmoothStart->get_visible()) + { + // set selected value for accelerate if different than in original set + + double fTemp = mxCBSmoothStart->get_active() ? 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, Any( fTemp ) ); + + // set selected value for decelerate if different than in original set + fTemp = mxCBSmoothEnd->get_active() ? 0.5 : 0.0; + + if(mpSet->getPropertyState( nHandleDecelerate ) != STLPropertyState::Ambiguous) + mpSet->getPropertyValue( nHandleDecelerate ) >>= fOldTemp; + else + fOldTemp = -2.0; + + if( fOldTemp != fTemp ) + pSet->setPropertyValue( nHandleDecelerate, Any( fTemp ) ); + } + + auto nPos = mxLBAfterEffect->get_active(); + if (nPos != -1) + { + bool bAfterEffect = nPos != 0; + + bool bOldAfterEffect = false; + + if(mpSet->getPropertyState( nHandleHasAfterEffect ) != STLPropertyState::Ambiguous) + mpSet->getPropertyValue( nHandleHasAfterEffect ) >>= bOldAfterEffect; + else + bOldAfterEffect = !bAfterEffect; + + if( bOldAfterEffect != bAfterEffect ) + pSet->setPropertyValue( nHandleHasAfterEffect, Any( bAfterEffect ) ); + + Any aDimColor; + if( nPos == 1 ) + { + Color aSelectedColor = mxCLBDimColor->GetSelectEntryColor(); + aDimColor <<= aSelectedColor.GetRGBColor(); + } + + if( (mpSet->getPropertyState( nHandleDimColor ) == STLPropertyState::Ambiguous) || + (mpSet->getPropertyValue( nHandleDimColor ) != aDimColor) ) + pSet->setPropertyValue( nHandleDimColor, aDimColor ); + + bool bAfterEffectOnNextEffect = nPos != 2; + bool bOldAfterEffectOnNextEffect = !bAfterEffectOnNextEffect; + + if( mpSet->getPropertyState( nHandleAfterEffectOnNextEffect ) != STLPropertyState::Ambiguous) + mpSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bOldAfterEffectOnNextEffect; + + if( bAfterEffectOnNextEffect != bOldAfterEffectOnNextEffect ) + pSet->setPropertyValue( nHandleAfterEffectOnNextEffect, Any( bAfterEffectOnNextEffect ) ); + } + + nPos = mxLBTextAnim->get_active(); + if (nPos != -1) + { + 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, Any( nIterateType ) ); + } + + { + double fIterateInterval = static_cast<double>(mxMFTextDelay->get_value(FieldUnit::NONE)) / 10; + double fOldIterateInterval = -1.0; + + if( mpSet->getPropertyState( nHandleIterateInterval ) != STLPropertyState::Ambiguous ) + mpSet->getPropertyValue( nHandleIterateInterval ) >>= fOldIterateInterval; + + if( fIterateInterval != fOldIterateInterval ) + pSet->setPropertyValue( nHandleIterateInterval, Any( fIterateInterval ) ); + } + + nPos = mxLBSound->get_active(); + if (nPos == -1) + return; + + Any aNewSoundURL, aOldSoundURL( Any( sal_Int32(0) ) ); + + if( nPos == 0 ) + { + // 0 means no sound, so leave any empty + } + else if( nPos == 1 ) + { + // this means stop sound + aNewSoundURL <<= true; + } + else + { + OUString aSoundURL( maSoundList[ nPos-2 ] ); + aNewSoundURL <<= aSoundURL; + } + + if( mpSet->getPropertyState( nHandleSoundURL ) != STLPropertyState::Ambiguous ) + aOldSoundURL = mpSet->getPropertyValue( nHandleSoundURL ); + + if( aNewSoundURL != aOldSoundURL ) + pSet->setPropertyValue( nHandleSoundURL, aNewSoundURL ); +} + +void CustomAnimationEffectTabPage::fillSoundListBox() +{ + GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, maSoundList ); + GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, maSoundList ); + + mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_NO_SOUND) ); + mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_STOP_PREVIOUS_SOUND) ); + for(const OUString & rString : maSoundList) + { + INetURLObject aURL( rString ); + mxLBSound->append_text( aURL.GetBase() ); + } + mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_BROWSE_SOUND) ); +} + +void CustomAnimationEffectTabPage::clearSoundListBox() +{ + maSoundList.clear(); + mxLBSound->clear(); +} + +sal_Int32 CustomAnimationEffectTabPage::getSoundObject( std::u16string_view rStr ) +{ + size_t i; + const size_t nCount = maSoundList.size(); + for( i = 0; i < nCount; i++ ) + { + if( maSoundList[ i ].equalsIgnoreAsciiCase(rStr) ) + return i+2; + } + + return -1; +} + +void CustomAnimationEffectTabPage::openSoundFileDialog() +{ + SdOpenSoundFileDialog aFileDialog(GetFrameWeld()); + + bool bValidSoundFile = false; + bool bQuitLoop = false; + ::tools::Long nPos = 0; + + while( !bQuitLoop && (aFileDialog.Execute() == ERRCODE_NONE) ) + { + OUString aFile = aFileDialog.GetPath(); + nPos = getSoundObject( aFile ); + + if( nPos < 0 ) // not in Soundliste + { + // try to insert in Gallery + if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile ) ) + { + clearSoundListBox(); + fillSoundListBox(); + + nPos = getSoundObject( aFile ); + DBG_ASSERT( nPos >= 0, "sd::CustomAnimationEffectTabPage::openSoundFileDialog(), Recently inserted sound not in list!" ); + + bValidSoundFile=true; + bQuitLoop=true; + } + else + { + OUString aStrWarning(SdResId(STR_WARNING_NOSOUNDFILE)); + aStrWarning = aStrWarning.replaceFirst("%", aFile); + std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(nullptr, + VclMessageType::Warning, VclButtonsType::NONE, + aStrWarning)); + xWarn->add_button(GetStandardText(StandardButtonType::Retry), RET_RETRY); + xWarn->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL); + bQuitLoop = xWarn->run() != RET_RETRY; + + bValidSoundFile=false; + } + } + else + { + bValidSoundFile=true; + bQuitLoop=true; + } + } + + if( !bValidSoundFile ) + nPos = 0; + + mxLBSound->set_active(nPos); +} + +void CustomAnimationEffectTabPage::onSoundPreview() +{ +#if HAVE_FEATURE_AVMEDIA + const auto nPos = mxLBSound->get_active(); + + if( nPos >= 2 ) try + { + const OUString aSoundURL( maSoundList[ nPos-2 ] ); + mxPlayer.set( avmedia::MediaWindow::createPlayer( aSoundURL, "" ), uno::UNO_SET_THROW ); + mxPlayer->start(); + } + catch( uno::Exception& ) + { + TOOLS_WARN_EXCEPTION( "sd", "CustomAnimationEffectTabPage::onSoundPreview()" ); + } +#endif +} + +class CustomAnimationDurationTabPage +{ +public: + CustomAnimationDurationTabPage(weld::Container* pParent, const STLPropertySet* pSet); + + void update( STLPropertySet* pSet ); + + DECL_LINK(implControlHdl, weld::ComboBox&, void); + DECL_LINK(DurationModifiedHdl, weld::MetricSpinButton&, void); + +private: + const STLPropertySet* mpSet; + + std::unique_ptr<weld::Builder> mxBuilder; + std::unique_ptr<weld::Container> mxContainer; + std::unique_ptr<weld::Label> mxFTStart; + std::unique_ptr<weld::ComboBox> mxLBStart; + std::unique_ptr<weld::Label> mxFTStartDelay; + std::unique_ptr<weld::MetricSpinButton> mxMFStartDelay; + std::unique_ptr<weld::Label> mxFTDuration; + std::unique_ptr<weld::MetricSpinButton> mxCBXDuration; + std::unique_ptr<weld::Label> mxFTRepeat; + std::unique_ptr<weld::ComboBox> mxCBRepeat; + std::unique_ptr<weld::CheckButton> mxCBXRewind; + std::unique_ptr<weld::RadioButton> mxRBClickSequence; + std::unique_ptr<weld::RadioButton> mxRBInteractive; + std::unique_ptr<weld::ComboBox> mxLBTrigger; +}; + +CustomAnimationDurationTabPage::CustomAnimationDurationTabPage(weld::Container* pParent, const STLPropertySet* pSet) + : mpSet(pSet) + , mxBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/customanimationtimingtab.ui")) + , mxContainer(mxBuilder->weld_container("TimingTab")) + , mxFTStart(mxBuilder->weld_label("start_label")) + , mxLBStart(mxBuilder->weld_combo_box("start_list")) + , mxFTStartDelay(mxBuilder->weld_label("delay_label")) + , mxMFStartDelay(mxBuilder->weld_metric_spin_button("delay_value", FieldUnit::SECOND)) + , mxFTDuration(mxBuilder->weld_label("duration_label")) + , mxCBXDuration(mxBuilder->weld_metric_spin_button("anim_duration", FieldUnit::SECOND)) + , mxFTRepeat(mxBuilder->weld_label("repeat_label")) + , mxCBRepeat(mxBuilder->weld_combo_box("repeat_list")) + , mxCBXRewind(mxBuilder->weld_check_button("rewind")) + , mxRBClickSequence(mxBuilder->weld_radio_button("rb_click_sequence")) + , mxRBInteractive(mxBuilder->weld_radio_button("rb_interactive")) + , mxLBTrigger(mxBuilder->weld_combo_box("trigger_list")) +{ + mxLBTrigger->set_size_request(mxLBTrigger->get_approximate_digit_width() * 20, -1); + + fillRepeatComboBox(*mxCBRepeat); + + mxLBTrigger->connect_changed(LINK(this, CustomAnimationDurationTabPage, implControlHdl)); + mxCBXDuration->connect_value_changed(LINK( this, CustomAnimationDurationTabPage, DurationModifiedHdl)); + + if( pSet->getPropertyState( nHandleStart ) != STLPropertyState::Ambiguous ) + { + sal_Int16 nStart = 0; + pSet->getPropertyValue( nHandleStart ) >>= nStart; + sal_Int32 nPos = 0; + switch( nStart ) + { + case EffectNodeType::WITH_PREVIOUS: nPos = 1; break; + case EffectNodeType::AFTER_PREVIOUS: nPos = 2; break; + } + mxLBStart->set_active(nPos); + } + + if( pSet->getPropertyState( nHandleBegin ) != STLPropertyState::Ambiguous ) + { + double fBegin = 0.0; + pSet->getPropertyValue( nHandleBegin ) >>= fBegin; + mxMFStartDelay->set_value(static_cast<::tools::Long>(fBegin*10), FieldUnit::NONE); + } + + if( pSet->getPropertyState( nHandleDuration ) != STLPropertyState::Ambiguous ) + { + double fDuration = 0.0; + pSet->getPropertyValue( nHandleDuration ) >>= fDuration; + + if( fDuration == 0.001 ) + { + mxFTDuration->set_sensitive(false); + mxCBXDuration->set_sensitive(false); + mxFTRepeat->set_sensitive(false); + mxCBRepeat->set_sensitive(false); + mxCBXRewind->set_sensitive(false); + } + else + { + mxCBXDuration->set_value(fDuration * 100.0, FieldUnit::NONE); + } + } + + if( pSet->getPropertyState( nHandleRepeat ) != STLPropertyState::Ambiguous ) + { + Any aRepeatCount( pSet->getPropertyValue( nHandleRepeat ) ); + if( (aRepeatCount.getValueType() == ::cppu::UnoType<double>::get()) || !aRepeatCount.hasValue() ) + { + double fRepeat = 0.0; + if( aRepeatCount.hasValue() ) + aRepeatCount >>= fRepeat; + + auto nPos = -1; + + 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 != -1) + mxCBRepeat->set_active(nPos); + else + mxCBRepeat->set_entry_text(OUString::number(fRepeat)); + } + else if( aRepeatCount.getValueType() == ::cppu::UnoType<Timing>::get() ) + { + Any aEnd; + if( pSet->getPropertyState( nHandleEnd ) != STLPropertyState::Ambiguous ) + aEnd = pSet->getPropertyValue( nHandleEnd ); + + mxCBRepeat->set_active(aEnd.hasValue() ? 6 : 7); + } + } + + if( pSet->getPropertyState( nHandleRewind ) != STLPropertyState::Ambiguous ) + { + sal_Int16 nFill = 0; + if( pSet->getPropertyValue( nHandleRewind ) >>= nFill ) + { + mxCBXRewind->set_active(nFill == AnimationFill::REMOVE); + } + else + { + mxCBXRewind->set_state(TRISTATE_INDET); + } + } + + Reference< XShape > xTrigger; + + if( pSet->getPropertyState( nHandleTrigger ) != STLPropertyState::Ambiguous ) + { + pSet->getPropertyValue( nHandleTrigger ) >>= xTrigger; + + mxRBInteractive->set_active(xTrigger.is()); + mxRBClickSequence->set_active(!xTrigger.is()); + } + + Reference< XDrawPage > xCurrentPage; + pSet->getPropertyValue( nHandleCurrentPage ) >>= xCurrentPage; + if( !xCurrentPage.is() ) + return; + + static const OUStringLiteral aStrIsEmptyPresObj( u"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 ) ) + { + bool bIsEmpty = false; + xSet->getPropertyValue( aStrIsEmptyPresObj ) >>= bIsEmpty; + if( bIsEmpty ) + continue; + } + + OUString aDescription( getShapeDescription( xShape, true ) ); + mxLBTrigger->append(OUString::number(nShape), aDescription); + auto nPos = mxLBTrigger->get_count() - 1; + if (xShape == xTrigger) + mxLBTrigger->set_active(nPos); + } +} + +IMPL_LINK_NOARG(CustomAnimationDurationTabPage, implControlHdl, weld::ComboBox&, void) +{ + mxRBInteractive->set_active(true); + assert(!mxRBClickSequence->get_active()); +} + +IMPL_LINK_NOARG(CustomAnimationDurationTabPage, DurationModifiedHdl, weld::MetricSpinButton&, void) +{ + if (!mxCBXDuration->get_text().isEmpty()) + { + double duration_value = static_cast<double>(mxCBXDuration->get_value(FieldUnit::NONE)); + if(duration_value <= 0.0) + mxCBXDuration->set_value(1, FieldUnit::NONE); + else + mxCBXDuration->set_value(duration_value, FieldUnit::NONE); + } +} + +void CustomAnimationDurationTabPage::update( STLPropertySet* pSet ) +{ + auto nPos = mxLBStart->get_active(); + if (nPos != -1) + { + 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, Any( nStart ) ); + } + + { + double fBegin = static_cast<double>(mxMFStartDelay->get_value(FieldUnit::NONE)) / 10.0; + double fOldBegin = -1.0; + + if( mpSet->getPropertyState( nHandleBegin ) != STLPropertyState::Ambiguous ) + mpSet->getPropertyValue( nHandleBegin ) >>= fOldBegin; + + if( fBegin != fOldBegin ) + pSet->setPropertyValue( nHandleBegin, Any( fBegin ) ); + } + + nPos = mxCBRepeat->get_active(); + if (nPos != -1 || !mxCBRepeat->get_active_text().isEmpty()) + { + Any aRepeatCount; + Any aEnd; + + switch( nPos ) + { + case 0: + break; + + case 6: + { + Event aEvent; + aEvent.Trigger = EventTrigger::ON_NEXT; + aEvent.Repeat = 0; + aEnd <<= aEvent; + } + [[fallthrough]]; + case 7: + aRepeatCount <<= Timing_INDEFINITE; + break; + default: + { + OUString aText(mxCBRepeat->get_text(nPos)); + if( !aText.isEmpty() ) + 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; + + if (!mxCBXDuration->get_text().isEmpty()) + { + double duration_value = static_cast<double>(mxCBXDuration->get_value(FieldUnit::NONE)); + + if(duration_value > 0) + fDuration = duration_value/100.0; + } + + if( fDuration != -1.0 ) + { + double fOldDuration = -1; + + if( mpSet->getPropertyState( nHandleDuration ) != STLPropertyState::Ambiguous ) + mpSet->getPropertyValue( nHandleDuration ) >>= fOldDuration; + + if( fDuration != fOldDuration ) + pSet->setPropertyValue( nHandleDuration, Any( fDuration ) ); + } + + if (mxCBXRewind->get_state() != TRISTATE_INDET) + { + sal_Int16 nFill = mxCBXRewind->get_active() ? 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, Any( nFill ) ); + } + + Reference< XShape > xTrigger; + + if (mxRBInteractive->get_active()) + { + nPos = mxLBTrigger->get_active(); + if (nPos != -1) + { + sal_Int32 nShape = mxLBTrigger->get_id(nPos).toInt32(); + + Reference< XDrawPage > xCurrentPage; + mpSet->getPropertyValue( nHandleCurrentPage ) >>= xCurrentPage; + + if( xCurrentPage.is() && (nShape >= 0) && (nShape < xCurrentPage->getCount()) ) + xCurrentPage->getByIndex( nShape ) >>= xTrigger; + } + } + + if (xTrigger.is() || mxRBClickSequence->get_active()) + { + Any aNewValue( xTrigger ); + Any aOldValue; + + if( mpSet->getPropertyState( nHandleTrigger ) != STLPropertyState::Ambiguous ) + aOldValue = mpSet->getPropertyValue( nHandleTrigger ); + + if( aNewValue != aOldValue ) + pSet->setPropertyValue( nHandleTrigger, aNewValue ); + } +} + +class CustomAnimationTextAnimTabPage +{ +public: + CustomAnimationTextAnimTabPage(weld::Container* pParent, const STLPropertySet* pSet); + + void update( STLPropertySet* pSet ); + + void updateControlStates(); + DECL_LINK(implSelectHdl, weld::ComboBox&, void); + +private: + const STLPropertySet* mpSet; + bool mbHasVisibleShapes; + + std::unique_ptr<weld::Builder> mxBuilder; + std::unique_ptr<weld::Container> mxContainer; + std::unique_ptr<weld::Label> mxFTGroupText; + std::unique_ptr<weld::ComboBox> mxLBGroupText; + std::unique_ptr<weld::CheckButton> mxCBXGroupAuto; + std::unique_ptr<weld::MetricSpinButton> mxMFGroupAuto; + std::unique_ptr<weld::CheckButton> mxCBXAnimateForm; + std::unique_ptr<weld::CheckButton> mxCBXReverse; +}; + +CustomAnimationTextAnimTabPage::CustomAnimationTextAnimTabPage(weld::Container* pParent, const STLPropertySet* pSet) + : mpSet(pSet) + , mbHasVisibleShapes(true) + , mxBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/customanimationtexttab.ui")) + , mxContainer(mxBuilder->weld_container("TextAnimationTab")) + , mxFTGroupText(mxBuilder->weld_label("group_text_label")) + , mxLBGroupText(mxBuilder->weld_combo_box("group_text_list")) + , mxCBXGroupAuto(mxBuilder->weld_check_button("auto_after")) + , mxMFGroupAuto(mxBuilder->weld_metric_spin_button("auto_after_value",FieldUnit::SECOND)) + , mxCBXAnimateForm(mxBuilder->weld_check_button("animate_shape")) + , mxCBXReverse(mxBuilder->weld_check_button("reverse_order")) +{ + mxLBGroupText->connect_changed(LINK(this, CustomAnimationTextAnimTabPage, implSelectHdl)); + + if( pSet->getPropertyState( nHandleTextGrouping ) != STLPropertyState::Ambiguous ) + { + sal_Int32 nTextGrouping = 0; + if( pSet->getPropertyValue( nHandleTextGrouping ) >>= nTextGrouping ) + mxLBGroupText->set_active(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 ) + { + mxCBXGroupAuto->set_active(fTextGroupingAuto >= 0.0); + if( fTextGroupingAuto >= 0.0 ) + mxMFGroupAuto->set_value(static_cast<::tools::Long>(fTextGroupingAuto*10), FieldUnit::NONE); + } + } + else + { + mxCBXGroupAuto->set_state( TRISTATE_INDET ); + } + + mxCBXAnimateForm->set_state( TRISTATE_INDET ); + if( pSet->getPropertyState( nHandleAnimateForm ) != STLPropertyState::Ambiguous ) + { + bool bAnimateForm = false; + if( pSet->getPropertyValue( nHandleAnimateForm ) >>= bAnimateForm ) + { + mxCBXAnimateForm->set_active( bAnimateForm ); + } + } + else + { + mxCBXAnimateForm->set_sensitive(false); + } + + mxCBXReverse->set_state(TRISTATE_INDET); + if( pSet->getPropertyState( nHandleTextReverse ) != STLPropertyState::Ambiguous ) + { + bool bTextReverse = false; + if( pSet->getPropertyValue( nHandleTextReverse ) >>= bTextReverse ) + { + mxCBXReverse->set_active( 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) ) + { + mxLBGroupText->remove(nPos); + nPos--; + } + } + + updateControlStates(); +} + +void CustomAnimationTextAnimTabPage::update( STLPropertySet* pSet ) +{ + auto nPos = mxLBGroupText->get_active(); + if (nPos != -1) + { + 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, Any( nTextGrouping ) ); + } + + if (nPos != 0) + { + bool bTextReverse = mxCBXReverse->get_active(); + bool bOldTextReverse = !bTextReverse; + + if(mpSet->getPropertyState( nHandleTextReverse ) != STLPropertyState::Ambiguous) + mpSet->getPropertyValue( nHandleTextReverse ) >>= bOldTextReverse; + + if( bTextReverse != bOldTextReverse ) + pSet->setPropertyValue( nHandleTextReverse, Any( bTextReverse ) ); + + if( nPos > 1 ) + { + double fTextGroupingAuto = mxCBXGroupAuto->get_active() ? mxMFGroupAuto->get_value(FieldUnit::NONE) / 10.0 : -1.0; + double fOldTextGroupingAuto = -2.0; + + if(mpSet->getPropertyState( nHandleTextGroupingAuto ) != STLPropertyState::Ambiguous) + mpSet->getPropertyValue( nHandleTextGroupingAuto ) >>= fOldTextGroupingAuto; + + if( fTextGroupingAuto != fOldTextGroupingAuto ) + pSet->setPropertyValue( nHandleTextGroupingAuto, Any( fTextGroupingAuto ) ); + } + } + //#i120049# impress crashes when modifying the "Random effects" animation + //effect's trigger condition to "Start effect on click of". + //If this control is disabled, we should ignore its value + if (mxCBXAnimateForm->get_sensitive()) + { + bool bAnimateForm = mxCBXAnimateForm->get_active(); + bool bOldAnimateForm = !bAnimateForm; + + if(mpSet->getPropertyState( nHandleAnimateForm ) != STLPropertyState::Ambiguous) + mpSet->getPropertyValue( nHandleAnimateForm ) >>= bOldAnimateForm; + + if( bAnimateForm != bOldAnimateForm ) + pSet->setPropertyValue( nHandleAnimateForm, Any( bAnimateForm ) ); + } +} + +void CustomAnimationTextAnimTabPage::updateControlStates() +{ + auto nPos = mxLBGroupText->get_active(); + + mxCBXGroupAuto->set_sensitive( nPos > 1 ); + mxMFGroupAuto->set_sensitive( nPos > 1 ); + mxCBXReverse->set_sensitive( nPos > 0 ); + + if( !mbHasVisibleShapes && nPos > 0 ) + { + mxCBXAnimateForm->set_active(false); + mxCBXAnimateForm->set_sensitive(false); + } + else + { + mxCBXAnimateForm->set_sensitive(true); + } +} + +IMPL_LINK_NOARG(CustomAnimationTextAnimTabPage, implSelectHdl, weld::ComboBox&, void) +{ + updateControlStates(); +} + +CustomAnimationDialog::CustomAnimationDialog(weld::Window* pParent, std::unique_ptr<STLPropertySet> pSet, const OString& rPage) + : GenericDialogController(pParent, "modules/simpress/ui/customanimationproperties.ui", "CustomAnimationProperties") + , mxSet(std::move(pSet)) + , mxTabControl(m_xBuilder->weld_notebook("tabcontrol")) + , mxDurationTabPage(new CustomAnimationDurationTabPage(mxTabControl->get_page("timing"), mxSet.get())) + , mxEffectTabPage(new CustomAnimationEffectTabPage(mxTabControl->get_page("effect"), m_xDialog.get(), mxSet.get())) +{ + bool bHasText = false; + if( mxSet->getPropertyState( nHandleHasText ) != STLPropertyState::Ambiguous ) + mxSet->getPropertyValue( nHandleHasText ) >>= bHasText; + + if( bHasText ) + { + mxTextAnimTabPage.reset(new CustomAnimationTextAnimTabPage(mxTabControl->get_page("textanim"), mxSet.get())); + } + else + { + mxTabControl->remove_page("textanim"); + } + + if (!rPage.isEmpty()) + mxTabControl->set_current_page(rPage); +} + +CustomAnimationDialog::~CustomAnimationDialog() +{ +} + +STLPropertySet* CustomAnimationDialog::getResultSet() +{ + mxResultSet = createDefaultSet(); + + mxEffectTabPage->update( mxResultSet.get() ); + mxDurationTabPage->update( mxResultSet.get() ); + if (mxTextAnimTabPage) + mxTextAnimTabPage->update( mxResultSet.get() ); + + return mxResultSet.get(); +} + +std::unique_ptr<STLPropertySet> CustomAnimationDialog::createDefaultSet() +{ + Any aEmpty; + + std::unique_ptr<STLPropertySet> pSet(new STLPropertySet()); + pSet->setPropertyDefaultValue( nHandleMaxParaDepth, Any( sal_Int32(-1) ) ); + + pSet->setPropertyDefaultValue( nHandleHasAfterEffect, Any( false ) ); + pSet->setPropertyDefaultValue( nHandleAfterEffectOnNextEffect, Any( false ) ); + pSet->setPropertyDefaultValue( nHandleDimColor, aEmpty ); + pSet->setPropertyDefaultValue( nHandleIterateType, Any( sal_Int16(0) ) ); + pSet->setPropertyDefaultValue( nHandleIterateInterval, Any( 0.0 ) ); + + pSet->setPropertyDefaultValue( nHandleStart, Any( sal_Int16(EffectNodeType::ON_CLICK) ) ); + pSet->setPropertyDefaultValue( nHandleBegin, Any( 0.0 ) ); + pSet->setPropertyDefaultValue( nHandleDuration, Any( 2.0 ) ); + pSet->setPropertyDefaultValue( nHandleRepeat, aEmpty ); + pSet->setPropertyDefaultValue( nHandleRewind, Any( AnimationFill::HOLD ) ); + + pSet->setPropertyDefaultValue( nHandleEnd, aEmpty ); + + pSet->setPropertyDefaultValue( nHandlePresetId, aEmpty ); + pSet->setPropertyDefaultValue( nHandleProperty1Type, Any( nPropertyTypeNone ) ); + pSet->setPropertyDefaultValue( nHandleProperty1Value, aEmpty ); + pSet->setPropertyDefaultValue( nHandleProperty2Type, Any( nPropertyTypeNone ) ); + pSet->setPropertyDefaultValue( nHandleProperty2Value, aEmpty ); + pSet->setPropertyDefaultValue( nHandleAccelerate, aEmpty ); + pSet->setPropertyDefaultValue( nHandleDecelerate, aEmpty ); + pSet->setPropertyDefaultValue( nHandleAutoReverse, aEmpty ); + pSet->setPropertyDefaultValue( nHandleTrigger, aEmpty ); + + pSet->setPropertyDefaultValue( nHandleHasText, Any( false ) ); + pSet->setPropertyDefaultValue( nHandleHasVisibleShape, Any( false ) ); + pSet->setPropertyDefaultValue( nHandleTextGrouping, Any( sal_Int32(-1) ) ); + pSet->setPropertyDefaultValue( nHandleAnimateForm, Any( true ) ); + pSet->setPropertyDefaultValue( nHandleTextGroupingAuto, Any( -1.0 ) ); + pSet->setPropertyDefaultValue( nHandleTextReverse, Any( false ) ); + + pSet->setPropertyDefaultValue( nHandleCurrentPage, aEmpty ); + + pSet->setPropertyDefaultValue( nHandleSoundURL, aEmpty ); + pSet->setPropertyDefaultValue( nHandleSoundVolume, Any( 1.0) ); + pSet->setPropertyDefaultValue( nHandleSoundEndAfterSlide, Any( sal_Int32(0) ) ); + + pSet->setPropertyDefaultValue( nHandleCommand, Any( sal_Int16(0) ) ); + return pSet; +} + +std::unique_ptr<SdPropertySubControl> SdPropertySubControl::create(sal_Int32 nType, weld::Label* pLabel, weld::Container* pParent, weld::Window* pTopLevel, const Any& rValue, const OUString& rPresetId, const Link<LinkParamNone*,void>& rModifyHdl) +{ + std::unique_ptr<SdPropertySubControl> pSubControl; + switch( nType ) + { + case nPropertyTypeDirection: + case nPropertyTypeSpokes: + case nPropertyTypeZoom: + pSubControl.reset( new SdPresetPropertyBox( pLabel, pParent, rValue, rPresetId, rModifyHdl ) ); + break; + + case nPropertyTypeColor: + case nPropertyTypeFillColor: + case nPropertyTypeFirstColor: + case nPropertyTypeCharColor: + case nPropertyTypeLineColor: + pSubControl.reset( new SdColorPropertyBox( pLabel, pParent, pTopLevel, rValue, rModifyHdl ) ); + break; + + case nPropertyTypeFont: + pSubControl.reset( new SdFontPropertyBox( pLabel, pParent, rValue, rModifyHdl ) ); + break; + + case nPropertyTypeCharHeight: + pSubControl.reset( new SdCharHeightPropertyBox( pLabel, pParent, rValue, rModifyHdl ) ); + break; + + case nPropertyTypeRotate: + pSubControl.reset( new SdRotationPropertyBox( pLabel, pParent, rValue, rModifyHdl ) ); + break; + + case nPropertyTypeTransparency: + pSubControl.reset( new SdTransparencyPropertyBox( pLabel, pParent, rValue, rModifyHdl ) ); + break; + + case nPropertyTypeScale: + pSubControl.reset( new SdScalePropertyBox( pLabel, pParent, rValue, rModifyHdl ) ); + break; + + case nPropertyTypeCharDecoration: + pSubControl.reset( new SdFontStylePropertyBox( pLabel, pParent, rValue, rModifyHdl ) ); + break; + } + + return pSubControl; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |