cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / animations / CustomAnimationDialog.cxx
blobf769f5b87c06edfea355bd343f8e9e4d6e22b355
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include <com/sun/star/presentation/EffectNodeType.hpp>
23 #include <com/sun/star/animations/Timing.hpp>
24 #include <com/sun/star/animations/Event.hpp>
25 #include <com/sun/star/animations/EventTrigger.hpp>
26 #include <com/sun/star/animations/AnimationFill.hpp>
27 #include <com/sun/star/presentation/TextAnimationType.hpp>
28 #include <com/sun/star/animations/ValuePair.hpp>
29 #include <com/sun/star/awt/FontSlant.hpp>
30 #include <com/sun/star/awt/FontWeight.hpp>
31 #include <com/sun/star/awt/FontUnderline.hpp>
32 #include <com/sun/star/drawing/XDrawPage.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/media/XPlayer.hpp>
36 #include <memory>
38 #include <comphelper/lok.hxx>
39 #include <i18nutil/unicode.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/stdtext.hxx>
42 #include <vcl/weld.hxx>
43 #include <vcl/settings.hxx>
45 #include <svtools/ctrltool.hxx>
46 #include <sfx2/objsh.hxx>
47 #include <sfx2/viewsh.hxx>
48 #include <tools/debug.hxx>
49 #include <tools/urlobj.hxx>
50 #include <comphelper/diagnose_ex.hxx>
52 #include <editeng/flstitem.hxx>
54 #include <svx/colorbox.hxx>
55 #include <svx/gallery.hxx>
57 #include <editeng/editids.hrc>
58 #include <sdresid.hxx>
60 #include "CustomAnimationDialog.hxx"
61 #include <CustomAnimationPane.hxx>
62 #include "STLPropertySet.hxx"
63 #include <CustomAnimationPreset.hxx>
65 #include <avmedia/mediawindow.hxx>
67 #include <filedlg.hxx>
68 #include <strings.hrc>
69 #include <helpids.h>
71 using namespace ::com::sun::star;
72 using namespace ::com::sun::star::animations;
73 using namespace ::com::sun::star::presentation;
75 using ::com::sun::star::uno::UNO_QUERY;
76 using ::com::sun::star::uno::Any;
77 using ::com::sun::star::uno::Sequence;
78 using ::com::sun::star::uno::Reference;
79 using ::com::sun::star::uno::Exception;
80 using ::com::sun::star::drawing::XShape;
81 using ::com::sun::star::drawing::XDrawPage;
82 using ::com::sun::star::beans::XPropertySet;
84 namespace sd {
86 SdPropertySubControl::SdPropertySubControl(weld::Container* pParent)
87 : mxBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/customanimationfragment.ui"_ustr,
88 false, reinterpret_cast<sal_uInt64>(SfxViewShell::Current())))
89 , mxContainer(mxBuilder->weld_container(u"EffectFragment"_ustr))
90 , mpParent(pParent)
94 SdPropertySubControl::~SdPropertySubControl()
96 mpParent->move(mxContainer.get(), nullptr);
99 namespace {
101 class SdPresetPropertyBox : public SdPropertySubControl
103 public:
104 SdPresetPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const OUString& aPresetId, const Link<LinkParamNone*,void>& rModifyHdl);
106 virtual Any getValue() override;
107 virtual void setValue( const Any& rValue, const OUString& rPresetId ) override;
109 private:
110 std::vector<OUString> maPropertyValues;
111 Link<LinkParamNone*,void> maModifyLink;
112 std::unique_ptr<weld::ComboBox> mxControl;
114 DECL_LINK(OnSelect, weld::ComboBox&, void);
119 SdPresetPropertyBox::SdPresetPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const OUString& aPresetId, const Link<LinkParamNone*,void>& rModifyHdl)
120 : SdPropertySubControl(pParent)
121 , maModifyLink(rModifyHdl)
122 , mxControl(mxBuilder->weld_combo_box(u"combo"_ustr))
124 mxControl->connect_changed(LINK(this, SdPresetPropertyBox, OnSelect));
125 mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_PRESETPROPERTYBOX);
126 mxControl->show();
127 pLabel->set_mnemonic_widget(mxControl.get());
128 setValue(rValue, aPresetId);
131 IMPL_LINK_NOARG(SdPresetPropertyBox, OnSelect, weld::ComboBox&, void)
133 maModifyLink.Call(nullptr);
136 void SdPresetPropertyBox::setValue( const Any& rValue, const OUString& rPresetId )
138 if (!mxControl)
139 return;
141 mxControl->freeze();
142 mxControl->clear();
143 maPropertyValues.clear();
144 int nPos = -1;
146 const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
147 CustomAnimationPresetPtr pDescriptor = rPresets.getEffectDescriptor( rPresetId );
148 if( pDescriptor )
151 OUString aPropertyValue;
152 rValue >>= aPropertyValue;
154 std::vector<OUString> aSubTypes( pDescriptor->getSubTypes() );
156 mxControl->set_sensitive(!aSubTypes.empty());
158 for( const auto& aSubType : aSubTypes )
160 mxControl->append_text(rPresets.getUINameForProperty(aSubType));
161 maPropertyValues.push_back(aSubType);
162 if (aSubType == aPropertyValue)
163 nPos = maPropertyValues.size() - 1;
166 else
168 mxControl->set_sensitive(false);
170 mxControl->thaw();
171 if (nPos != -1)
172 mxControl->set_active(nPos);
175 Any SdPresetPropertyBox::getValue()
177 const int nIndex = mxControl->get_active();
178 if (nIndex == -1)
179 return Any();
180 return Any(maPropertyValues[nIndex]);
183 namespace {
185 class SdColorPropertyBox : public SdPropertySubControl
187 public:
188 SdColorPropertyBox(weld::Label* pLabel, weld::Container* pParent, weld::Window* pTopLevel, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
190 virtual Any getValue() override;
191 virtual void setValue( const Any& rValue, const OUString& rPresetId ) override;
193 private:
194 Link<LinkParamNone*,void> maModifyLink;
195 std::unique_ptr<ColorListBox> mxControl;
197 DECL_LINK(OnSelect, ColorListBox&, void);
202 SdColorPropertyBox::SdColorPropertyBox(weld::Label* pLabel, weld::Container* pParent, weld::Window* pTopLevel, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
203 : SdPropertySubControl(pParent)
204 , maModifyLink(rModifyHdl)
205 , mxControl(new ColorListBox(mxBuilder->weld_menu_button(u"color"_ustr), [pTopLevel]{ return pTopLevel; }))
207 mxControl->SetSelectHdl(LINK(this, SdColorPropertyBox, OnSelect));
208 mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_COLORPROPERTYBOX);
209 pLabel->set_mnemonic_widget(&mxControl->get_widget());
210 mxControl->show();
212 Color nColor;
213 rValue >>= nColor;
214 mxControl->SelectEntry(nColor);
217 IMPL_LINK_NOARG(SdColorPropertyBox, OnSelect, ColorListBox&, void)
219 maModifyLink.Call(nullptr);
222 void SdColorPropertyBox::setValue( const Any& rValue, const OUString& )
224 if (mxControl)
226 Color nColor;
227 rValue >>= nColor;
229 mxControl->SetNoSelection();
230 mxControl->SelectEntry(nColor);
234 Any SdColorPropertyBox::getValue()
236 return Any(sal_Int32(mxControl->GetSelectEntryColor().GetRGBColor()));
239 namespace {
241 class SdFontPropertyBox : public SdPropertySubControl
243 public:
244 SdFontPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
246 virtual Any getValue() override;
247 virtual void setValue(const Any& rValue, const OUString& rPresetId) override;
249 private:
250 Link<LinkParamNone*,void> maModifyHdl;
251 std::unique_ptr<weld::ComboBox> mxControl;
253 DECL_LINK(ControlSelectHdl, weld::ComboBox&, void);
258 SdFontPropertyBox::SdFontPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
259 : SdPropertySubControl(pParent)
260 , maModifyHdl(rModifyHdl)
261 , mxControl(mxBuilder->weld_combo_box(u"fontname"_ustr))
263 mxControl->connect_changed(LINK(this, SdFontPropertyBox, ControlSelectHdl));
264 mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTPROPERTYBOX);
265 mxControl->show();
266 pLabel->set_mnemonic_widget(mxControl.get());
268 const FontList* pFontList = nullptr;
269 bool bMustDelete = false;
271 if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
273 auto pItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST );
274 if (pItem)
275 pFontList = static_cast<const SvxFontListItem*>(pItem)->GetFontList();
278 if (!pFontList)
280 pFontList = new FontList(Application::GetDefaultDevice(), nullptr);
281 bMustDelete = true;
284 mxControl->freeze();
286 sal_uInt16 nFontCount = pFontList->GetFontNameCount();
287 for (sal_uInt16 i = 0; i < nFontCount; ++i)
289 const FontMetric& rFontMetric = pFontList->GetFontName(i);
290 mxControl->append_text(rFontMetric.GetFamilyName());
293 mxControl->thaw();
295 if( bMustDelete )
296 delete pFontList;
298 setValue( rValue, OUString() );
301 IMPL_LINK_NOARG(SdFontPropertyBox, ControlSelectHdl, weld::ComboBox&, void)
303 maModifyHdl.Call(nullptr);
306 void SdFontPropertyBox::setValue( const Any& rValue, const OUString& )
308 if (mxControl)
310 OUString aFontName;
311 rValue >>= aFontName;
312 mxControl->set_entry_text(aFontName);
316 Any SdFontPropertyBox::getValue()
318 OUString aFontName(mxControl->get_active_text());
319 return Any(aFontName);
322 namespace {
324 class SdCharHeightPropertyBox : public SdPropertySubControl
326 public:
327 SdCharHeightPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
329 virtual Any getValue() override;
330 virtual void setValue( const Any& rValue, const OUString& ) override;
332 DECL_LINK(implMenuSelectHdl, const OUString& rIdent, void);
334 private:
335 Link<LinkParamNone*,void> maModifyHdl;
336 std::unique_ptr<weld::MetricSpinButton> mxMetric;
337 std::unique_ptr<weld::MenuButton> mxControl;
339 DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void);
344 SdCharHeightPropertyBox::SdCharHeightPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
345 : SdPropertySubControl(pParent)
346 , maModifyHdl(rModifyHdl)
347 , mxMetric(mxBuilder->weld_metric_spin_button(u"fontsize"_ustr, FieldUnit::PERCENT))
348 , mxControl(mxBuilder->weld_menu_button(u"fontsizemenu"_ustr))
350 mxMetric->connect_value_changed(LINK(this, SdCharHeightPropertyBox, EditModifyHdl));
351 mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_CHARHEIGHTPROPERTYBOX);
352 mxMetric->show();
353 pLabel->set_mnemonic_widget(&mxMetric->get_widget());
355 mxControl->connect_selected(LINK(this, SdCharHeightPropertyBox, implMenuSelectHdl));
356 mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_CHARHEIGHTPROPERTYBOX);
357 mxControl->show();
359 setValue(rValue, OUString());
362 IMPL_LINK_NOARG(SdCharHeightPropertyBox, EditModifyHdl, weld::MetricSpinButton&, void)
364 maModifyHdl.Call(nullptr);
367 IMPL_LINK(SdCharHeightPropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
369 sal_Int32 nValue = rIdent.toInt32();
370 mxMetric->set_value(nValue, FieldUnit::PERCENT);
371 EditModifyHdl(*mxMetric);
374 void SdCharHeightPropertyBox::setValue( const Any& rValue, const OUString& )
376 if (mxMetric)
378 double fValue = 0.0;
379 rValue >>= fValue;
380 mxMetric->set_value(static_cast<::tools::Long>(fValue * 100.0), FieldUnit::PERCENT);
384 Any SdCharHeightPropertyBox::getValue()
386 return Any(static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0);
389 namespace {
391 class SdTransparencyPropertyBox : public SdPropertySubControl
393 public:
394 SdTransparencyPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
396 virtual Any getValue() override;
397 virtual void setValue( const Any& rValue, const OUString& rPresetId ) override;
399 DECL_LINK(implMenuSelectHdl, const OUString&, void);
400 DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void);
402 void updateMenu();
404 private:
405 Link<LinkParamNone*,void> maModifyHdl;
407 std::unique_ptr<weld::MetricSpinButton> mxMetric;
408 std::unique_ptr<weld::MenuButton> mxControl;
413 SdTransparencyPropertyBox::SdTransparencyPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
414 : SdPropertySubControl(pParent)
415 , maModifyHdl(rModifyHdl)
416 , mxMetric(mxBuilder->weld_metric_spin_button(u"transparent"_ustr, FieldUnit::PERCENT))
417 , mxControl(mxBuilder->weld_menu_button(u"transparentmenu"_ustr))
419 for (sal_Int32 i = 25; i < 101; i += 25)
421 OUString aStr(unicode::formatPercent(i,
422 Application::GetSettings().GetUILanguageTag()));
423 mxControl->append_item_check(OUString::number(i), aStr);
426 mxControl->connect_selected(LINK(this, SdTransparencyPropertyBox, implMenuSelectHdl));
427 mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_TRANSPARENCYPROPERTYBOX);
428 mxControl->show();
430 mxMetric->connect_value_changed(LINK(this, SdTransparencyPropertyBox, implModifyHdl));
431 mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_TRANSPARENCYPROPERTYBOX);
432 mxMetric->show();
433 pLabel->set_mnemonic_widget(&mxMetric->get_widget());
435 setValue(rValue, OUString());
438 void SdTransparencyPropertyBox::updateMenu()
440 sal_Int64 nValue = mxMetric->get_value(FieldUnit::PERCENT);
441 for (sal_uInt16 i = 25; i < 101; i += 25)
442 mxControl->set_item_active(OUString::number(i), nValue == i);
445 IMPL_LINK_NOARG(SdTransparencyPropertyBox, implModifyHdl, weld::MetricSpinButton&, void)
447 updateMenu();
448 maModifyHdl.Call(nullptr);
451 IMPL_LINK(SdTransparencyPropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
453 auto nValue = rIdent.toInt32();
454 if (nValue != mxMetric->get_value(FieldUnit::PERCENT))
456 mxMetric->set_value(nValue, FieldUnit::PERCENT);
457 implModifyHdl(*mxMetric);
461 void SdTransparencyPropertyBox::setValue(const Any& rValue, const OUString&)
463 if (mxMetric)
465 double fValue = 0.0;
466 rValue >>= fValue;
467 ::tools::Long nValue = static_cast<::tools::Long>(fValue * 100);
468 mxMetric->set_value(nValue, FieldUnit::PERCENT);
469 updateMenu();
473 Any SdTransparencyPropertyBox::getValue()
475 return Any(static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0);
478 namespace {
480 class SdRotationPropertyBox : public SdPropertySubControl
482 public:
483 SdRotationPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
485 virtual Any getValue() override;
486 virtual void setValue( const Any& rValue, const OUString& ) override;
488 DECL_LINK(implMenuSelectHdl, const OUString&, void);
489 DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void);
491 void updateMenu();
493 private:
494 Link<LinkParamNone*,void> maModifyHdl;
496 std::unique_ptr<weld::MetricSpinButton> mxMetric;
497 std::unique_ptr<weld::MenuButton> mxControl;
502 SdRotationPropertyBox::SdRotationPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
503 : SdPropertySubControl(pParent)
504 , maModifyHdl(rModifyHdl)
505 , mxMetric(mxBuilder->weld_metric_spin_button(u"rotate"_ustr, FieldUnit::DEGREE))
506 , mxControl(mxBuilder->weld_menu_button(u"rotatemenu"_ustr))
508 mxMetric->connect_value_changed(LINK( this, SdRotationPropertyBox, implModifyHdl));
509 mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_ROTATIONPROPERTYBOX);
510 mxMetric->show();
511 pLabel->set_mnemonic_widget(&mxMetric->get_widget());
513 mxControl->connect_selected(LINK(this, SdRotationPropertyBox, implMenuSelectHdl));
514 mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_ROTATIONPROPERTYBOX);
515 mxControl->show();
517 setValue(rValue, OUString());
520 void SdRotationPropertyBox::updateMenu()
522 sal_Int64 nValue = mxMetric->get_value(FieldUnit::DEGREE);
523 bool bDirection = nValue >= 0;
524 nValue = (nValue < 0 ? -nValue : nValue);
526 mxControl->set_item_active(u"90"_ustr, nValue == 90);
527 mxControl->set_item_active(u"180"_ustr, nValue == 180);
528 mxControl->set_item_active(u"360"_ustr, nValue == 360);
529 mxControl->set_item_active(u"720"_ustr, nValue == 720);
531 mxControl->set_item_active(u"clockwise"_ustr, bDirection);
532 mxControl->set_item_active(u"counterclock"_ustr, !bDirection);
535 IMPL_LINK_NOARG(SdRotationPropertyBox, implModifyHdl, weld::MetricSpinButton&, void)
537 updateMenu();
538 maModifyHdl.Call(nullptr);
541 IMPL_LINK(SdRotationPropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
543 auto nValue = mxMetric->get_value(FieldUnit::DEGREE);
544 bool bDirection = nValue >= 0;
545 nValue = (nValue < 0 ? -nValue : nValue);
547 if (rIdent == "clockwise")
548 bDirection = true;
549 else if (rIdent == "counterclock")
550 bDirection = false;
551 else
552 nValue = rIdent.toInt32();
554 if( !bDirection )
555 nValue = -nValue;
557 if (nValue != mxMetric->get_value(FieldUnit::DEGREE))
559 mxMetric->set_value(nValue, FieldUnit::DEGREE);
560 implModifyHdl(*mxMetric);
564 void SdRotationPropertyBox::setValue( const Any& rValue, const OUString& )
566 if (mxMetric)
568 double fValue = 0.0;
569 rValue >>= fValue;
570 ::tools::Long nValue = static_cast<::tools::Long>(fValue);
571 mxMetric->set_value(nValue, FieldUnit::DEGREE);
572 updateMenu();
576 Any SdRotationPropertyBox::getValue()
578 return Any(static_cast<double>(mxMetric->get_value(FieldUnit::DEGREE)));
581 namespace {
583 class SdScalePropertyBox : public SdPropertySubControl
585 public:
586 SdScalePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
588 virtual Any getValue() override;
589 virtual void setValue( const Any& rValue, const OUString& ) override;
591 DECL_LINK(implMenuSelectHdl, const OUString&, void);
592 DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void);
594 void updateMenu();
596 private:
597 Link<LinkParamNone*,void> maModifyHdl;
598 int mnDirection;
600 std::unique_ptr<weld::MetricSpinButton> mxMetric;
601 std::unique_ptr<weld::MenuButton> mxControl;
606 SdScalePropertyBox::SdScalePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
607 : SdPropertySubControl(pParent)
608 , maModifyHdl( rModifyHdl )
609 , mxMetric(mxBuilder->weld_metric_spin_button(u"scale"_ustr, FieldUnit::PERCENT))
610 , mxControl(mxBuilder->weld_menu_button(u"scalemenu"_ustr))
612 mxControl->connect_selected(LINK(this, SdScalePropertyBox, implMenuSelectHdl));
613 mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_SCALEPROPERTYBOX);
614 mxControl->show();
616 mxMetric->connect_value_changed(LINK(this, SdScalePropertyBox, implModifyHdl));
617 mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_SCALEPROPERTYBOX);
618 mxMetric->show();
619 pLabel->set_mnemonic_widget(&mxMetric->get_widget());
621 setValue(rValue, OUString());
624 void SdScalePropertyBox::updateMenu()
626 auto nValue = mxMetric->get_value(FieldUnit::PERCENT);
628 mxControl->set_item_active(u"25scale"_ustr, nValue == 25);
629 mxControl->set_item_active(u"50scale"_ustr, nValue == 50);
630 mxControl->set_item_active(u"150scale"_ustr, nValue == 150);
631 mxControl->set_item_active(u"400scale"_ustr, nValue == 400);
633 mxControl->set_item_active(u"hori"_ustr, mnDirection == 1);
634 mxControl->set_item_active(u"vert"_ustr, mnDirection == 2);
635 mxControl->set_item_active(u"both"_ustr, mnDirection == 3);
638 IMPL_LINK_NOARG(SdScalePropertyBox, implModifyHdl, weld::MetricSpinButton&, void)
640 updateMenu();
641 maModifyHdl.Call(nullptr);
644 IMPL_LINK(SdScalePropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
646 auto nValue = mxMetric->get_value(FieldUnit::PERCENT);
648 int nDirection = mnDirection;
650 if (rIdent == "hori")
651 nDirection = 1;
652 else if (rIdent == "vert")
653 nDirection = 2;
654 else if (rIdent == "both")
655 nDirection = 3;
656 else
657 nValue = rIdent.toInt32(); // Getting here indicates a UI bug and should be handled better
659 bool bModified = false;
661 if( nDirection != mnDirection )
663 mnDirection = nDirection;
664 bModified = true;
667 if (nValue != mxMetric->get_value(FieldUnit::PERCENT))
669 mxMetric->set_value(nValue, FieldUnit::PERCENT);
670 bModified = true;
673 if(bModified)
675 implModifyHdl(*mxMetric);
676 updateMenu();
680 void SdScalePropertyBox::setValue(const Any& rValue, const OUString&)
682 if (!mxMetric)
683 return;
685 ValuePair aValues;
686 rValue >>= aValues;
688 double fValue1 = 0.0;
689 double fValue2 = 0.0;
691 aValues.First >>= fValue1;
692 aValues.Second >>= fValue2;
694 // 'Size' drop down menu set by mnDirection when loading Grow and Shrink Animation
695 // Shouldn't compare a float directly to zero... should be fixed with delta epsilon compare
696 // Might be better to just have a flag in the content.xml for this
697 if( (fValue1 == 0.0) && (fValue2 == 0.0) )
698 mnDirection = 3; // assume 'Both' scaling option when both are zero
699 else if( (fValue1 != 0.0) && (fValue2 == 0.0) )
700 mnDirection = 1;
701 else if( (fValue1 == 0.0) && (fValue2 != 0.0) )
702 mnDirection = 2;
703 else
704 mnDirection = 3;
706 // Grow and Shrink Animation is a relative change with value stored in content.xml under tag
707 // smil:by=*,*
708 // An offset of 1 must be added to properly translate from content.xml to UI value displayed
709 // 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
710 // size horizontal and vertical
711 // 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%
712 // of the size horizontal and vertical
713 fValue1 += 1;
714 fValue2 += 1;
716 // Determine value from file for UI 'Size' field based on determined mnDirection
717 ::tools::Long nValue;
718 if( mnDirection == 1 )
719 nValue = static_cast<::tools::Long>(fValue1 * 100.0);
720 else if( mnDirection == 2 )
721 nValue = static_cast<::tools::Long>(fValue2 * 100.0);
722 else if( mnDirection == 3 ){
723 if (fValue1 >= fValue2)
724 nValue = static_cast<::tools::Long>(fValue1 * 100.0);
725 else
726 nValue = static_cast<::tools::Long>(fValue2 * 100.0);
728 else
729 nValue = static_cast<::tools::Long>(100.0); // default to 100% in UI if something goes wrong
731 mxMetric->set_value(nValue, FieldUnit::PERCENT);
732 updateMenu();
735 Any SdScalePropertyBox::getValue()
737 double fValue1 = static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0;
739 // Grow and Shrink Animation is a relative change with value stored in content.xml under tag
740 // smil:by=*,*
741 // An offset of 1 must be subtracted to properly translate UI value displayed and save to
742 // content.xml
743 // 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
744 // 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
745 fValue1 -= 1;
747 double fValue2 = fValue1;
749 // mnDirection set by 'Size' drop down menu and used to zero out either horizontal or vertical
750 // scaling depending on what option is selected
751 if( mnDirection == 1 )
752 fValue2 = 0.0;
753 else if( mnDirection == 2 )
754 fValue1 = 0.0;
756 ValuePair aValues;
757 aValues.First <<= fValue1;
758 aValues.Second <<= fValue2;
760 return Any( aValues );
763 namespace {
765 class SdFontStylePropertyBox : public SdPropertySubControl
767 public:
768 SdFontStylePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
770 virtual Any getValue() override;
771 virtual void setValue( const Any& rValue, const OUString& ) override;
773 DECL_LINK(implMenuSelectHdl, const OUString&, void);
775 void update();
777 private:
778 float mfFontWeight;
779 awt::FontSlant meFontSlant;
780 sal_Int16 mnFontUnderline;
781 Link<LinkParamNone*,void> maModifyHdl;
783 std::unique_ptr<weld::Entry> mxEdit;
784 std::unique_ptr<weld::MenuButton> mxControl;
789 SdFontStylePropertyBox::SdFontStylePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl )
790 : SdPropertySubControl(pParent)
791 , maModifyHdl( rModifyHdl )
792 , mxEdit(mxBuilder->weld_entry(u"entry"_ustr))
793 , mxControl(mxBuilder->weld_menu_button(u"entrymenu"_ustr))
795 mxEdit->set_text(SdResId(STR_CUSTOMANIMATION_SAMPLE));
796 mxEdit->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTSTYLEPROPERTYBOX);
797 pLabel->set_mnemonic_widget(mxEdit.get());
798 mxEdit->show();
800 mxControl->connect_selected(LINK(this, SdFontStylePropertyBox, implMenuSelectHdl));
801 mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTSTYLEPROPERTYBOX);
802 mxControl->show();
804 setValue(rValue, OUString());
807 void SdFontStylePropertyBox::update()
809 // update menu
810 mxControl->set_item_active(u"bold"_ustr, mfFontWeight == awt::FontWeight::BOLD);
811 mxControl->set_item_active(u"italic"_ustr, meFontSlant == awt::FontSlant_ITALIC);
812 mxControl->set_item_active(u"underline"_ustr, mnFontUnderline != awt::FontUnderline::NONE );
814 // update sample edit
815 vcl::Font aFont(mxEdit->get_font());
816 aFont.SetWeight(mfFontWeight == awt::FontWeight::BOLD ? WEIGHT_BOLD : WEIGHT_NORMAL);
817 aFont.SetItalic(meFontSlant == awt::FontSlant_ITALIC ? ITALIC_NORMAL : ITALIC_NONE);
818 aFont.SetUnderline(mnFontUnderline == awt::FontUnderline::NONE ? LINESTYLE_NONE : LINESTYLE_SINGLE);
819 mxEdit->set_font(aFont);
822 IMPL_LINK(SdFontStylePropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
824 if (rIdent == "bold")
826 if( mfFontWeight == awt::FontWeight::BOLD )
827 mfFontWeight = awt::FontWeight::NORMAL;
828 else
829 mfFontWeight = awt::FontWeight::BOLD;
831 else if (rIdent == "italic")
833 if( meFontSlant == awt::FontSlant_ITALIC )
834 meFontSlant = awt::FontSlant_NONE;
835 else
836 meFontSlant = awt::FontSlant_ITALIC;
838 else if (rIdent == "underline")
840 if( mnFontUnderline == awt::FontUnderline::SINGLE )
841 mnFontUnderline = awt::FontUnderline::NONE;
842 else
843 mnFontUnderline = awt::FontUnderline::SINGLE;
846 update();
847 maModifyHdl.Call(nullptr);
850 void SdFontStylePropertyBox::setValue( const Any& rValue, const OUString& )
852 Sequence<Any> aValues;
853 rValue >>= aValues;
855 aValues[0] >>= mfFontWeight;
856 aValues[1] >>= meFontSlant;
857 aValues[2] >>= mnFontUnderline;
859 update();
862 Any SdFontStylePropertyBox::getValue()
864 Sequence<Any> aValues{ Any(mfFontWeight), Any(meFontSlant), Any(mnFontUnderline) };
865 return Any( aValues );
868 class CustomAnimationEffectTabPage
870 public:
871 CustomAnimationEffectTabPage(weld::Container* pParent, weld::Window* pDialog, const STLPropertySet* pSet);
873 void update( STLPropertySet* pSet );
874 DECL_LINK(implSelectHdl, weld::ComboBox&, void);
875 DECL_LINK(implClickHdl, weld::Button&, void);
876 void implHdl(const weld::Widget*);
878 private:
879 void updateControlStates();
880 void fillSoundListBox();
881 void clearSoundListBox();
882 sal_Int32 getSoundObject( std::u16string_view rStr );
883 void openSoundFileDialog();
884 void onSoundPreview();
885 weld::Window* GetFrameWeld() const { return mpDialog; }
887 private:
888 ::std::vector< OUString > maSoundList;
889 bool mbHasText;
890 const STLPropertySet* mpSet;
891 css::uno::Reference<css::media::XPlayer> mxPlayer;
893 weld::Window* mpDialog;
894 std::unique_ptr<weld::Builder> mxBuilder;
895 std::unique_ptr<weld::Container> mxContainer;
896 std::unique_ptr<weld::Widget> mxSettings;
897 std::unique_ptr<weld::Label> mxFTProperty1;
898 std::unique_ptr<weld::Container> mxPlaceholderBox;
899 std::unique_ptr<weld::CheckButton> mxCBSmoothStart;
900 std::unique_ptr<weld::CheckButton> mxCBSmoothEnd;
901 std::unique_ptr<weld::Label> mxFTSound;
902 std::unique_ptr<weld::ComboBox> mxLBSound;
903 std::unique_ptr<weld::Button> mxPBSoundPreview;
904 std::unique_ptr<weld::ComboBox> mxLBAfterEffect;
905 std::unique_ptr<weld::Label> mxFTDimColor;
906 std::unique_ptr<ColorListBox> mxCLBDimColor;
907 std::unique_ptr<weld::Label> mxFTTextAnim;
908 std::unique_ptr<weld::ComboBox> mxLBTextAnim;
909 std::unique_ptr<weld::MetricSpinButton> mxMFTextDelay;
910 std::unique_ptr<weld::Label> mxFTTextDelay;
911 std::unique_ptr<SdPropertySubControl> mxLBSubControl;
914 CustomAnimationEffectTabPage::CustomAnimationEffectTabPage(weld::Container* pParent, weld::Window* pDialog, const STLPropertySet* pSet)
915 : mbHasText(false)
916 , mpSet(pSet)
917 , mpDialog(pDialog)
918 , mxBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/customanimationeffecttab.ui"_ustr))
919 , mxContainer(mxBuilder->weld_container(u"EffectTab"_ustr))
920 , mxSettings(mxBuilder->weld_widget(u"settings"_ustr))
921 , mxFTProperty1(mxBuilder->weld_label(u"prop_label1"_ustr))
922 , mxPlaceholderBox(mxBuilder->weld_container(u"placeholder"_ustr))
923 , mxCBSmoothStart(mxBuilder->weld_check_button(u"smooth_start"_ustr))
924 , mxCBSmoothEnd(mxBuilder->weld_check_button(u"smooth_end"_ustr))
925 , mxFTSound(mxBuilder->weld_label(u"sound_label"_ustr))
926 , mxLBSound(mxBuilder->weld_combo_box(u"sound_list"_ustr))
927 , mxPBSoundPreview(mxBuilder->weld_button(u"sound_preview"_ustr))
928 , mxLBAfterEffect(mxBuilder->weld_combo_box(u"aeffect_list"_ustr))
929 , mxFTDimColor(mxBuilder->weld_label(u"dim_color_label"_ustr))
930 , mxCLBDimColor(new ColorListBox(mxBuilder->weld_menu_button(u"dim_color_list"_ustr), [pDialog]{ return pDialog; }))
931 , mxFTTextAnim(mxBuilder->weld_label(u"text_animation_label"_ustr))
932 , mxLBTextAnim(mxBuilder->weld_combo_box(u"text_animation_list"_ustr))
933 , mxMFTextDelay(mxBuilder->weld_metric_spin_button(u"text_delay"_ustr, FieldUnit::PERCENT))
934 , mxFTTextDelay(mxBuilder->weld_label(u"text_delay_label"_ustr))
936 mxCLBDimColor->SelectEntry(COL_BLACK);
938 // fill the soundbox
939 fillSoundListBox();
941 mxLBSound->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl));
942 mxPBSoundPreview->connect_clicked(LINK(this, CustomAnimationEffectTabPage, implClickHdl));
944 // only show settings if all selected effects have the same preset-id
945 if( pSet->getPropertyState( nHandlePresetId ) != STLPropertyState::Ambiguous )
947 OUString aPresetId;
948 pSet->getPropertyValue( nHandlePresetId ) >>= aPresetId;
950 // property 1
952 if( pSet->getPropertyState( nHandleProperty1Type ) != STLPropertyState::Ambiguous )
954 sal_Int32 nType = 0;
955 pSet->getPropertyValue( nHandleProperty1Type ) >>= nType;
957 if( nType != nPropertyTypeNone )
959 // set ui name for property at fixed text
960 OUString aPropertyName( getPropertyName( nType ) );
962 if( !aPropertyName.isEmpty() )
964 mxSettings->show();
965 mxFTProperty1->set_label(aPropertyName);
968 // get property value
969 const Any aValue( pSet->getPropertyValue( nHandleProperty1Value ) );
971 // create property sub control
972 mxLBSubControl = SdPropertySubControl::create(nType, mxFTProperty1.get(), mxPlaceholderBox.get(), mpDialog, aValue, aPresetId, Link<LinkParamNone*,void>());
976 mxFTProperty1->set_sensitive(mxPlaceholderBox->get_sensitive());
978 // accelerate & decelerate
980 if( pSet->getPropertyState( nHandleAccelerate ) == STLPropertyState::Direct )
982 mxCBSmoothStart->show();
983 mxCBSmoothEnd->show();
985 double fTemp = 0.0;
986 pSet->getPropertyValue( nHandleAccelerate ) >>= fTemp;
987 mxCBSmoothStart->set_active( fTemp > 0.0 );
989 pSet->getPropertyValue( nHandleDecelerate ) >>= fTemp;
990 mxCBSmoothEnd->set_active( fTemp > 0.0 );
994 // init after effect controls
996 mxLBAfterEffect->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl));
997 mxLBTextAnim->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl));
999 if( (pSet->getPropertyState( nHandleHasAfterEffect ) != STLPropertyState::Ambiguous) &&
1000 (pSet->getPropertyState( nHandleAfterEffectOnNextEffect ) != STLPropertyState::Ambiguous) &&
1001 (pSet->getPropertyState( nHandleDimColor ) != STLPropertyState::Ambiguous))
1003 bool bHasAfterEffect = false;
1004 pSet->getPropertyValue( nHandleHasAfterEffect ) >>= bHasAfterEffect;
1006 sal_Int32 nPos = 0;
1007 if( bHasAfterEffect )
1009 nPos++;
1011 bool bAfterEffectOnNextClick = false;
1012 pSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bAfterEffectOnNextClick;
1013 Any aDimColor( pSet->getPropertyValue( nHandleDimColor ) );
1015 if( aDimColor.hasValue() )
1017 Color aColor;
1018 aDimColor >>= aColor;
1019 mxCLBDimColor->SelectEntry(aColor);
1021 else
1023 nPos++;
1024 if( bAfterEffectOnNextClick )
1025 nPos++;
1029 mxLBAfterEffect->set_active(nPos);
1032 if( pSet->getPropertyState( nHandleHasText ) != STLPropertyState::Ambiguous )
1033 pSet->getPropertyValue( nHandleHasText ) >>= mbHasText;
1035 if( mbHasText )
1037 if( pSet->getPropertyState( nHandleIterateType ) != STLPropertyState::Ambiguous)
1039 int nPos = -1;
1041 sal_Int32 nIterateType = 0;
1042 pSet->getPropertyValue( nHandleIterateType ) >>= nIterateType;
1043 switch( nIterateType )
1045 case TextAnimationType::BY_PARAGRAPH: nPos = 0; break;
1046 case TextAnimationType::BY_WORD: nPos = 1; break;
1047 case TextAnimationType::BY_LETTER: nPos = 2; break;
1050 mxLBTextAnim->set_active(nPos);
1053 if( pSet->getPropertyState( nHandleIterateInterval ) != STLPropertyState::Default )
1055 double fIterateInterval = 0.0;
1056 pSet->getPropertyValue( nHandleIterateInterval ) >>= fIterateInterval;
1057 mxMFTextDelay->set_value(static_cast<::tools::Long>(fIterateInterval*10), FieldUnit::NONE);
1060 else
1062 mxFTTextAnim->set_sensitive(false);
1063 mxLBTextAnim->set_sensitive(false);
1064 mxMFTextDelay->set_sensitive(false);
1065 mxFTTextDelay->set_sensitive(false);
1069 if( pSet->getPropertyState( nHandleSoundURL ) != STLPropertyState::Ambiguous )
1071 sal_Int32 nPos = 0;
1073 const Any aValue( pSet->getPropertyValue( nHandleSoundURL ) );
1075 if( aValue.getValueType() == ::cppu::UnoType<sal_Bool>::get() )
1077 nPos = 1;
1079 else
1081 OUString aSoundURL;
1082 aValue >>= aSoundURL;
1084 if( !aSoundURL.isEmpty() )
1086 sal_uLong i;
1087 for( i = 0; i < maSoundList.size(); i++ )
1089 OUString aString = maSoundList[ i ];
1090 if( aString == aSoundURL )
1092 nPos = static_cast<sal_Int32>(i)+2;
1093 break;
1097 if( nPos == 0 )
1099 nPos = static_cast<sal_Int32>(maSoundList.size())+2;
1100 maSoundList.push_back( aSoundURL );
1101 INetURLObject aURL( aSoundURL );
1102 mxLBSound->insert_text(nPos, aURL.GetBase());
1107 if( nPos != -1)
1108 mxLBSound->set_active(nPos);
1111 updateControlStates();
1115 void CustomAnimationEffectTabPage::updateControlStates()
1117 auto nPos = mxLBAfterEffect->get_active();
1118 mxCLBDimColor->set_sensitive( nPos == 1 );
1119 mxFTDimColor->set_sensitive( nPos == 1 );
1121 if( mbHasText )
1123 nPos = mxLBTextAnim->get_active();
1124 mxMFTextDelay->set_sensitive( nPos != 0 );
1125 mxFTTextDelay->set_sensitive( nPos != 0 );
1128 if (comphelper::LibreOfficeKit::isActive())
1130 mxFTSound->hide();
1131 mxLBSound->hide();
1132 mxPBSoundPreview->hide();
1134 else
1136 nPos = mxLBSound->get_active();
1137 mxPBSoundPreview->set_sensitive( nPos >= 2 );
1142 IMPL_LINK(CustomAnimationEffectTabPage, implClickHdl, weld::Button&, rBtn, void)
1144 implHdl(&rBtn);
1147 IMPL_LINK(CustomAnimationEffectTabPage, implSelectHdl, weld::ComboBox&, rListBox, void)
1149 implHdl(&rListBox);
1152 void CustomAnimationEffectTabPage::implHdl(const weld::Widget* pControl)
1154 if (pControl == mxLBTextAnim.get())
1156 if (mxMFTextDelay->get_value(FieldUnit::NONE) == 0)
1157 mxMFTextDelay->set_value(100, FieldUnit::NONE);
1159 else if (pControl == mxLBSound.get())
1161 auto nPos = mxLBSound->get_active();
1162 if (nPos == (mxLBSound->get_count() - 1))
1164 openSoundFileDialog();
1167 else if (pControl == mxPBSoundPreview.get())
1169 onSoundPreview();
1172 updateControlStates();
1175 void CustomAnimationEffectTabPage::update( STLPropertySet* pSet )
1177 if (mxLBSubControl)
1179 Any aNewValue(mxLBSubControl->getValue());
1180 Any aOldValue;
1181 if( mpSet->getPropertyState( nHandleProperty1Value ) != STLPropertyState::Ambiguous)
1182 aOldValue = mpSet->getPropertyValue( nHandleProperty1Value );
1184 if( aOldValue != aNewValue )
1185 pSet->setPropertyValue( nHandleProperty1Value, aNewValue );
1188 if (mxCBSmoothStart->get_visible())
1190 // set selected value for accelerate if different than in original set
1192 double fTemp = mxCBSmoothStart->get_active() ? 0.5 : 0.0;
1194 double fOldTemp = 0.0;
1195 if(mpSet->getPropertyState( nHandleAccelerate ) != STLPropertyState::Ambiguous)
1196 mpSet->getPropertyValue( nHandleAccelerate ) >>= fOldTemp;
1197 else
1198 fOldTemp = -2.0;
1200 if( fOldTemp != fTemp )
1201 pSet->setPropertyValue( nHandleAccelerate, Any( fTemp ) );
1203 // set selected value for decelerate if different than in original set
1204 fTemp = mxCBSmoothEnd->get_active() ? 0.5 : 0.0;
1206 if(mpSet->getPropertyState( nHandleDecelerate ) != STLPropertyState::Ambiguous)
1207 mpSet->getPropertyValue( nHandleDecelerate ) >>= fOldTemp;
1208 else
1209 fOldTemp = -2.0;
1211 if( fOldTemp != fTemp )
1212 pSet->setPropertyValue( nHandleDecelerate, Any( fTemp ) );
1215 auto nPos = mxLBAfterEffect->get_active();
1216 if (nPos != -1)
1218 bool bAfterEffect = nPos != 0;
1220 bool bOldAfterEffect = false;
1222 if(mpSet->getPropertyState( nHandleHasAfterEffect ) != STLPropertyState::Ambiguous)
1223 mpSet->getPropertyValue( nHandleHasAfterEffect ) >>= bOldAfterEffect;
1224 else
1225 bOldAfterEffect = !bAfterEffect;
1227 if( bOldAfterEffect != bAfterEffect )
1228 pSet->setPropertyValue( nHandleHasAfterEffect, Any( bAfterEffect ) );
1230 Any aDimColor;
1231 if( nPos == 1 )
1233 Color aSelectedColor = mxCLBDimColor->GetSelectEntryColor();
1234 aDimColor <<= aSelectedColor.GetRGBColor();
1237 if( (mpSet->getPropertyState( nHandleDimColor ) == STLPropertyState::Ambiguous) ||
1238 (mpSet->getPropertyValue( nHandleDimColor ) != aDimColor) )
1239 pSet->setPropertyValue( nHandleDimColor, aDimColor );
1241 bool bAfterEffectOnNextEffect = nPos != 2;
1242 bool bOldAfterEffectOnNextEffect = !bAfterEffectOnNextEffect;
1244 if( mpSet->getPropertyState( nHandleAfterEffectOnNextEffect ) != STLPropertyState::Ambiguous)
1245 mpSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bOldAfterEffectOnNextEffect;
1247 if( bAfterEffectOnNextEffect != bOldAfterEffectOnNextEffect )
1248 pSet->setPropertyValue( nHandleAfterEffectOnNextEffect, Any( bAfterEffectOnNextEffect ) );
1251 nPos = mxLBTextAnim->get_active();
1252 if (nPos != -1)
1254 sal_Int16 nIterateType;
1256 switch( nPos )
1258 case 1: nIterateType = TextAnimationType::BY_WORD; break;
1259 case 2: nIterateType = TextAnimationType::BY_LETTER; break;
1260 default:
1261 nIterateType = TextAnimationType::BY_PARAGRAPH;
1264 sal_Int16 nOldIterateType = nIterateType-1;
1266 if(mpSet->getPropertyState( nHandleIterateType ) != STLPropertyState::Ambiguous)
1267 mpSet->getPropertyValue( nHandleIterateType ) >>= nOldIterateType;
1269 if( nIterateType != nOldIterateType )
1270 pSet->setPropertyValue( nHandleIterateType, Any( nIterateType ) );
1274 double fIterateInterval = static_cast<double>(mxMFTextDelay->get_value(FieldUnit::NONE)) / 10;
1275 double fOldIterateInterval = -1.0;
1277 if( mpSet->getPropertyState( nHandleIterateInterval ) != STLPropertyState::Ambiguous )
1278 mpSet->getPropertyValue( nHandleIterateInterval ) >>= fOldIterateInterval;
1280 if( fIterateInterval != fOldIterateInterval )
1281 pSet->setPropertyValue( nHandleIterateInterval, Any( fIterateInterval ) );
1284 nPos = mxLBSound->get_active();
1285 if (nPos == -1)
1286 return;
1288 Any aNewSoundURL, aOldSoundURL( Any( sal_Int32(0) ) );
1290 if( nPos == 0 )
1292 // 0 means no sound, so leave any empty
1294 else if( nPos == 1 )
1296 // this means stop sound
1297 aNewSoundURL <<= true;
1299 else
1301 OUString aSoundURL( maSoundList[ nPos-2 ] );
1302 aNewSoundURL <<= aSoundURL;
1305 if( mpSet->getPropertyState( nHandleSoundURL ) != STLPropertyState::Ambiguous )
1306 aOldSoundURL = mpSet->getPropertyValue( nHandleSoundURL );
1308 if( aNewSoundURL != aOldSoundURL )
1309 pSet->setPropertyValue( nHandleSoundURL, aNewSoundURL );
1312 void CustomAnimationEffectTabPage::fillSoundListBox()
1314 GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, maSoundList );
1315 GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, maSoundList );
1317 mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_NO_SOUND) );
1318 mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_STOP_PREVIOUS_SOUND) );
1319 for(const OUString & rString : maSoundList)
1321 INetURLObject aURL( rString );
1322 mxLBSound->append_text( aURL.GetBase() );
1324 mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_BROWSE_SOUND) );
1327 void CustomAnimationEffectTabPage::clearSoundListBox()
1329 maSoundList.clear();
1330 mxLBSound->clear();
1333 sal_Int32 CustomAnimationEffectTabPage::getSoundObject( std::u16string_view rStr )
1335 size_t i;
1336 const size_t nCount = maSoundList.size();
1337 for( i = 0; i < nCount; i++ )
1339 if( maSoundList[ i ].equalsIgnoreAsciiCase(rStr) )
1340 return i+2;
1343 return -1;
1346 void CustomAnimationEffectTabPage::openSoundFileDialog()
1348 SdOpenSoundFileDialog aFileDialog(GetFrameWeld());
1350 bool bValidSoundFile = false;
1351 bool bQuitLoop = false;
1352 ::tools::Long nPos = 0;
1354 while( !bQuitLoop && (aFileDialog.Execute() == ERRCODE_NONE) )
1356 OUString aFile = aFileDialog.GetPath();
1357 nPos = getSoundObject( aFile );
1359 if( nPos < 0 ) // not in Soundliste
1361 // try to insert in Gallery
1362 if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile ) )
1364 clearSoundListBox();
1365 fillSoundListBox();
1367 nPos = getSoundObject( aFile );
1368 DBG_ASSERT( nPos >= 0, "sd::CustomAnimationEffectTabPage::openSoundFileDialog(), Recently inserted sound not in list!" );
1370 bValidSoundFile=true;
1371 bQuitLoop=true;
1373 else
1375 OUString aStrWarning(SdResId(STR_WARNING_NOSOUNDFILE));
1376 aStrWarning = aStrWarning.replaceFirst("%", aFile);
1377 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(nullptr,
1378 VclMessageType::Warning, VclButtonsType::NONE,
1379 aStrWarning));
1380 xWarn->add_button(GetStandardText(StandardButtonType::Retry), RET_RETRY);
1381 xWarn->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
1382 bQuitLoop = xWarn->run() != RET_RETRY;
1384 bValidSoundFile=false;
1387 else
1389 bValidSoundFile=true;
1390 bQuitLoop=true;
1394 if( !bValidSoundFile )
1395 nPos = 0;
1397 mxLBSound->set_active(nPos);
1400 void CustomAnimationEffectTabPage::onSoundPreview()
1402 #if HAVE_FEATURE_AVMEDIA
1403 const auto nPos = mxLBSound->get_active();
1405 if( nPos >= 2 ) try
1407 const OUString aSoundURL( maSoundList[ nPos-2 ] );
1408 mxPlayer.set( avmedia::MediaWindow::createPlayer( aSoundURL, u""_ustr ), uno::UNO_SET_THROW );
1409 mxPlayer->start();
1411 catch( uno::Exception& )
1413 TOOLS_WARN_EXCEPTION( "sd", "CustomAnimationEffectTabPage::onSoundPreview()" );
1415 #endif
1418 class CustomAnimationDurationTabPage
1420 public:
1421 CustomAnimationDurationTabPage(weld::Container* pParent, const STLPropertySet* pSet);
1423 void update( STLPropertySet* pSet );
1425 DECL_LINK(implControlHdl, weld::ComboBox&, void);
1426 DECL_LINK(DurationModifiedHdl, weld::MetricSpinButton&, void);
1428 private:
1429 const STLPropertySet* mpSet;
1431 std::unique_ptr<weld::Builder> mxBuilder;
1432 std::unique_ptr<weld::Container> mxContainer;
1433 std::unique_ptr<weld::ComboBox> mxLBStart;
1434 std::unique_ptr<weld::MetricSpinButton> mxMFStartDelay;
1435 std::unique_ptr<weld::Label> mxFTDuration;
1436 std::unique_ptr<weld::MetricSpinButton> mxCBXDuration;
1437 std::unique_ptr<weld::Label> mxFTRepeat;
1438 std::unique_ptr<weld::ComboBox> mxCBRepeat;
1439 std::unique_ptr<weld::CheckButton> mxCBXRewind;
1440 std::unique_ptr<weld::RadioButton> mxRBClickSequence;
1441 std::unique_ptr<weld::RadioButton> mxRBInteractive;
1442 std::unique_ptr<weld::ComboBox> mxLBTrigger;
1445 CustomAnimationDurationTabPage::CustomAnimationDurationTabPage(weld::Container* pParent, const STLPropertySet* pSet)
1446 : mpSet(pSet)
1447 , mxBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/customanimationtimingtab.ui"_ustr))
1448 , mxContainer(mxBuilder->weld_container(u"TimingTab"_ustr))
1449 , mxLBStart(mxBuilder->weld_combo_box(u"start_list"_ustr))
1450 , mxMFStartDelay(mxBuilder->weld_metric_spin_button(u"delay_value"_ustr, FieldUnit::SECOND))
1451 , mxFTDuration(mxBuilder->weld_label(u"duration_label"_ustr))
1452 , mxCBXDuration(mxBuilder->weld_metric_spin_button(u"anim_duration"_ustr, FieldUnit::SECOND))
1453 , mxFTRepeat(mxBuilder->weld_label(u"repeat_label"_ustr))
1454 , mxCBRepeat(mxBuilder->weld_combo_box(u"repeat_list"_ustr))
1455 , mxCBXRewind(mxBuilder->weld_check_button(u"rewind"_ustr))
1456 , mxRBClickSequence(mxBuilder->weld_radio_button(u"rb_click_sequence"_ustr))
1457 , mxRBInteractive(mxBuilder->weld_radio_button(u"rb_interactive"_ustr))
1458 , mxLBTrigger(mxBuilder->weld_combo_box(u"trigger_list"_ustr))
1460 mxLBTrigger->set_size_request(mxLBTrigger->get_approximate_digit_width() * 20, -1);
1462 fillRepeatComboBox(*mxCBRepeat);
1464 mxLBTrigger->connect_changed(LINK(this, CustomAnimationDurationTabPage, implControlHdl));
1465 mxCBXDuration->connect_value_changed(LINK( this, CustomAnimationDurationTabPage, DurationModifiedHdl));
1467 if( pSet->getPropertyState( nHandleStart ) != STLPropertyState::Ambiguous )
1469 sal_Int16 nStart = 0;
1470 pSet->getPropertyValue( nHandleStart ) >>= nStart;
1471 sal_Int32 nPos = 0;
1472 switch( nStart )
1474 case EffectNodeType::WITH_PREVIOUS: nPos = 1; break;
1475 case EffectNodeType::AFTER_PREVIOUS: nPos = 2; break;
1477 mxLBStart->set_active(nPos);
1480 if( pSet->getPropertyState( nHandleBegin ) != STLPropertyState::Ambiguous )
1482 double fBegin = 0.0;
1483 pSet->getPropertyValue( nHandleBegin ) >>= fBegin;
1484 mxMFStartDelay->set_value(static_cast<::tools::Long>(fBegin*10), FieldUnit::NONE);
1487 if( pSet->getPropertyState( nHandleDuration ) != STLPropertyState::Ambiguous )
1489 double fDuration = 0.0;
1490 pSet->getPropertyValue( nHandleDuration ) >>= fDuration;
1492 if( fDuration == 0.001 )
1494 mxFTDuration->set_sensitive(false);
1495 mxCBXDuration->set_sensitive(false);
1496 mxFTRepeat->set_sensitive(false);
1497 mxCBRepeat->set_sensitive(false);
1498 mxCBXRewind->set_sensitive(false);
1500 else
1502 mxCBXDuration->set_value(fDuration * 100.0, FieldUnit::NONE);
1506 if( pSet->getPropertyState( nHandleRepeat ) != STLPropertyState::Ambiguous )
1508 Any aRepeatCount( pSet->getPropertyValue( nHandleRepeat ) );
1509 if( (aRepeatCount.getValueType() == ::cppu::UnoType<double>::get()) || !aRepeatCount.hasValue() )
1511 double fRepeat = 0.0;
1512 if( aRepeatCount.hasValue() )
1513 aRepeatCount >>= fRepeat;
1515 auto nPos = -1;
1517 if( fRepeat == 0 )
1518 nPos = 0;
1519 else if( fRepeat == 2.0 )
1520 nPos = 1;
1521 else if( fRepeat == 3.0 )
1522 nPos = 2;
1523 else if( fRepeat == 4.0 )
1524 nPos = 3;
1525 else if( fRepeat == 5.0 )
1526 nPos = 4;
1527 else if( fRepeat == 10.0 )
1528 nPos = 5;
1530 if (nPos != -1)
1531 mxCBRepeat->set_active(nPos);
1532 else
1533 mxCBRepeat->set_entry_text(OUString::number(fRepeat));
1535 else if( aRepeatCount.getValueType() == ::cppu::UnoType<Timing>::get() )
1537 Any aEnd;
1538 if( pSet->getPropertyState( nHandleEnd ) != STLPropertyState::Ambiguous )
1539 aEnd = pSet->getPropertyValue( nHandleEnd );
1541 mxCBRepeat->set_active(aEnd.hasValue() ? 6 : 7);
1545 if( pSet->getPropertyState( nHandleRewind ) != STLPropertyState::Ambiguous )
1547 sal_Int16 nFill = 0;
1548 if( pSet->getPropertyValue( nHandleRewind ) >>= nFill )
1550 mxCBXRewind->set_active(nFill == AnimationFill::REMOVE);
1552 else
1554 mxCBXRewind->set_state(TRISTATE_INDET);
1558 Reference< XShape > xTrigger;
1560 if( pSet->getPropertyState( nHandleTrigger ) != STLPropertyState::Ambiguous )
1562 pSet->getPropertyValue( nHandleTrigger ) >>= xTrigger;
1564 mxRBInteractive->set_active(xTrigger.is());
1565 mxRBClickSequence->set_active(!xTrigger.is());
1568 Reference< XDrawPage > xCurrentPage;
1569 pSet->getPropertyValue( nHandleCurrentPage ) >>= xCurrentPage;
1570 if( !xCurrentPage.is() )
1571 return;
1573 static constexpr OUString aStrIsEmptyPresObj( u"IsEmptyPresentationObject"_ustr );
1575 sal_Int32 nShape, nCount = xCurrentPage->getCount();
1576 for( nShape = 0; nShape < nCount; nShape++ )
1578 Reference< XShape > xShape( xCurrentPage->getByIndex( nShape ), UNO_QUERY );
1580 if( !xShape.is() )
1581 continue;
1583 Reference< XPropertySet > xSet( xShape, UNO_QUERY );
1584 if( xSet.is() && xSet->getPropertySetInfo()->hasPropertyByName( aStrIsEmptyPresObj ) )
1586 bool bIsEmpty = false;
1587 xSet->getPropertyValue( aStrIsEmptyPresObj ) >>= bIsEmpty;
1588 if( bIsEmpty )
1589 continue;
1592 OUString aDescription( getShapeDescription( xShape, true ) );
1593 mxLBTrigger->append(OUString::number(nShape), aDescription);
1594 auto nPos = mxLBTrigger->get_count() - 1;
1595 if (xShape == xTrigger)
1596 mxLBTrigger->set_active(nPos);
1600 IMPL_LINK_NOARG(CustomAnimationDurationTabPage, implControlHdl, weld::ComboBox&, void)
1602 mxRBInteractive->set_active(true);
1603 assert(!mxRBClickSequence->get_active());
1606 IMPL_LINK_NOARG(CustomAnimationDurationTabPage, DurationModifiedHdl, weld::MetricSpinButton&, void)
1608 if (!mxCBXDuration->get_text().isEmpty())
1610 double duration_value = static_cast<double>(mxCBXDuration->get_value(FieldUnit::NONE));
1611 if(duration_value <= 0.0)
1612 mxCBXDuration->set_value(1, FieldUnit::NONE);
1613 else
1614 mxCBXDuration->set_value(duration_value, FieldUnit::NONE);
1618 void CustomAnimationDurationTabPage::update( STLPropertySet* pSet )
1620 auto nPos = mxLBStart->get_active();
1621 if (nPos != -1)
1623 sal_Int16 nStart;
1624 sal_Int16 nOldStart = -1;
1626 switch( nPos )
1628 case 1: nStart = EffectNodeType::WITH_PREVIOUS; break;
1629 case 2: nStart = EffectNodeType::AFTER_PREVIOUS; break;
1630 default:
1631 nStart = EffectNodeType::ON_CLICK; break;
1634 if(mpSet->getPropertyState( nHandleStart ) != STLPropertyState::Ambiguous)
1635 mpSet->getPropertyValue( nHandleStart ) >>= nOldStart;
1637 if( nStart != nOldStart )
1638 pSet->setPropertyValue( nHandleStart, Any( nStart ) );
1642 double fBegin = static_cast<double>(mxMFStartDelay->get_value(FieldUnit::NONE)) / 10.0;
1643 double fOldBegin = -1.0;
1645 if( mpSet->getPropertyState( nHandleBegin ) != STLPropertyState::Ambiguous )
1646 mpSet->getPropertyValue( nHandleBegin ) >>= fOldBegin;
1648 if( fBegin != fOldBegin )
1649 pSet->setPropertyValue( nHandleBegin, Any( fBegin ) );
1652 nPos = mxCBRepeat->get_active();
1653 if (nPos != -1 || !mxCBRepeat->get_active_text().isEmpty())
1655 Any aRepeatCount;
1656 Any aEnd;
1658 switch( nPos )
1660 case 0:
1661 break;
1663 case 6:
1665 Event aEvent;
1666 aEvent.Trigger = EventTrigger::ON_NEXT;
1667 aEvent.Repeat = 0;
1668 aEnd <<= aEvent;
1670 [[fallthrough]];
1671 case 7:
1672 aRepeatCount <<= Timing_INDEFINITE;
1673 break;
1674 default:
1676 OUString aText(mxCBRepeat->get_text(nPos));
1677 if( !aText.isEmpty() )
1678 aRepeatCount <<= aText.toDouble();
1682 Any aOldRepeatCount( aRepeatCount );
1683 if( mpSet->getPropertyState( nHandleRepeat ) != STLPropertyState::Ambiguous )
1684 aOldRepeatCount = mpSet->getPropertyValue( nHandleRepeat );
1686 if( aRepeatCount != aOldRepeatCount )
1687 pSet->setPropertyValue( nHandleRepeat, aRepeatCount );
1689 Any aOldEnd( aEnd );
1690 if( mpSet->getPropertyState( nHandleEnd ) != STLPropertyState::Ambiguous )
1691 aOldEnd = mpSet->getPropertyValue( nHandleEnd );
1693 if( aEnd != aOldEnd )
1694 pSet->setPropertyValue( nHandleEnd, aEnd );
1697 double fDuration = -1.0;
1699 if (!mxCBXDuration->get_text().isEmpty())
1701 double duration_value = static_cast<double>(mxCBXDuration->get_value(FieldUnit::NONE));
1703 if(duration_value > 0)
1704 fDuration = duration_value/100.0;
1707 if( fDuration != -1.0 )
1709 double fOldDuration = -1;
1711 if( mpSet->getPropertyState( nHandleDuration ) != STLPropertyState::Ambiguous )
1712 mpSet->getPropertyValue( nHandleDuration ) >>= fOldDuration;
1714 if( fDuration != fOldDuration )
1715 pSet->setPropertyValue( nHandleDuration, Any( fDuration ) );
1718 if (mxCBXRewind->get_state() != TRISTATE_INDET)
1720 sal_Int16 nFill = mxCBXRewind->get_active() ? AnimationFill::REMOVE : AnimationFill::HOLD;
1722 bool bSet = true;
1724 if( mpSet->getPropertyState( nHandleRewind ) != STLPropertyState::Ambiguous )
1726 sal_Int16 nOldFill = 0;
1727 mpSet->getPropertyValue( nHandleRewind ) >>= nOldFill;
1728 bSet = nFill != nOldFill;
1731 if( bSet )
1732 pSet->setPropertyValue( nHandleRewind, Any( nFill ) );
1735 Reference< XShape > xTrigger;
1737 if (mxRBInteractive->get_active())
1739 nPos = mxLBTrigger->get_active();
1740 if (nPos != -1)
1742 sal_Int32 nShape = mxLBTrigger->get_id(nPos).toInt32();
1744 Reference< XDrawPage > xCurrentPage;
1745 mpSet->getPropertyValue( nHandleCurrentPage ) >>= xCurrentPage;
1747 if( xCurrentPage.is() && (nShape >= 0) && (nShape < xCurrentPage->getCount()) )
1748 xCurrentPage->getByIndex( nShape ) >>= xTrigger;
1752 if (xTrigger.is() || mxRBClickSequence->get_active())
1754 Any aNewValue( xTrigger );
1755 Any aOldValue;
1757 if( mpSet->getPropertyState( nHandleTrigger ) != STLPropertyState::Ambiguous )
1758 aOldValue = mpSet->getPropertyValue( nHandleTrigger );
1760 if( aNewValue != aOldValue )
1761 pSet->setPropertyValue( nHandleTrigger, aNewValue );
1765 class CustomAnimationTextAnimTabPage
1767 public:
1768 CustomAnimationTextAnimTabPage(weld::Container* pParent, const STLPropertySet* pSet);
1770 void update( STLPropertySet* pSet );
1772 void updateControlStates();
1773 DECL_LINK(implSelectHdl, weld::ComboBox&, void);
1775 private:
1776 const STLPropertySet* mpSet;
1777 bool mbHasVisibleShapes;
1779 std::unique_ptr<weld::Builder> mxBuilder;
1780 std::unique_ptr<weld::Container> mxContainer;
1781 std::unique_ptr<weld::ComboBox> mxLBGroupText;
1782 std::unique_ptr<weld::CheckButton> mxCBXGroupAuto;
1783 std::unique_ptr<weld::MetricSpinButton> mxMFGroupAuto;
1784 std::unique_ptr<weld::CheckButton> mxCBXAnimateForm;
1785 std::unique_ptr<weld::CheckButton> mxCBXReverse;
1788 CustomAnimationTextAnimTabPage::CustomAnimationTextAnimTabPage(weld::Container* pParent, const STLPropertySet* pSet)
1789 : mpSet(pSet)
1790 , mbHasVisibleShapes(true)
1791 , mxBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/customanimationtexttab.ui"_ustr))
1792 , mxContainer(mxBuilder->weld_container(u"TextAnimationTab"_ustr))
1793 , mxLBGroupText(mxBuilder->weld_combo_box(u"group_text_list"_ustr))
1794 , mxCBXGroupAuto(mxBuilder->weld_check_button(u"auto_after"_ustr))
1795 , mxMFGroupAuto(mxBuilder->weld_metric_spin_button(u"auto_after_value"_ustr,FieldUnit::SECOND))
1796 , mxCBXAnimateForm(mxBuilder->weld_check_button(u"animate_shape"_ustr))
1797 , mxCBXReverse(mxBuilder->weld_check_button(u"reverse_order"_ustr))
1799 mxLBGroupText->connect_changed(LINK(this, CustomAnimationTextAnimTabPage, implSelectHdl));
1801 if( pSet->getPropertyState( nHandleTextGrouping ) != STLPropertyState::Ambiguous )
1803 sal_Int32 nTextGrouping = 0;
1804 if( pSet->getPropertyValue( nHandleTextGrouping ) >>= nTextGrouping )
1805 mxLBGroupText->set_active(nTextGrouping + 1);
1808 if( pSet->getPropertyState( nHandleHasVisibleShape ) != STLPropertyState::Ambiguous )
1809 pSet->getPropertyValue( nHandleHasVisibleShape ) >>= mbHasVisibleShapes;
1811 if( pSet->getPropertyState( nHandleTextGroupingAuto ) != STLPropertyState::Ambiguous )
1813 double fTextGroupingAuto = 0.0;
1814 if( pSet->getPropertyValue( nHandleTextGroupingAuto ) >>= fTextGroupingAuto )
1816 mxCBXGroupAuto->set_active(fTextGroupingAuto >= 0.0);
1817 if( fTextGroupingAuto >= 0.0 )
1818 mxMFGroupAuto->set_value(static_cast<::tools::Long>(fTextGroupingAuto*10), FieldUnit::NONE);
1821 else
1823 mxCBXGroupAuto->set_state( TRISTATE_INDET );
1826 mxCBXAnimateForm->set_state( TRISTATE_INDET );
1827 if( pSet->getPropertyState( nHandleAnimateForm ) != STLPropertyState::Ambiguous )
1829 bool bAnimateForm = false;
1830 if( pSet->getPropertyValue( nHandleAnimateForm ) >>= bAnimateForm )
1832 mxCBXAnimateForm->set_active( bAnimateForm );
1835 else
1837 mxCBXAnimateForm->set_sensitive(false);
1840 mxCBXReverse->set_state(TRISTATE_INDET);
1841 if( pSet->getPropertyState( nHandleTextReverse ) != STLPropertyState::Ambiguous )
1843 bool bTextReverse = false;
1844 if( pSet->getPropertyValue( nHandleTextReverse ) >>= bTextReverse )
1846 mxCBXReverse->set_active( bTextReverse );
1850 if( pSet->getPropertyState( nHandleMaxParaDepth ) == STLPropertyState::Direct )
1852 sal_Int32 nMaxParaDepth = 0;
1853 pSet->getPropertyValue( nHandleMaxParaDepth ) >>= nMaxParaDepth;
1854 nMaxParaDepth += 1;
1856 sal_Int32 nPos = 6;
1857 while( (nPos > 2) && (nPos > nMaxParaDepth) )
1859 mxLBGroupText->remove(nPos);
1860 nPos--;
1864 updateControlStates();
1867 void CustomAnimationTextAnimTabPage::update( STLPropertySet* pSet )
1869 auto nPos = mxLBGroupText->get_active();
1870 if (nPos != -1)
1872 sal_Int32 nTextGrouping = nPos - 1;
1873 sal_Int32 nOldGrouping = -2;
1875 if(mpSet->getPropertyState( nHandleTextGrouping ) != STLPropertyState::Ambiguous)
1876 mpSet->getPropertyValue( nHandleTextGrouping ) >>= nOldGrouping;
1878 if( nTextGrouping != nOldGrouping )
1879 pSet->setPropertyValue( nHandleTextGrouping, Any( nTextGrouping ) );
1882 if (nPos != 0)
1884 bool bTextReverse = mxCBXReverse->get_active();
1885 bool bOldTextReverse = !bTextReverse;
1887 if(mpSet->getPropertyState( nHandleTextReverse ) != STLPropertyState::Ambiguous)
1888 mpSet->getPropertyValue( nHandleTextReverse ) >>= bOldTextReverse;
1890 if( bTextReverse != bOldTextReverse )
1891 pSet->setPropertyValue( nHandleTextReverse, Any( bTextReverse ) );
1893 if( nPos > 1 )
1895 double fTextGroupingAuto = mxCBXGroupAuto->get_active() ? mxMFGroupAuto->get_value(FieldUnit::NONE) / 10.0 : -1.0;
1896 double fOldTextGroupingAuto = -2.0;
1898 if(mpSet->getPropertyState( nHandleTextGroupingAuto ) != STLPropertyState::Ambiguous)
1899 mpSet->getPropertyValue( nHandleTextGroupingAuto ) >>= fOldTextGroupingAuto;
1901 if( fTextGroupingAuto != fOldTextGroupingAuto )
1902 pSet->setPropertyValue( nHandleTextGroupingAuto, Any( fTextGroupingAuto ) );
1905 //#i120049# impress crashes when modifying the "Random effects" animation
1906 //effect's trigger condition to "Start effect on click of".
1907 //If this control is disabled, we should ignore its value
1908 if (mxCBXAnimateForm->get_sensitive())
1910 bool bAnimateForm = mxCBXAnimateForm->get_active();
1911 bool bOldAnimateForm = !bAnimateForm;
1913 if(mpSet->getPropertyState( nHandleAnimateForm ) != STLPropertyState::Ambiguous)
1914 mpSet->getPropertyValue( nHandleAnimateForm ) >>= bOldAnimateForm;
1916 if( bAnimateForm != bOldAnimateForm )
1917 pSet->setPropertyValue( nHandleAnimateForm, Any( bAnimateForm ) );
1921 void CustomAnimationTextAnimTabPage::updateControlStates()
1923 auto nPos = mxLBGroupText->get_active();
1925 mxCBXGroupAuto->set_sensitive( nPos > 1 );
1926 mxMFGroupAuto->set_sensitive( nPos > 1 );
1927 mxCBXReverse->set_sensitive( nPos > 0 );
1929 if( !mbHasVisibleShapes && nPos > 0 )
1931 mxCBXAnimateForm->set_active(false);
1932 mxCBXAnimateForm->set_sensitive(false);
1934 else
1936 mxCBXAnimateForm->set_sensitive(true);
1940 IMPL_LINK_NOARG(CustomAnimationTextAnimTabPage, implSelectHdl, weld::ComboBox&, void)
1942 updateControlStates();
1945 CustomAnimationDialog::CustomAnimationDialog(weld::Window* pParent, std::unique_ptr<STLPropertySet> pSet, const OUString& rPage)
1946 : GenericDialogController(pParent, u"modules/simpress/ui/customanimationproperties.ui"_ustr, u"CustomAnimationProperties"_ustr)
1947 , mxSet(std::move(pSet))
1948 , mxTabControl(m_xBuilder->weld_notebook(u"tabcontrol"_ustr))
1949 , mxDurationTabPage(new CustomAnimationDurationTabPage(mxTabControl->get_page(u"timing"_ustr), mxSet.get()))
1950 , mxEffectTabPage(new CustomAnimationEffectTabPage(mxTabControl->get_page(u"effect"_ustr), m_xDialog.get(), mxSet.get()))
1952 bool bHasText = false;
1953 if( mxSet->getPropertyState( nHandleHasText ) != STLPropertyState::Ambiguous )
1954 mxSet->getPropertyValue( nHandleHasText ) >>= bHasText;
1956 if( bHasText )
1958 mxTextAnimTabPage.reset(new CustomAnimationTextAnimTabPage(mxTabControl->get_page(u"textanim"_ustr), mxSet.get()));
1960 else
1962 mxTabControl->remove_page(u"textanim"_ustr);
1965 if (!rPage.isEmpty())
1966 mxTabControl->set_current_page(rPage);
1969 CustomAnimationDialog::~CustomAnimationDialog()
1973 STLPropertySet* CustomAnimationDialog::getResultSet()
1975 mxResultSet = createDefaultSet();
1977 mxEffectTabPage->update( mxResultSet.get() );
1978 mxDurationTabPage->update( mxResultSet.get() );
1979 if (mxTextAnimTabPage)
1980 mxTextAnimTabPage->update( mxResultSet.get() );
1982 return mxResultSet.get();
1985 std::unique_ptr<STLPropertySet> CustomAnimationDialog::createDefaultSet()
1987 Any aEmpty;
1989 std::unique_ptr<STLPropertySet> pSet(new STLPropertySet());
1990 pSet->setPropertyDefaultValue( nHandleMaxParaDepth, Any( sal_Int32(-1) ) );
1992 pSet->setPropertyDefaultValue( nHandleHasAfterEffect, Any( false ) );
1993 pSet->setPropertyDefaultValue( nHandleAfterEffectOnNextEffect, Any( false ) );
1994 pSet->setPropertyDefaultValue( nHandleDimColor, aEmpty );
1995 pSet->setPropertyDefaultValue( nHandleIterateType, Any( sal_Int16(0) ) );
1996 pSet->setPropertyDefaultValue( nHandleIterateInterval, Any( 0.0 ) );
1998 pSet->setPropertyDefaultValue( nHandleStart, Any( sal_Int16(EffectNodeType::ON_CLICK) ) );
1999 pSet->setPropertyDefaultValue( nHandleBegin, Any( 0.0 ) );
2000 pSet->setPropertyDefaultValue( nHandleDuration, Any( 2.0 ) );
2001 pSet->setPropertyDefaultValue( nHandleRepeat, aEmpty );
2002 pSet->setPropertyDefaultValue( nHandleRewind, Any( AnimationFill::HOLD ) );
2004 pSet->setPropertyDefaultValue( nHandleEnd, aEmpty );
2006 pSet->setPropertyDefaultValue( nHandlePresetId, aEmpty );
2007 pSet->setPropertyDefaultValue( nHandleProperty1Type, Any( nPropertyTypeNone ) );
2008 pSet->setPropertyDefaultValue( nHandleProperty1Value, aEmpty );
2009 pSet->setPropertyDefaultValue( nHandleProperty2Type, Any( nPropertyTypeNone ) );
2010 pSet->setPropertyDefaultValue( nHandleProperty2Value, aEmpty );
2011 pSet->setPropertyDefaultValue( nHandleAccelerate, aEmpty );
2012 pSet->setPropertyDefaultValue( nHandleDecelerate, aEmpty );
2013 pSet->setPropertyDefaultValue( nHandleAutoReverse, aEmpty );
2014 pSet->setPropertyDefaultValue( nHandleTrigger, aEmpty );
2016 pSet->setPropertyDefaultValue( nHandleHasText, Any( false ) );
2017 pSet->setPropertyDefaultValue( nHandleHasVisibleShape, Any( false ) );
2018 pSet->setPropertyDefaultValue( nHandleTextGrouping, Any( sal_Int32(-1) ) );
2019 pSet->setPropertyDefaultValue( nHandleAnimateForm, Any( true ) );
2020 pSet->setPropertyDefaultValue( nHandleTextGroupingAuto, Any( -1.0 ) );
2021 pSet->setPropertyDefaultValue( nHandleTextReverse, Any( false ) );
2023 pSet->setPropertyDefaultValue( nHandleCurrentPage, aEmpty );
2025 pSet->setPropertyDefaultValue( nHandleSoundURL, aEmpty );
2026 pSet->setPropertyDefaultValue( nHandleSoundVolume, Any( 1.0) );
2027 pSet->setPropertyDefaultValue( nHandleSoundEndAfterSlide, Any( sal_Int32(0) ) );
2029 pSet->setPropertyDefaultValue( nHandleCommand, Any( sal_Int16(0) ) );
2030 return pSet;
2033 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)
2035 std::unique_ptr<SdPropertySubControl> pSubControl;
2036 switch( nType )
2038 case nPropertyTypeDirection:
2039 case nPropertyTypeSpokes:
2040 case nPropertyTypeZoom:
2041 pSubControl.reset( new SdPresetPropertyBox( pLabel, pParent, rValue, rPresetId, rModifyHdl ) );
2042 break;
2044 case nPropertyTypeColor:
2045 case nPropertyTypeFillColor:
2046 case nPropertyTypeFirstColor:
2047 case nPropertyTypeCharColor:
2048 case nPropertyTypeLineColor:
2049 pSubControl.reset( new SdColorPropertyBox( pLabel, pParent, pTopLevel, rValue, rModifyHdl ) );
2050 break;
2052 case nPropertyTypeFont:
2053 pSubControl.reset( new SdFontPropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2054 break;
2056 case nPropertyTypeCharHeight:
2057 pSubControl.reset( new SdCharHeightPropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2058 break;
2060 case nPropertyTypeRotate:
2061 pSubControl.reset( new SdRotationPropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2062 break;
2064 case nPropertyTypeTransparency:
2065 pSubControl.reset( new SdTransparencyPropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2066 break;
2068 case nPropertyTypeScale:
2069 pSubControl.reset( new SdScalePropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2070 break;
2072 case nPropertyTypeCharDecoration:
2073 pSubControl.reset( new SdFontStylePropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2074 break;
2077 return pSubControl;
2082 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */