Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/animations/CustomAnimationDialog.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
20
#include <config_features.h>
21
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>
35
36
#include <memory>
37
38
#include <comphelper/lok.hxx>
39
#include <i18nutil/unicode.hxx>
40
#include <vcl/metric.hxx>
41
#include <vcl/svapp.hxx>
42
#include <vcl/stdtext.hxx>
43
#include <vcl/weld/CheckButton.hxx>
44
#include <vcl/weld/ComboBox.hxx>
45
#include <vcl/weld/MenuButton.hxx>
46
#include <vcl/weld/MessageDialog.hxx>
47
#include <vcl/weld/RadioButton.hxx>
48
#include <vcl/settings.hxx>
49
50
#include <svtools/ctrltool.hxx>
51
#include <sfx2/objsh.hxx>
52
#include <sfx2/viewsh.hxx>
53
#include <tools/fldunit.hxx>
54
#include <tools/debug.hxx>
55
#include <tools/urlobj.hxx>
56
#include <comphelper/diagnose_ex.hxx>
57
58
#include <editeng/flstitem.hxx>
59
60
#include <svx/colorbox.hxx>
61
#include <svx/gallery.hxx>
62
63
#include <editeng/editids.hrc>
64
#include <sdresid.hxx>
65
66
#include "CustomAnimationDialog.hxx"
67
#include <CustomAnimationPane.hxx>
68
#include "STLPropertySet.hxx"
69
#include <CustomAnimationPreset.hxx>
70
71
#include <avmedia/mediawindow.hxx>
72
73
#include <filedlg.hxx>
74
#include <strings.hrc>
75
#include <helpids.h>
76
77
using namespace ::com::sun::star;
78
using namespace ::com::sun::star::animations;
79
using namespace ::com::sun::star::presentation;
80
81
using ::com::sun::star::uno::UNO_QUERY;
82
using ::com::sun::star::uno::Any;
83
using ::com::sun::star::uno::Sequence;
84
using ::com::sun::star::uno::Reference;
85
using ::com::sun::star::uno::Exception;
86
using ::com::sun::star::drawing::XShape;
87
using ::com::sun::star::drawing::XDrawPage;
88
using ::com::sun::star::beans::XPropertySet;
89
90
namespace sd {
91
92
SdPropertySubControl::SdPropertySubControl(weld::Container* pParent)
93
0
    : mxBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/customanimationfragment.ui"_ustr))
94
0
    , mxContainer(mxBuilder->weld_container(u"EffectFragment"_ustr))
95
0
    , mpParent(pParent)
96
0
{
97
0
}
98
99
SdPropertySubControl::~SdPropertySubControl()
100
0
{
101
0
    mpParent->move(mxContainer.get(), nullptr);
102
0
}
103
104
namespace {
105
106
class SdPresetPropertyBox  : public SdPropertySubControl
107
{
108
public:
109
    SdPresetPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const OUString& aPresetId, const Link<LinkParamNone*,void>& rModifyHdl);
110
111
    virtual Any getValue() override;
112
    virtual void setValue( const Any& rValue, const OUString& rPresetId ) override;
113
114
private:
115
    std::vector<OUString> maPropertyValues;
116
    Link<LinkParamNone*,void> maModifyLink;
117
    std::unique_ptr<weld::ComboBox> mxControl;
118
119
    DECL_LINK(OnSelect, weld::ComboBox&, void);
120
};
121
122
}
123
124
SdPresetPropertyBox::SdPresetPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const OUString& aPresetId, const Link<LinkParamNone*,void>& rModifyHdl)
125
0
    : SdPropertySubControl(pParent)
126
0
    , maModifyLink(rModifyHdl)
127
0
    , mxControl(mxBuilder->weld_combo_box(u"combo"_ustr))
128
0
{
129
0
    mxControl->connect_changed(LINK(this, SdPresetPropertyBox, OnSelect));
130
0
    mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_PRESETPROPERTYBOX);
131
0
    mxControl->show();
132
0
    pLabel->set_mnemonic_widget(mxControl.get());
133
0
    setValue(rValue, aPresetId);
134
0
}
135
136
IMPL_LINK_NOARG(SdPresetPropertyBox, OnSelect, weld::ComboBox&, void)
137
0
{
138
0
    maModifyLink.Call(nullptr);
139
0
}
140
141
void SdPresetPropertyBox::setValue( const Any& rValue, const OUString& rPresetId )
142
0
{
143
0
    if (!mxControl)
144
0
        return;
145
146
0
    mxControl->freeze();
147
0
    mxControl->clear();
148
0
    maPropertyValues.clear();
149
0
    int nPos = -1;
150
151
0
    const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
152
0
    CustomAnimationPresetPtr pDescriptor = rPresets.getEffectDescriptor( rPresetId );
153
0
    if( pDescriptor )
154
0
    {
155
156
0
        OUString aPropertyValue;
157
0
        rValue >>= aPropertyValue;
158
159
0
        std::vector<OUString> aSubTypes( pDescriptor->getSubTypes() );
160
161
0
        mxControl->set_sensitive(!aSubTypes.empty());
162
163
0
        for( const auto& aSubType : aSubTypes )
164
0
        {
165
0
            mxControl->append_text(rPresets.getUINameForProperty(aSubType));
166
0
            maPropertyValues.push_back(aSubType);
167
0
            if (aSubType == aPropertyValue)
168
0
                nPos = maPropertyValues.size() - 1;
169
0
        }
170
0
    }
171
0
    else
172
0
    {
173
0
        mxControl->set_sensitive(false);
174
0
    }
175
0
    mxControl->thaw();
176
0
    if (nPos != -1)
177
0
        mxControl->set_active(nPos);
178
0
}
179
180
Any SdPresetPropertyBox::getValue()
181
0
{
182
0
    const int nIndex = mxControl->get_active();
183
0
    if (nIndex == -1)
184
0
        return Any();
185
0
    return Any(maPropertyValues[nIndex]);
186
0
}
187
188
namespace {
189
190
class SdColorPropertyBox : public SdPropertySubControl
191
{
192
public:
193
    SdColorPropertyBox(weld::Label* pLabel, weld::Container* pParent, weld::Window* pTopLevel, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
194
195
    virtual Any getValue() override;
196
    virtual void setValue( const Any& rValue, const OUString& rPresetId  ) override;
197
198
private:
199
    Link<LinkParamNone*,void> maModifyLink;
200
    std::unique_ptr<ColorListBox> mxControl;
201
202
    DECL_LINK(OnSelect, ColorListBox&, void);
203
};
204
205
}
206
207
SdColorPropertyBox::SdColorPropertyBox(weld::Label* pLabel, weld::Container* pParent, weld::Window* pTopLevel, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
208
0
    : SdPropertySubControl(pParent)
209
0
    , maModifyLink(rModifyHdl)
210
0
    , mxControl(new ColorListBox(mxBuilder->weld_menu_button(u"color"_ustr), [pTopLevel]{ return pTopLevel; }))
211
0
{
212
0
    mxControl->SetSelectHdl(LINK(this, SdColorPropertyBox, OnSelect));
213
0
    mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_COLORPROPERTYBOX);
214
0
    pLabel->set_mnemonic_widget(&mxControl->get_widget());
215
0
    mxControl->show();
216
217
0
    Color nColor;
218
0
    rValue >>= nColor;
219
0
    mxControl->SelectEntry(nColor);
220
0
}
221
222
IMPL_LINK_NOARG(SdColorPropertyBox, OnSelect, ColorListBox&, void)
223
0
{
224
0
    maModifyLink.Call(nullptr);
225
0
}
226
227
void SdColorPropertyBox::setValue( const Any& rValue, const OUString& )
228
0
{
229
0
    if (mxControl)
230
0
    {
231
0
        Color nColor;
232
0
        rValue >>= nColor;
233
234
0
        mxControl->SetNoSelection();
235
0
        mxControl->SelectEntry(nColor);
236
0
    }
237
0
}
238
239
Any SdColorPropertyBox::getValue()
240
0
{
241
0
    return Any(sal_Int32(mxControl->GetSelectEntryColor().GetRGBColor()));
242
0
}
243
244
namespace {
245
246
class SdFontPropertyBox : public SdPropertySubControl
247
{
248
public:
249
    SdFontPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
250
251
    virtual Any getValue() override;
252
    virtual void setValue(const Any& rValue, const OUString& rPresetId) override;
253
254
private:
255
    Link<LinkParamNone*,void>   maModifyHdl;
256
    std::unique_ptr<weld::ComboBox> mxControl;
257
258
    DECL_LINK(ControlSelectHdl, weld::ComboBox&, void);
259
};
260
261
}
262
263
SdFontPropertyBox::SdFontPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
264
0
    : SdPropertySubControl(pParent)
265
0
    , maModifyHdl(rModifyHdl)
266
0
    , mxControl(mxBuilder->weld_combo_box(u"fontname"_ustr))
267
0
{
268
0
    mxControl->connect_changed(LINK(this, SdFontPropertyBox, ControlSelectHdl));
269
0
    mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTPROPERTYBOX);
270
0
    mxControl->show();
271
0
    pLabel->set_mnemonic_widget(mxControl.get());
272
273
0
    const FontList* pFontList = nullptr;
274
0
    bool bMustDelete = false;
275
276
0
    if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
277
0
    {
278
0
        const SvxFontListItem* pItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST );
279
0
        if (pItem)
280
0
            pFontList = pItem->GetFontList();
281
0
    }
282
283
0
    if (!pFontList)
284
0
    {
285
0
        pFontList = new FontList(Application::GetDefaultDevice(), nullptr);
286
0
        bMustDelete = true;
287
0
    }
288
289
0
    mxControl->freeze();
290
291
0
    sal_uInt16 nFontCount = pFontList->GetFontNameCount();
292
0
    for (sal_uInt16 i = 0; i < nFontCount; ++i)
293
0
    {
294
0
        const FontMetric& rFontMetric = pFontList->GetFontName(i);
295
0
        mxControl->append_text(rFontMetric.GetFamilyName());
296
0
    }
297
298
0
    mxControl->thaw();
299
300
0
    if( bMustDelete )
301
0
        delete pFontList;
302
303
0
    setValue( rValue, OUString() );
304
0
}
305
306
IMPL_LINK_NOARG(SdFontPropertyBox, ControlSelectHdl, weld::ComboBox&, void)
307
0
{
308
0
    maModifyHdl.Call(nullptr);
309
0
}
310
311
void SdFontPropertyBox::setValue( const Any& rValue, const OUString& )
312
0
{
313
0
    if (mxControl)
314
0
    {
315
0
        OUString aFontName;
316
0
        rValue >>= aFontName;
317
0
        mxControl->set_entry_text(aFontName);
318
0
    }
319
0
}
320
321
Any SdFontPropertyBox::getValue()
322
0
{
323
0
    OUString aFontName(mxControl->get_active_text());
324
0
    return Any(aFontName);
325
0
}
326
327
namespace {
328
329
class SdCharHeightPropertyBox : public SdPropertySubControl
330
{
331
public:
332
    SdCharHeightPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
333
334
    virtual Any getValue() override;
335
    virtual void setValue( const Any& rValue, const OUString& ) override;
336
337
    DECL_LINK(implMenuSelectHdl, const OUString& rIdent, void);
338
339
private:
340
    Link<LinkParamNone*,void> maModifyHdl;
341
    std::unique_ptr<weld::MetricSpinButton> mxMetric;
342
    std::unique_ptr<weld::MenuButton> mxControl;
343
344
    DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void);
345
};
346
347
}
348
349
SdCharHeightPropertyBox::SdCharHeightPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
350
0
    : SdPropertySubControl(pParent)
351
0
    , maModifyHdl(rModifyHdl)
352
0
    , mxMetric(mxBuilder->weld_metric_spin_button(u"fontsize"_ustr, FieldUnit::PERCENT))
353
0
    , mxControl(mxBuilder->weld_menu_button(u"fontsizemenu"_ustr))
354
0
{
355
0
    mxMetric->connect_value_changed(LINK(this, SdCharHeightPropertyBox, EditModifyHdl));
356
0
    mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_CHARHEIGHTPROPERTYBOX);
357
0
    mxMetric->show();
358
0
    pLabel->set_mnemonic_widget(&mxMetric->get_widget());
359
360
0
    mxControl->connect_selected(LINK(this, SdCharHeightPropertyBox, implMenuSelectHdl));
361
0
    mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_CHARHEIGHTPROPERTYBOX);
362
0
    mxControl->show();
363
364
0
    setValue(rValue, OUString());
365
0
}
366
367
IMPL_LINK_NOARG(SdCharHeightPropertyBox, EditModifyHdl, weld::MetricSpinButton&, void)
368
0
{
369
0
    maModifyHdl.Call(nullptr);
370
0
}
371
372
IMPL_LINK(SdCharHeightPropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
373
0
{
374
0
    sal_Int32 nValue = rIdent.toInt32();
375
0
    mxMetric->set_value(nValue, FieldUnit::PERCENT);
376
0
    EditModifyHdl(*mxMetric);
377
0
}
378
379
void SdCharHeightPropertyBox::setValue( const Any& rValue, const OUString& )
380
0
{
381
0
    if (mxMetric)
382
0
    {
383
0
        double fValue = 0.0;
384
0
        rValue >>= fValue;
385
0
        mxMetric->set_value(static_cast<::tools::Long>(fValue * 100.0), FieldUnit::PERCENT);
386
0
    }
387
0
}
388
389
Any SdCharHeightPropertyBox::getValue()
390
0
{
391
0
    return Any(static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0);
392
0
}
393
394
namespace {
395
396
class SdTransparencyPropertyBox : public SdPropertySubControl
397
{
398
public:
399
    SdTransparencyPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
400
401
    virtual Any getValue() override;
402
    virtual void setValue( const Any& rValue, const OUString& rPresetId  ) override;
403
404
    DECL_LINK(implMenuSelectHdl, const OUString&, void);
405
    DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void);
406
407
    void updateMenu();
408
409
private:
410
    Link<LinkParamNone*,void> maModifyHdl;
411
412
    std::unique_ptr<weld::MetricSpinButton> mxMetric;
413
    std::unique_ptr<weld::MenuButton> mxControl;
414
};
415
416
}
417
418
SdTransparencyPropertyBox::SdTransparencyPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
419
0
    : SdPropertySubControl(pParent)
420
0
    , maModifyHdl(rModifyHdl)
421
0
    , mxMetric(mxBuilder->weld_metric_spin_button(u"transparent"_ustr, FieldUnit::PERCENT))
422
0
    , mxControl(mxBuilder->weld_menu_button(u"transparentmenu"_ustr))
423
0
{
424
0
    for (sal_Int32 i = 25; i < 101; i += 25)
425
0
    {
426
0
        OUString aStr(unicode::formatPercent(i,
427
0
            Application::GetSettings().GetUILanguageTag()));
428
0
        mxControl->append_item_check(OUString::number(i), aStr);
429
0
    }
430
431
0
    mxControl->connect_selected(LINK(this, SdTransparencyPropertyBox, implMenuSelectHdl));
432
0
    mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_TRANSPARENCYPROPERTYBOX);
433
0
    mxControl->show();
434
435
0
    mxMetric->connect_value_changed(LINK(this, SdTransparencyPropertyBox, implModifyHdl));
436
0
    mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_TRANSPARENCYPROPERTYBOX);
437
0
    mxMetric->show();
438
0
    pLabel->set_mnemonic_widget(&mxMetric->get_widget());
439
440
0
    setValue(rValue, OUString());
441
0
}
442
443
void SdTransparencyPropertyBox::updateMenu()
444
0
{
445
0
    sal_Int64 nValue = mxMetric->get_value(FieldUnit::PERCENT);
446
0
    for (sal_uInt16 i = 25; i < 101; i += 25)
447
0
        mxControl->set_item_active(OUString::number(i), nValue == i);
448
0
}
449
450
IMPL_LINK_NOARG(SdTransparencyPropertyBox, implModifyHdl, weld::MetricSpinButton&, void)
451
0
{
452
0
    updateMenu();
453
0
    maModifyHdl.Call(nullptr);
454
0
}
455
456
IMPL_LINK(SdTransparencyPropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
457
0
{
458
0
    auto nValue = rIdent.toInt32();
459
0
    if (nValue != mxMetric->get_value(FieldUnit::PERCENT))
460
0
    {
461
0
        mxMetric->set_value(nValue, FieldUnit::PERCENT);
462
0
        implModifyHdl(*mxMetric);
463
0
    }
464
0
}
465
466
void SdTransparencyPropertyBox::setValue(const Any& rValue, const OUString&)
467
0
{
468
0
    if (mxMetric)
469
0
    {
470
0
        double fValue = 0.0;
471
0
        rValue >>= fValue;
472
0
        ::tools::Long nValue = static_cast<::tools::Long>(fValue * 100);
473
0
        mxMetric->set_value(nValue, FieldUnit::PERCENT);
474
0
        updateMenu();
475
0
    }
476
0
}
477
478
Any SdTransparencyPropertyBox::getValue()
479
0
{
480
0
    return Any(static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0);
481
0
}
482
483
namespace {
484
485
class SdRotationPropertyBox : public SdPropertySubControl
486
{
487
public:
488
    SdRotationPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
489
490
    virtual Any getValue() override;
491
    virtual void setValue( const Any& rValue, const OUString& ) override;
492
493
    DECL_LINK(implMenuSelectHdl, const OUString&, void);
494
    DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void);
495
496
    void updateMenu();
497
498
private:
499
    Link<LinkParamNone*,void> maModifyHdl;
500
501
    std::unique_ptr<weld::MetricSpinButton> mxMetric;
502
    std::unique_ptr<weld::MenuButton> mxControl;
503
};
504
505
}
506
507
SdRotationPropertyBox::SdRotationPropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
508
0
    : SdPropertySubControl(pParent)
509
0
    , maModifyHdl(rModifyHdl)
510
0
    , mxMetric(mxBuilder->weld_metric_spin_button(u"rotate"_ustr, FieldUnit::DEGREE))
511
0
    , mxControl(mxBuilder->weld_menu_button(u"rotatemenu"_ustr))
512
0
{
513
0
    mxMetric->connect_value_changed(LINK( this, SdRotationPropertyBox, implModifyHdl));
514
0
    mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_ROTATIONPROPERTYBOX);
515
0
    mxMetric->show();
516
0
    pLabel->set_mnemonic_widget(&mxMetric->get_widget());
517
518
0
    mxControl->connect_selected(LINK(this, SdRotationPropertyBox, implMenuSelectHdl));
519
0
    mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_ROTATIONPROPERTYBOX);
520
0
    mxControl->show();
521
522
0
    setValue(rValue, OUString());
523
0
}
524
525
void SdRotationPropertyBox::updateMenu()
526
0
{
527
0
    sal_Int64 nValue = mxMetric->get_value(FieldUnit::DEGREE);
528
0
    bool bDirection = nValue >= 0;
529
0
    if (nValue < 0) nValue = o3tl::saturating_toggle_sign(nValue);
530
531
0
    mxControl->set_item_active(u"90"_ustr, nValue == 90);
532
0
    mxControl->set_item_active(u"180"_ustr, nValue == 180);
533
0
    mxControl->set_item_active(u"360"_ustr, nValue == 360);
534
0
    mxControl->set_item_active(u"720"_ustr, nValue == 720);
535
536
0
    mxControl->set_item_active(u"clockwise"_ustr, bDirection);
537
0
    mxControl->set_item_active(u"counterclock"_ustr, !bDirection);
538
0
}
539
540
IMPL_LINK_NOARG(SdRotationPropertyBox, implModifyHdl, weld::MetricSpinButton&, void)
541
0
{
542
0
    updateMenu();
543
0
    maModifyHdl.Call(nullptr);
544
0
}
545
546
IMPL_LINK(SdRotationPropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
547
0
{
548
0
    auto nValue = mxMetric->get_value(FieldUnit::DEGREE);
549
0
    bool bDirection = nValue >= 0;
550
0
    if (nValue < 0) nValue = o3tl::saturating_toggle_sign(nValue);
551
552
0
    if (rIdent == "clockwise")
553
0
        bDirection = true;
554
0
    else if (rIdent == "counterclock")
555
0
        bDirection = false;
556
0
    else
557
0
        nValue = rIdent.toInt32();
558
559
0
    if( !bDirection )
560
0
        nValue = -nValue;
561
562
0
    if (nValue != mxMetric->get_value(FieldUnit::DEGREE))
563
0
    {
564
0
        mxMetric->set_value(nValue, FieldUnit::DEGREE);
565
0
        implModifyHdl(*mxMetric);
566
0
    }
567
0
}
568
569
void SdRotationPropertyBox::setValue( const Any& rValue, const OUString& )
570
0
{
571
0
    if (mxMetric)
572
0
    {
573
0
        double fValue = 0.0;
574
0
        rValue >>= fValue;
575
0
        ::tools::Long nValue = static_cast<::tools::Long>(fValue);
576
0
        mxMetric->set_value(nValue, FieldUnit::DEGREE);
577
0
        updateMenu();
578
0
    }
579
0
}
580
581
Any SdRotationPropertyBox::getValue()
582
0
{
583
0
    return Any(static_cast<double>(mxMetric->get_value(FieldUnit::DEGREE)));
584
0
}
585
586
namespace {
587
588
class SdScalePropertyBox : public SdPropertySubControl
589
{
590
public:
591
    SdScalePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
592
593
    virtual Any getValue() override;
594
    virtual void setValue( const Any& rValue, const OUString& ) override;
595
596
    DECL_LINK(implMenuSelectHdl, const OUString&, void);
597
    DECL_LINK(implModifyHdl, weld::MetricSpinButton&, void);
598
599
    void updateMenu();
600
601
private:
602
    Link<LinkParamNone*,void> maModifyHdl;
603
    int                       mnDirection;
604
605
    std::unique_ptr<weld::MetricSpinButton> mxMetric;
606
    std::unique_ptr<weld::MenuButton> mxControl;
607
};
608
609
}
610
611
SdScalePropertyBox::SdScalePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl)
612
0
    : SdPropertySubControl(pParent)
613
0
    , maModifyHdl( rModifyHdl )
614
0
    , mxMetric(mxBuilder->weld_metric_spin_button(u"scale"_ustr, FieldUnit::PERCENT))
615
0
    , mxControl(mxBuilder->weld_menu_button(u"scalemenu"_ustr))
616
0
{
617
0
    mxControl->connect_selected(LINK(this, SdScalePropertyBox, implMenuSelectHdl));
618
0
    mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_SCALEPROPERTYBOX);
619
0
    mxControl->show();
620
621
0
    mxMetric->connect_value_changed(LINK(this, SdScalePropertyBox, implModifyHdl));
622
0
    mxMetric->set_help_id(HID_SD_CUSTOMANIMATIONPANE_SCALEPROPERTYBOX);
623
0
    mxMetric->show();
624
0
    pLabel->set_mnemonic_widget(&mxMetric->get_widget());
625
626
0
    setValue(rValue, OUString());
627
0
}
628
629
void SdScalePropertyBox::updateMenu()
630
0
{
631
0
    auto nValue = mxMetric->get_value(FieldUnit::PERCENT);
632
633
0
    mxControl->set_item_active(u"25scale"_ustr, nValue == 25);
634
0
    mxControl->set_item_active(u"50scale"_ustr, nValue == 50);
635
0
    mxControl->set_item_active(u"150scale"_ustr, nValue == 150);
636
0
    mxControl->set_item_active(u"400scale"_ustr, nValue == 400);
637
638
0
    mxControl->set_item_active(u"hori"_ustr, mnDirection == 1);
639
0
    mxControl->set_item_active(u"vert"_ustr, mnDirection == 2);
640
0
    mxControl->set_item_active(u"both"_ustr, mnDirection == 3);
641
0
}
642
643
IMPL_LINK_NOARG(SdScalePropertyBox, implModifyHdl, weld::MetricSpinButton&, void)
644
0
{
645
0
    updateMenu();
646
0
    maModifyHdl.Call(nullptr);
647
0
}
648
649
IMPL_LINK(SdScalePropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
650
0
{
651
0
    auto nValue = mxMetric->get_value(FieldUnit::PERCENT);
652
653
0
    int nDirection = mnDirection;
654
655
0
    if (rIdent == "hori")
656
0
        nDirection = 1;
657
0
    else if (rIdent == "vert")
658
0
        nDirection = 2;
659
0
    else if (rIdent == "both")
660
0
        nDirection = 3;
661
0
    else
662
0
        nValue = rIdent.toInt32(); // Getting here indicates a UI bug and should be handled better
663
664
0
    bool bModified = false;
665
666
0
    if( nDirection != mnDirection )
667
0
    {
668
0
        mnDirection = nDirection;
669
0
        bModified = true;
670
0
    }
671
672
0
    if (nValue != mxMetric->get_value(FieldUnit::PERCENT))
673
0
    {
674
0
        mxMetric->set_value(nValue, FieldUnit::PERCENT);
675
0
        bModified = true;
676
0
    }
677
678
0
    if(bModified)
679
0
    {
680
0
        implModifyHdl(*mxMetric);
681
0
        updateMenu();
682
0
    }
683
0
}
684
685
void SdScalePropertyBox::setValue(const Any& rValue, const OUString&)
686
0
{
687
0
    if (!mxMetric)
688
0
        return;
689
690
0
    ValuePair aValues;
691
0
    rValue >>= aValues;
692
693
0
    double fValue1 = 0.0;
694
0
    double fValue2 = 0.0;
695
696
0
    aValues.First >>= fValue1;
697
0
    aValues.Second >>= fValue2;
698
699
    // 'Size' drop down menu set by mnDirection when loading Grow and Shrink Animation
700
    // Shouldn't compare a float directly to zero... should be fixed with delta epsilon compare
701
    // Might be better to just have a flag in the content.xml for this
702
0
    if( (fValue1 == 0.0) && (fValue2 == 0.0) )
703
0
        mnDirection = 3; // assume 'Both' scaling option when both are zero
704
0
    else if( (fValue1 != 0.0) && (fValue2 == 0.0) )
705
0
        mnDirection = 1;
706
0
    else if( (fValue1 == 0.0) && (fValue2 != 0.0) )
707
0
        mnDirection = 2;
708
0
    else
709
0
        mnDirection = 3;
710
711
    // Grow and Shrink Animation is a relative change with value stored in content.xml under tag
712
    // smil:by=*,*
713
    // An offset of 1 must be added to properly translate from content.xml to UI value displayed
714
    // 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
715
    // size horizontal and vertical
716
    // 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%
717
    // of the size horizontal and vertical
718
0
    fValue1 += 1;
719
0
    fValue2 += 1;
720
721
    // Determine value from file for UI 'Size' field based on determined mnDirection
722
0
    ::tools::Long nValue;
723
0
    if( mnDirection == 1 )
724
0
        nValue = static_cast<::tools::Long>(fValue1 * 100.0);
725
0
    else if( mnDirection == 2 )
726
0
        nValue = static_cast<::tools::Long>(fValue2 * 100.0);
727
0
    else if( mnDirection == 3 ){
728
0
        if (fValue1 >= fValue2)
729
0
            nValue = static_cast<::tools::Long>(fValue1 * 100.0);
730
0
        else
731
0
            nValue = static_cast<::tools::Long>(fValue2 * 100.0);
732
0
    }
733
0
    else
734
0
        nValue = static_cast<::tools::Long>(100.0); // default to 100% in UI if something goes wrong
735
736
0
    mxMetric->set_value(nValue, FieldUnit::PERCENT);
737
0
    updateMenu();
738
0
}
739
740
Any SdScalePropertyBox::getValue()
741
0
{
742
0
    double fValue1 = static_cast<double>(mxMetric->get_value(FieldUnit::PERCENT)) / 100.0;
743
744
    // Grow and Shrink Animation is a relative change with value stored in content.xml under tag
745
    // smil:by=*,*
746
    // An offset of 1 must be subtracted to properly translate UI value displayed and save to
747
    // content.xml
748
    // 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
749
    // 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
750
0
    fValue1 -= 1;
751
752
0
    double fValue2 = fValue1;
753
754
    // mnDirection set by 'Size' drop down menu and used to zero out either horizontal or vertical
755
    // scaling depending on what option is selected
756
0
    if( mnDirection == 1 )
757
0
        fValue2 = 0.0;
758
0
    else if( mnDirection == 2 )
759
0
        fValue1 = 0.0;
760
761
0
    ValuePair aValues;
762
0
    aValues.First <<= fValue1;
763
0
    aValues.Second <<= fValue2;
764
765
0
    return Any( aValues );
766
0
}
767
768
namespace {
769
770
class SdFontStylePropertyBox : public SdPropertySubControl
771
{
772
public:
773
    SdFontStylePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl);
774
775
    virtual Any getValue() override;
776
    virtual void setValue( const Any& rValue, const OUString& ) override;
777
778
    DECL_LINK(implMenuSelectHdl, const OUString&, void);
779
780
    void update();
781
782
private:
783
    float mfFontWeight;
784
    awt::FontSlant meFontSlant;
785
    sal_Int16 mnFontUnderline;
786
    Link<LinkParamNone*,void> maModifyHdl;
787
788
    std::unique_ptr<weld::Entry> mxEdit;
789
    std::unique_ptr<weld::MenuButton> mxControl;
790
};
791
792
}
793
794
SdFontStylePropertyBox::SdFontStylePropertyBox(weld::Label* pLabel, weld::Container* pParent, const Any& rValue, const Link<LinkParamNone*,void>& rModifyHdl )
795
0
    : SdPropertySubControl(pParent)
796
0
    , maModifyHdl( rModifyHdl )
797
0
    , mxEdit(mxBuilder->weld_entry(u"entry"_ustr))
798
0
    , mxControl(mxBuilder->weld_menu_button(u"entrymenu"_ustr))
799
0
{
800
0
    mxEdit->set_text(SdResId(STR_CUSTOMANIMATION_SAMPLE));
801
0
    mxEdit->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTSTYLEPROPERTYBOX);
802
0
    pLabel->set_mnemonic_widget(mxEdit.get());
803
0
    mxEdit->show();
804
805
0
    mxControl->connect_selected(LINK(this, SdFontStylePropertyBox, implMenuSelectHdl));
806
0
    mxControl->set_help_id(HID_SD_CUSTOMANIMATIONPANE_FONTSTYLEPROPERTYBOX);
807
0
    mxControl->show();
808
809
0
    setValue(rValue, OUString());
810
0
}
811
812
void SdFontStylePropertyBox::update()
813
0
{
814
    // update menu
815
0
    mxControl->set_item_active(u"bold"_ustr, mfFontWeight == awt::FontWeight::BOLD);
816
0
    mxControl->set_item_active(u"italic"_ustr, meFontSlant == awt::FontSlant_ITALIC);
817
0
    mxControl->set_item_active(u"underline"_ustr, mnFontUnderline != awt::FontUnderline::NONE );
818
819
    // update sample edit
820
0
    vcl::Font aFont(mxEdit->get_font());
821
0
    aFont.SetWeight(mfFontWeight == awt::FontWeight::BOLD ? WEIGHT_BOLD : WEIGHT_NORMAL);
822
0
    aFont.SetItalic(meFontSlant == awt::FontSlant_ITALIC ? ITALIC_NORMAL : ITALIC_NONE);
823
0
    aFont.SetUnderline(mnFontUnderline == awt::FontUnderline::NONE ? LINESTYLE_NONE : LINESTYLE_SINGLE);
824
0
    mxEdit->set_font(aFont);
825
0
}
826
827
IMPL_LINK(SdFontStylePropertyBox, implMenuSelectHdl, const OUString&, rIdent, void)
828
0
{
829
0
    if (rIdent == "bold")
830
0
    {
831
0
        if( mfFontWeight == awt::FontWeight::BOLD )
832
0
            mfFontWeight = awt::FontWeight::NORMAL;
833
0
        else
834
0
            mfFontWeight = awt::FontWeight::BOLD;
835
0
    }
836
0
    else if (rIdent == "italic")
837
0
    {
838
0
        if( meFontSlant == awt::FontSlant_ITALIC )
839
0
            meFontSlant = awt::FontSlant_NONE;
840
0
        else
841
0
            meFontSlant = awt::FontSlant_ITALIC;
842
0
    }
843
0
    else if (rIdent == "underline")
844
0
    {
845
0
        if( mnFontUnderline == awt::FontUnderline::SINGLE )
846
0
            mnFontUnderline = awt::FontUnderline::NONE;
847
0
        else
848
0
            mnFontUnderline = awt::FontUnderline::SINGLE;
849
0
    }
850
851
0
    update();
852
0
    maModifyHdl.Call(nullptr);
853
0
}
854
855
void SdFontStylePropertyBox::setValue( const Any& rValue, const OUString& )
856
0
{
857
0
    Sequence<Any> aValues;
858
0
    rValue >>= aValues;
859
860
0
    aValues[0] >>= mfFontWeight;
861
0
    aValues[1] >>= meFontSlant;
862
0
    aValues[2] >>= mnFontUnderline;
863
864
0
    update();
865
0
}
866
867
Any SdFontStylePropertyBox::getValue()
868
0
{
869
0
    Sequence<Any> aValues{ Any(mfFontWeight), Any(meFontSlant), Any(mnFontUnderline) };
870
0
    return Any( aValues );
871
0
}
872
873
class CustomAnimationEffectTabPage
874
{
875
public:
876
    CustomAnimationEffectTabPage(weld::Container* pParent, weld::Window* pDialog, const STLPropertySet* pSet);
877
878
    void update( STLPropertySet* pSet );
879
    DECL_LINK(implSelectHdl, weld::ComboBox&, void);
880
    DECL_LINK(implClickHdl, weld::Button&, void);
881
    void implHdl(const weld::Widget*);
882
883
private:
884
    void updateControlStates();
885
    void fillSoundListBox();
886
    void clearSoundListBox();
887
    sal_Int32 getSoundObject( std::u16string_view rStr );
888
    void openSoundFileDialog();
889
    void onSoundPreview();
890
0
    weld::Window* GetFrameWeld() const { return mpDialog; }
891
892
private:
893
    ::std::vector< OUString > maSoundList;
894
    bool mbHasText;
895
    const STLPropertySet* mpSet;
896
    css::uno::Reference<css::media::XPlayer> mxPlayer;
897
898
    weld::Window* mpDialog;
899
    std::unique_ptr<weld::Builder> mxBuilder;
900
    std::unique_ptr<weld::Container> mxContainer;
901
    std::unique_ptr<weld::Widget> mxSettings;
902
    std::unique_ptr<weld::Label> mxFTProperty1;
903
    std::unique_ptr<weld::Container> mxPlaceholderBox;
904
    std::unique_ptr<weld::CheckButton> mxCBSmoothStart;
905
    std::unique_ptr<weld::CheckButton> mxCBSmoothEnd;
906
    std::unique_ptr<weld::Label> mxFTSound;
907
    std::unique_ptr<weld::ComboBox> mxLBSound;
908
    std::unique_ptr<weld::Button> mxPBSoundPreview;
909
    std::unique_ptr<weld::ComboBox> mxLBAfterEffect;
910
    std::unique_ptr<weld::Label> mxFTDimColor;
911
    std::unique_ptr<ColorListBox> mxCLBDimColor;
912
    std::unique_ptr<weld::Label> mxFTTextAnim;
913
    std::unique_ptr<weld::ComboBox> mxLBTextAnim;
914
    std::unique_ptr<weld::MetricSpinButton> mxMFTextDelay;
915
    std::unique_ptr<weld::Label> mxFTTextDelay;
916
    std::unique_ptr<SdPropertySubControl> mxLBSubControl;
917
};
918
919
CustomAnimationEffectTabPage::CustomAnimationEffectTabPage(weld::Container* pParent, weld::Window* pDialog, const STLPropertySet* pSet)
920
0
    : mbHasText(false)
921
0
    , mpSet(pSet)
922
0
    , mpDialog(pDialog)
923
0
    , mxBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/customanimationeffecttab.ui"_ustr))
924
0
    , mxContainer(mxBuilder->weld_container(u"EffectTab"_ustr))
925
0
    , mxSettings(mxBuilder->weld_widget(u"settings"_ustr))
926
0
    , mxFTProperty1(mxBuilder->weld_label(u"prop_label1"_ustr))
927
0
    , mxPlaceholderBox(mxBuilder->weld_container(u"placeholder"_ustr))
928
0
    , mxCBSmoothStart(mxBuilder->weld_check_button(u"smooth_start"_ustr))
929
0
    , mxCBSmoothEnd(mxBuilder->weld_check_button(u"smooth_end"_ustr))
930
0
    , mxFTSound(mxBuilder->weld_label(u"sound_label"_ustr))
931
0
    , mxLBSound(mxBuilder->weld_combo_box(u"sound_list"_ustr))
932
0
    , mxPBSoundPreview(mxBuilder->weld_button(u"sound_preview"_ustr))
933
0
    , mxLBAfterEffect(mxBuilder->weld_combo_box(u"aeffect_list"_ustr))
934
0
    , mxFTDimColor(mxBuilder->weld_label(u"dim_color_label"_ustr))
935
0
    , mxCLBDimColor(new ColorListBox(mxBuilder->weld_menu_button(u"dim_color_list"_ustr), [pDialog]{ return pDialog; }))
936
0
    , mxFTTextAnim(mxBuilder->weld_label(u"text_animation_label"_ustr))
937
0
    , mxLBTextAnim(mxBuilder->weld_combo_box(u"text_animation_list"_ustr))
938
0
    , mxMFTextDelay(mxBuilder->weld_metric_spin_button(u"text_delay"_ustr, FieldUnit::PERCENT))
939
0
    , mxFTTextDelay(mxBuilder->weld_label(u"text_delay_label"_ustr))
940
0
{
941
0
    mxCLBDimColor->SelectEntry(COL_BLACK);
942
943
    // fill the soundbox
944
0
    fillSoundListBox();
945
946
0
    mxLBSound->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl));
947
0
    mxPBSoundPreview->connect_clicked(LINK(this, CustomAnimationEffectTabPage, implClickHdl));
948
949
    // only show settings if all selected effects have the same preset-id
950
0
    if( pSet->getPropertyState( nHandlePresetId ) != STLPropertyState::Ambiguous )
951
0
    {
952
0
        OUString aPresetId;
953
0
        pSet->getPropertyValue( nHandlePresetId ) >>= aPresetId;
954
955
        // property 1
956
957
0
        if( pSet->getPropertyState( nHandleProperty1Type ) != STLPropertyState::Ambiguous )
958
0
        {
959
0
            sal_Int32 nType = 0;
960
0
            pSet->getPropertyValue( nHandleProperty1Type ) >>= nType;
961
962
0
            if( nType != nPropertyTypeNone )
963
0
            {
964
                // set ui name for property at fixed text
965
0
                OUString aPropertyName( getPropertyName( nType ) );
966
967
0
                if( !aPropertyName.isEmpty() )
968
0
                {
969
0
                    mxSettings->show();
970
0
                    mxFTProperty1->set_label(aPropertyName);
971
0
                }
972
973
                // get property value
974
0
                const Any aValue( pSet->getPropertyValue( nHandleProperty1Value ) );
975
976
                // create property sub control
977
0
                mxLBSubControl = SdPropertySubControl::create(nType, mxFTProperty1.get(), mxPlaceholderBox.get(), mpDialog, aValue, aPresetId, Link<LinkParamNone*,void>());
978
0
            }
979
0
        }
980
981
0
        mxFTProperty1->set_sensitive(mxPlaceholderBox->get_sensitive());
982
983
        // accelerate & decelerate
984
985
0
        if( pSet->getPropertyState( nHandleAccelerate ) == STLPropertyState::Direct )
986
0
        {
987
0
            mxCBSmoothStart->show();
988
0
            mxCBSmoothEnd->show();
989
990
0
            double fTemp = 0.0;
991
0
            pSet->getPropertyValue( nHandleAccelerate ) >>= fTemp;
992
0
            mxCBSmoothStart->set_active( fTemp > 0.0 );
993
994
0
            pSet->getPropertyValue( nHandleDecelerate ) >>= fTemp;
995
0
            mxCBSmoothEnd->set_active( fTemp > 0.0 );
996
0
        }
997
0
    }
998
999
    // init after effect controls
1000
1001
0
    mxLBAfterEffect->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl));
1002
0
    mxLBTextAnim->connect_changed(LINK(this, CustomAnimationEffectTabPage, implSelectHdl));
1003
1004
0
    if( (pSet->getPropertyState( nHandleHasAfterEffect ) != STLPropertyState::Ambiguous) &&
1005
0
        (pSet->getPropertyState( nHandleAfterEffectOnNextEffect ) != STLPropertyState::Ambiguous) &&
1006
0
        (pSet->getPropertyState( nHandleDimColor ) != STLPropertyState::Ambiguous))
1007
0
    {
1008
0
        bool bHasAfterEffect = false;
1009
0
        pSet->getPropertyValue( nHandleHasAfterEffect ) >>= bHasAfterEffect;
1010
1011
0
        sal_Int32 nPos = 0;
1012
0
        if( bHasAfterEffect )
1013
0
        {
1014
0
            nPos++;
1015
1016
0
            bool bAfterEffectOnNextClick = false;
1017
0
            pSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bAfterEffectOnNextClick;
1018
0
            Any aDimColor( pSet->getPropertyValue( nHandleDimColor ) );
1019
1020
0
            if( aDimColor.hasValue() )
1021
0
            {
1022
0
                Color aColor;
1023
0
                aDimColor >>= aColor;
1024
0
                mxCLBDimColor->SelectEntry(aColor);
1025
0
            }
1026
0
            else
1027
0
            {
1028
0
                nPos++;
1029
0
                if( bAfterEffectOnNextClick )
1030
0
                    nPos++;
1031
0
            }
1032
0
        }
1033
1034
0
        mxLBAfterEffect->set_active(nPos);
1035
0
    }
1036
1037
0
    if( pSet->getPropertyState( nHandleHasText ) != STLPropertyState::Ambiguous )
1038
0
        pSet->getPropertyValue( nHandleHasText ) >>= mbHasText;
1039
1040
0
    if( mbHasText )
1041
0
    {
1042
0
        if( pSet->getPropertyState( nHandleIterateType ) != STLPropertyState::Ambiguous)
1043
0
        {
1044
0
            int nPos = -1;
1045
1046
0
            sal_Int32 nIterateType = 0;
1047
0
            pSet->getPropertyValue( nHandleIterateType ) >>= nIterateType;
1048
0
            switch( nIterateType )
1049
0
            {
1050
0
            case TextAnimationType::BY_PARAGRAPH:   nPos = 0; break;
1051
0
            case TextAnimationType::BY_WORD:        nPos = 1; break;
1052
0
            case TextAnimationType::BY_LETTER:      nPos = 2; break;
1053
0
            }
1054
1055
0
            mxLBTextAnim->set_active(nPos);
1056
0
        }
1057
1058
0
        if( pSet->getPropertyState( nHandleIterateInterval ) != STLPropertyState::Default )
1059
0
        {
1060
0
            double fIterateInterval = 0.0;
1061
0
            pSet->getPropertyValue( nHandleIterateInterval ) >>= fIterateInterval;
1062
0
            mxMFTextDelay->set_value(static_cast<::tools::Long>(fIterateInterval*10), FieldUnit::NONE);
1063
0
        }
1064
0
    }
1065
0
    else
1066
0
    {
1067
0
        mxFTTextAnim->set_sensitive(false);
1068
0
        mxLBTextAnim->set_sensitive(false);
1069
0
        mxMFTextDelay->set_sensitive(false);
1070
0
        mxFTTextDelay->set_sensitive(false);
1071
1072
0
    }
1073
1074
0
    if( pSet->getPropertyState( nHandleSoundURL ) != STLPropertyState::Ambiguous )
1075
0
    {
1076
0
        sal_Int32 nPos = 0;
1077
1078
0
        const Any aValue( pSet->getPropertyValue( nHandleSoundURL ) );
1079
1080
0
        if( aValue.getValueType() == ::cppu::UnoType<sal_Bool>::get() )
1081
0
        {
1082
0
            nPos = 1;
1083
0
        }
1084
0
        else
1085
0
        {
1086
0
            OUString aSoundURL;
1087
0
            aValue >>= aSoundURL;
1088
1089
0
            if( !aSoundURL.isEmpty() )
1090
0
            {
1091
0
                sal_uLong i;
1092
0
                for( i = 0; i < maSoundList.size(); i++ )
1093
0
                {
1094
0
                    OUString aString = maSoundList[ i ];
1095
0
                    if( aString == aSoundURL )
1096
0
                    {
1097
0
                        nPos = static_cast<sal_Int32>(i)+2;
1098
0
                        break;
1099
0
                    }
1100
0
                }
1101
1102
0
                if( nPos == 0 )
1103
0
                {
1104
0
                    nPos = static_cast<sal_Int32>(maSoundList.size())+2;
1105
0
                    maSoundList.push_back( aSoundURL );
1106
0
                    INetURLObject aURL( aSoundURL );
1107
0
                    mxLBSound->insert_text(nPos, aURL.GetBase());
1108
0
                }
1109
0
            }
1110
0
        }
1111
1112
0
        if( nPos != -1)
1113
0
            mxLBSound->set_active(nPos);
1114
0
    }
1115
1116
0
    updateControlStates();
1117
1118
0
}
1119
1120
void CustomAnimationEffectTabPage::updateControlStates()
1121
0
{
1122
0
    auto nPos = mxLBAfterEffect->get_active();
1123
0
    mxCLBDimColor->set_sensitive( nPos == 1 );
1124
0
    mxFTDimColor->set_sensitive( nPos == 1 );
1125
1126
0
    if( mbHasText )
1127
0
    {
1128
0
        nPos = mxLBTextAnim->get_active();
1129
0
        mxMFTextDelay->set_sensitive( nPos != 0 );
1130
0
        mxFTTextDelay->set_sensitive( nPos != 0 );
1131
0
    }
1132
1133
0
    if (comphelper::LibreOfficeKit::isActive())
1134
0
    {
1135
0
        mxFTSound->hide();
1136
0
        mxLBSound->hide();
1137
0
        mxPBSoundPreview->hide();
1138
0
    }
1139
0
    else
1140
0
    {
1141
0
        nPos = mxLBSound->get_active();
1142
0
        mxPBSoundPreview->set_sensitive( nPos >= 2 );
1143
0
    }
1144
1145
0
}
1146
1147
IMPL_LINK(CustomAnimationEffectTabPage, implClickHdl, weld::Button&, rBtn, void)
1148
0
{
1149
0
    implHdl(&rBtn);
1150
0
}
1151
1152
IMPL_LINK(CustomAnimationEffectTabPage, implSelectHdl, weld::ComboBox&, rListBox, void)
1153
0
{
1154
0
    implHdl(&rListBox);
1155
0
}
1156
1157
void CustomAnimationEffectTabPage::implHdl(const weld::Widget* pControl)
1158
0
{
1159
0
    if (pControl == mxLBTextAnim.get())
1160
0
    {
1161
0
        if (mxMFTextDelay->get_value(FieldUnit::NONE) == 0)
1162
0
            mxMFTextDelay->set_value(100, FieldUnit::NONE);
1163
0
    }
1164
0
    else if (pControl == mxLBSound.get())
1165
0
    {
1166
0
        auto nPos = mxLBSound->get_active();
1167
0
        if (nPos == (mxLBSound->get_count() - 1))
1168
0
        {
1169
0
            openSoundFileDialog();
1170
0
        }
1171
0
    }
1172
0
    else if (pControl == mxPBSoundPreview.get())
1173
0
    {
1174
0
        onSoundPreview();
1175
0
    }
1176
1177
0
    updateControlStates();
1178
0
}
1179
1180
void CustomAnimationEffectTabPage::update( STLPropertySet* pSet )
1181
0
{
1182
0
    if (mxLBSubControl)
1183
0
    {
1184
0
        Any aNewValue(mxLBSubControl->getValue());
1185
0
        Any aOldValue;
1186
0
        if( mpSet->getPropertyState( nHandleProperty1Value ) != STLPropertyState::Ambiguous)
1187
0
            aOldValue = mpSet->getPropertyValue( nHandleProperty1Value );
1188
1189
0
        if( aOldValue != aNewValue )
1190
0
            pSet->setPropertyValue( nHandleProperty1Value, aNewValue );
1191
0
    }
1192
1193
0
    if (mxCBSmoothStart->get_visible())
1194
0
    {
1195
        // set selected value for accelerate if different than in original set
1196
1197
0
        double fTemp = mxCBSmoothStart->get_active() ? 0.5 : 0.0;
1198
1199
0
        double fOldTemp = 0.0;
1200
0
        if(mpSet->getPropertyState( nHandleAccelerate ) != STLPropertyState::Ambiguous)
1201
0
            mpSet->getPropertyValue( nHandleAccelerate ) >>= fOldTemp;
1202
0
        else
1203
0
            fOldTemp = -2.0;
1204
1205
0
        if( fOldTemp != fTemp )
1206
0
            pSet->setPropertyValue( nHandleAccelerate, Any( fTemp ) );
1207
1208
        // set selected value for decelerate if different than in original set
1209
0
        fTemp = mxCBSmoothEnd->get_active() ? 0.5 : 0.0;
1210
1211
0
        if(mpSet->getPropertyState( nHandleDecelerate ) != STLPropertyState::Ambiguous)
1212
0
            mpSet->getPropertyValue( nHandleDecelerate ) >>= fOldTemp;
1213
0
        else
1214
0
            fOldTemp = -2.0;
1215
1216
0
        if( fOldTemp != fTemp )
1217
0
            pSet->setPropertyValue( nHandleDecelerate, Any( fTemp ) );
1218
0
    }
1219
1220
0
    auto nPos = mxLBAfterEffect->get_active();
1221
0
    if (nPos != -1)
1222
0
    {
1223
0
        bool bAfterEffect = nPos != 0;
1224
1225
0
        bool bOldAfterEffect = false;
1226
1227
0
        if(mpSet->getPropertyState( nHandleHasAfterEffect ) != STLPropertyState::Ambiguous)
1228
0
            mpSet->getPropertyValue( nHandleHasAfterEffect ) >>= bOldAfterEffect;
1229
0
        else
1230
0
            bOldAfterEffect = !bAfterEffect;
1231
1232
0
        if( bOldAfterEffect != bAfterEffect )
1233
0
            pSet->setPropertyValue( nHandleHasAfterEffect, Any( bAfterEffect ) );
1234
1235
0
        Any aDimColor;
1236
0
        if( nPos == 1 )
1237
0
        {
1238
0
            Color aSelectedColor = mxCLBDimColor->GetSelectEntryColor();
1239
0
            aDimColor <<= aSelectedColor.GetRGBColor();
1240
0
        }
1241
1242
0
        if( (mpSet->getPropertyState( nHandleDimColor ) == STLPropertyState::Ambiguous) ||
1243
0
            (mpSet->getPropertyValue( nHandleDimColor ) != aDimColor) )
1244
0
            pSet->setPropertyValue( nHandleDimColor, aDimColor );
1245
1246
0
        bool bAfterEffectOnNextEffect = nPos != 2;
1247
0
        bool bOldAfterEffectOnNextEffect = !bAfterEffectOnNextEffect;
1248
1249
0
        if( mpSet->getPropertyState( nHandleAfterEffectOnNextEffect ) != STLPropertyState::Ambiguous)
1250
0
            mpSet->getPropertyValue( nHandleAfterEffectOnNextEffect ) >>= bOldAfterEffectOnNextEffect;
1251
1252
0
        if( bAfterEffectOnNextEffect != bOldAfterEffectOnNextEffect )
1253
0
            pSet->setPropertyValue( nHandleAfterEffectOnNextEffect, Any( bAfterEffectOnNextEffect ) );
1254
0
    }
1255
1256
0
    nPos = mxLBTextAnim->get_active();
1257
0
    if (nPos != -1)
1258
0
    {
1259
0
        sal_Int16 nIterateType;
1260
1261
0
        switch( nPos )
1262
0
        {
1263
0
        case 1: nIterateType = TextAnimationType::BY_WORD; break;
1264
0
        case 2: nIterateType = TextAnimationType::BY_LETTER; break;
1265
0
        default:
1266
0
            nIterateType = TextAnimationType::BY_PARAGRAPH;
1267
0
        }
1268
1269
0
        sal_Int16 nOldIterateType = nIterateType-1;
1270
1271
0
        if(mpSet->getPropertyState( nHandleIterateType ) != STLPropertyState::Ambiguous)
1272
0
            mpSet->getPropertyValue( nHandleIterateType ) >>= nOldIterateType;
1273
1274
0
        if( nIterateType != nOldIterateType )
1275
0
            pSet->setPropertyValue( nHandleIterateType, Any( nIterateType ) );
1276
0
    }
1277
1278
0
    {
1279
0
        double fIterateInterval = static_cast<double>(mxMFTextDelay->get_value(FieldUnit::NONE)) / 10;
1280
0
        double fOldIterateInterval = -1.0;
1281
1282
0
        if( mpSet->getPropertyState( nHandleIterateInterval ) != STLPropertyState::Ambiguous )
1283
0
            mpSet->getPropertyValue( nHandleIterateInterval ) >>= fOldIterateInterval;
1284
1285
0
        if( fIterateInterval != fOldIterateInterval )
1286
0
            pSet->setPropertyValue( nHandleIterateInterval, Any( fIterateInterval ) );
1287
0
    }
1288
1289
0
    nPos = mxLBSound->get_active();
1290
0
    if (nPos == -1)
1291
0
        return;
1292
1293
0
    Any aNewSoundURL, aOldSoundURL( Any( sal_Int32(0) ) );
1294
1295
0
    if( nPos == 0 )
1296
0
    {
1297
        // 0 means no sound, so leave any empty
1298
0
    }
1299
0
    else if( nPos == 1 )
1300
0
    {
1301
        // this means stop sound
1302
0
        aNewSoundURL <<= true;
1303
0
    }
1304
0
    else
1305
0
    {
1306
0
        OUString aSoundURL( maSoundList[ nPos-2 ] );
1307
0
        aNewSoundURL <<= aSoundURL;
1308
0
    }
1309
1310
0
    if( mpSet->getPropertyState( nHandleSoundURL ) != STLPropertyState::Ambiguous )
1311
0
        aOldSoundURL = mpSet->getPropertyValue( nHandleSoundURL  );
1312
1313
0
    if( aNewSoundURL != aOldSoundURL )
1314
0
        pSet->setPropertyValue( nHandleSoundURL, aNewSoundURL );
1315
0
}
1316
1317
void CustomAnimationEffectTabPage::fillSoundListBox()
1318
0
{
1319
0
    GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, maSoundList );
1320
0
    GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, maSoundList );
1321
1322
0
    mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_NO_SOUND) );
1323
0
    mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_STOP_PREVIOUS_SOUND) );
1324
0
    for(const OUString & rString : maSoundList)
1325
0
    {
1326
0
        INetURLObject aURL( rString );
1327
0
        mxLBSound->append_text( aURL.GetBase() );
1328
0
    }
1329
0
    mxLBSound->append_text( SdResId(STR_CUSTOMANIMATION_BROWSE_SOUND) );
1330
0
}
1331
1332
void CustomAnimationEffectTabPage::clearSoundListBox()
1333
0
{
1334
0
    maSoundList.clear();
1335
0
    mxLBSound->clear();
1336
0
}
1337
1338
sal_Int32 CustomAnimationEffectTabPage::getSoundObject( std::u16string_view rStr )
1339
0
{
1340
0
    size_t i;
1341
0
    const size_t nCount = maSoundList.size();
1342
0
    for( i = 0; i < nCount; i++ )
1343
0
    {
1344
0
        if( maSoundList[ i ].equalsIgnoreAsciiCase(rStr) )
1345
0
            return i+2;
1346
0
    }
1347
1348
0
    return -1;
1349
0
}
1350
1351
void CustomAnimationEffectTabPage::openSoundFileDialog()
1352
0
{
1353
0
    SdOpenSoundFileDialog aFileDialog(GetFrameWeld());
1354
1355
0
    bool bValidSoundFile = false;
1356
0
    bool bQuitLoop = false;
1357
0
    ::tools::Long nPos = 0;
1358
1359
0
    while( !bQuitLoop && (aFileDialog.Execute() == ERRCODE_NONE) )
1360
0
    {
1361
0
        OUString aFile = aFileDialog.GetPath();
1362
0
        nPos = getSoundObject( aFile );
1363
1364
0
        if( nPos < 0 ) // not in Soundliste
1365
0
        {
1366
            // try to insert in Gallery
1367
0
            if( GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aFile ) )
1368
0
            {
1369
0
                clearSoundListBox();
1370
0
                fillSoundListBox();
1371
1372
0
                nPos = getSoundObject( aFile );
1373
0
                DBG_ASSERT( nPos >= 0, "sd::CustomAnimationEffectTabPage::openSoundFileDialog(), Recently inserted sound not in list!" );
1374
1375
0
                bValidSoundFile=true;
1376
0
                bQuitLoop=true;
1377
0
            }
1378
0
            else
1379
0
            {
1380
0
                OUString aStrWarning(SdResId(STR_WARNING_NOSOUNDFILE));
1381
0
                aStrWarning = aStrWarning.replaceFirst("%", aFile);
1382
0
                std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(nullptr,
1383
0
                                                           VclMessageType::Warning, VclButtonsType::NONE,
1384
0
                                                           aStrWarning));
1385
0
                xWarn->add_button(GetStandardText(StandardButtonType::Retry), RET_RETRY);
1386
0
                xWarn->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
1387
0
                bQuitLoop = xWarn->run() != RET_RETRY;
1388
1389
0
                bValidSoundFile=false;
1390
0
            }
1391
0
        }
1392
0
        else
1393
0
        {
1394
0
            bValidSoundFile=true;
1395
0
            bQuitLoop=true;
1396
0
        }
1397
0
    }
1398
1399
0
    if( !bValidSoundFile )
1400
0
        nPos = 0;
1401
1402
0
    mxLBSound->set_active(nPos);
1403
0
}
1404
1405
void CustomAnimationEffectTabPage::onSoundPreview()
1406
0
{
1407
0
#if HAVE_FEATURE_AVMEDIA
1408
0
    const auto nPos = mxLBSound->get_active();
1409
1410
0
    if( nPos >= 2 ) try
1411
0
    {
1412
0
        const OUString aSoundURL( maSoundList[ nPos-2 ] );
1413
1414
        // Preview the effect's own source only once it is allowed; a gallery or
1415
        // browsed sound has a different URL and is left alone.
1416
0
        if( mpSet->getPropertyState( nHandleSoundURL ) != STLPropertyState::Ambiguous )
1417
0
        {
1418
0
            OUString aEffectSoundURL;
1419
0
            mpSet->getPropertyValue( nHandleSoundURL ) >>= aEffectSoundURL;
1420
0
            bool bAllowed = true;
1421
0
            if( mpSet->getPropertyState( nHandleSoundAllowed ) != STLPropertyState::Ambiguous )
1422
0
                mpSet->getPropertyValue( nHandleSoundAllowed ) >>= bAllowed;
1423
0
            if( aSoundURL == aEffectSoundURL && !bAllowed )
1424
0
                return;
1425
0
        }
1426
1427
0
        mxPlayer.set( avmedia::MediaWindow::createPlayer( aSoundURL, u""_ustr ), uno::UNO_SET_THROW );
1428
0
        mxPlayer->start();
1429
0
    }
1430
0
    catch( uno::Exception& )
1431
0
    {
1432
0
        TOOLS_WARN_EXCEPTION( "sd", "CustomAnimationEffectTabPage::onSoundPreview()" );
1433
0
    }
1434
0
#endif
1435
0
}
1436
1437
class CustomAnimationDurationTabPage
1438
{
1439
public:
1440
    CustomAnimationDurationTabPage(weld::Container* pParent, const STLPropertySet* pSet);
1441
1442
    void update( STLPropertySet* pSet );
1443
1444
    DECL_LINK(implControlHdl, weld::ComboBox&, void);
1445
    DECL_LINK(DurationModifiedHdl, weld::MetricSpinButton&, void);
1446
1447
private:
1448
    const STLPropertySet* mpSet;
1449
1450
    std::unique_ptr<weld::Builder> mxBuilder;
1451
    std::unique_ptr<weld::Container> mxContainer;
1452
    std::unique_ptr<weld::ComboBox> mxLBStart;
1453
    std::unique_ptr<weld::MetricSpinButton> mxMFStartDelay;
1454
    std::unique_ptr<weld::Label> mxFTDuration;
1455
    std::unique_ptr<weld::MetricSpinButton> mxCBXDuration;
1456
    std::unique_ptr<weld::Label> mxFTRepeat;
1457
    std::unique_ptr<weld::ComboBox> mxCBRepeat;
1458
    std::unique_ptr<weld::CheckButton> mxCBXRewind;
1459
    std::unique_ptr<weld::RadioButton> mxRBClickSequence;
1460
    std::unique_ptr<weld::RadioButton> mxRBInteractive;
1461
    std::unique_ptr<weld::ComboBox> mxLBTrigger;
1462
};
1463
1464
CustomAnimationDurationTabPage::CustomAnimationDurationTabPage(weld::Container* pParent, const STLPropertySet* pSet)
1465
0
    : mpSet(pSet)
1466
0
    , mxBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/customanimationtimingtab.ui"_ustr))
1467
0
    , mxContainer(mxBuilder->weld_container(u"TimingTab"_ustr))
1468
0
    , mxLBStart(mxBuilder->weld_combo_box(u"start_list"_ustr))
1469
0
    , mxMFStartDelay(mxBuilder->weld_metric_spin_button(u"delay_value"_ustr, FieldUnit::SECOND))
1470
0
    , mxFTDuration(mxBuilder->weld_label(u"duration_label"_ustr))
1471
0
    , mxCBXDuration(mxBuilder->weld_metric_spin_button(u"anim_duration"_ustr, FieldUnit::SECOND))
1472
0
    , mxFTRepeat(mxBuilder->weld_label(u"repeat_label"_ustr))
1473
0
    , mxCBRepeat(mxBuilder->weld_combo_box(u"repeat_list"_ustr))
1474
0
    , mxCBXRewind(mxBuilder->weld_check_button(u"rewind"_ustr))
1475
0
    , mxRBClickSequence(mxBuilder->weld_radio_button(u"rb_click_sequence"_ustr))
1476
0
    , mxRBInteractive(mxBuilder->weld_radio_button(u"rb_interactive"_ustr))
1477
0
    , mxLBTrigger(mxBuilder->weld_combo_box(u"trigger_list"_ustr))
1478
0
{
1479
0
    mxLBTrigger->set_size_request(mxLBTrigger->get_approximate_digit_width() * 20, -1);
1480
1481
0
    fillRepeatComboBox(*mxCBRepeat);
1482
1483
0
    mxLBTrigger->connect_changed(LINK(this, CustomAnimationDurationTabPage, implControlHdl));
1484
0
    mxCBXDuration->connect_value_changed(LINK( this, CustomAnimationDurationTabPage, DurationModifiedHdl));
1485
1486
0
    if( pSet->getPropertyState( nHandleStart ) != STLPropertyState::Ambiguous )
1487
0
    {
1488
0
        sal_Int16 nStart = 0;
1489
0
        pSet->getPropertyValue( nHandleStart ) >>= nStart;
1490
0
        sal_Int32 nPos = 0;
1491
0
        switch( nStart )
1492
0
        {
1493
0
            case EffectNodeType::WITH_PREVIOUS:     nPos = 1; break;
1494
0
            case EffectNodeType::AFTER_PREVIOUS:    nPos = 2; break;
1495
0
        }
1496
0
        mxLBStart->set_active(nPos);
1497
0
    }
1498
1499
0
    if( pSet->getPropertyState( nHandleBegin ) != STLPropertyState::Ambiguous )
1500
0
    {
1501
0
        double fBegin = 0.0;
1502
0
        pSet->getPropertyValue( nHandleBegin ) >>= fBegin;
1503
0
        mxMFStartDelay->set_value(static_cast<::tools::Long>(fBegin*10), FieldUnit::NONE);
1504
0
    }
1505
1506
0
    if( pSet->getPropertyState( nHandleDuration ) != STLPropertyState::Ambiguous )
1507
0
    {
1508
0
        double fDuration = 0.0;
1509
0
        pSet->getPropertyValue( nHandleDuration ) >>= fDuration;
1510
1511
0
        if( fDuration == 0.001 )
1512
0
        {
1513
0
            mxFTDuration->set_sensitive(false);
1514
0
            mxCBXDuration->set_sensitive(false);
1515
0
            mxFTRepeat->set_sensitive(false);
1516
0
            mxCBRepeat->set_sensitive(false);
1517
0
            mxCBXRewind->set_sensitive(false);
1518
0
        }
1519
0
        else
1520
0
        {
1521
0
            mxCBXDuration->set_value(fDuration * 100.0, FieldUnit::NONE);
1522
0
        }
1523
0
    }
1524
1525
0
    if( pSet->getPropertyState( nHandleRepeat ) != STLPropertyState::Ambiguous )
1526
0
    {
1527
0
        Any aRepeatCount( pSet->getPropertyValue( nHandleRepeat ) );
1528
0
        if( (aRepeatCount.getValueType() == ::cppu::UnoType<double>::get()) || !aRepeatCount.hasValue() )
1529
0
        {
1530
0
            double fRepeat = 0.0;
1531
0
            if( aRepeatCount.hasValue() )
1532
0
                aRepeatCount >>= fRepeat;
1533
1534
0
            auto nPos = -1;
1535
1536
0
            if( fRepeat == 0 )
1537
0
                nPos = 0;
1538
0
            else if( fRepeat == 2.0 )
1539
0
                nPos = 1;
1540
0
            else if( fRepeat == 3.0 )
1541
0
                nPos = 2;
1542
0
            else if( fRepeat == 4.0 )
1543
0
                nPos = 3;
1544
0
            else if( fRepeat == 5.0 )
1545
0
                nPos = 4;
1546
0
            else if( fRepeat == 10.0 )
1547
0
                nPos = 5;
1548
1549
0
            if (nPos != -1)
1550
0
                mxCBRepeat->set_active(nPos);
1551
0
            else
1552
0
                mxCBRepeat->set_entry_text(OUString::number(fRepeat));
1553
0
        }
1554
0
        else if( aRepeatCount.getValueType() == ::cppu::UnoType<Timing>::get() )
1555
0
        {
1556
0
            Any aEnd;
1557
0
            if( pSet->getPropertyState( nHandleEnd ) != STLPropertyState::Ambiguous )
1558
0
                aEnd = pSet->getPropertyValue( nHandleEnd );
1559
1560
0
            mxCBRepeat->set_active(aEnd.hasValue() ? 6 : 7);
1561
0
        }
1562
0
    }
1563
1564
0
    if( pSet->getPropertyState( nHandleRewind ) != STLPropertyState::Ambiguous )
1565
0
    {
1566
0
        sal_Int16 nFill = 0;
1567
0
        if( pSet->getPropertyValue( nHandleRewind ) >>= nFill )
1568
0
        {
1569
0
            mxCBXRewind->set_active(nFill == AnimationFill::REMOVE);
1570
0
        }
1571
0
        else
1572
0
        {
1573
0
            mxCBXRewind->set_state(TRISTATE_INDET);
1574
0
        }
1575
0
    }
1576
1577
0
    Reference< XShape > xTrigger;
1578
1579
0
    if( pSet->getPropertyState( nHandleTrigger ) != STLPropertyState::Ambiguous )
1580
0
    {
1581
0
        pSet->getPropertyValue( nHandleTrigger ) >>= xTrigger;
1582
1583
0
        mxRBInteractive->set_active(xTrigger.is());
1584
0
        mxRBClickSequence->set_active(!xTrigger.is());
1585
0
    }
1586
1587
0
    Reference< XDrawPage > xCurrentPage;
1588
0
    pSet->getPropertyValue( nHandleCurrentPage ) >>= xCurrentPage;
1589
0
    if( !xCurrentPage.is() )
1590
0
        return;
1591
1592
0
    static constexpr OUString aStrIsEmptyPresObj( u"IsEmptyPresentationObject"_ustr );
1593
1594
0
    sal_Int32 nShape, nCount = xCurrentPage->getCount();
1595
0
    for( nShape = 0; nShape < nCount; nShape++ )
1596
0
    {
1597
0
        Reference< XShape > xShape( xCurrentPage->getByIndex( nShape ), UNO_QUERY );
1598
1599
0
        if( !xShape.is() )
1600
0
            continue;
1601
1602
0
        Reference< XPropertySet > xSet( xShape, UNO_QUERY );
1603
0
        if( xSet.is() && xSet->getPropertySetInfo()->hasPropertyByName( aStrIsEmptyPresObj ) )
1604
0
        {
1605
0
            bool bIsEmpty = false;
1606
0
            xSet->getPropertyValue( aStrIsEmptyPresObj ) >>= bIsEmpty;
1607
0
            if( bIsEmpty )
1608
0
                continue;
1609
0
        }
1610
1611
0
        OUString aDescription( getShapeDescription( xShape, true ) );
1612
0
        mxLBTrigger->append(OUString::number(nShape), aDescription);
1613
0
        auto nPos = mxLBTrigger->get_count() - 1;
1614
0
        if (xShape == xTrigger)
1615
0
            mxLBTrigger->set_active(nPos);
1616
0
    }
1617
0
}
1618
1619
IMPL_LINK_NOARG(CustomAnimationDurationTabPage, implControlHdl, weld::ComboBox&, void)
1620
0
{
1621
0
    mxRBInteractive->set_active(true);
1622
0
    assert(!mxRBClickSequence->get_active());
1623
0
}
1624
1625
IMPL_LINK_NOARG(CustomAnimationDurationTabPage, DurationModifiedHdl, weld::MetricSpinButton&, void)
1626
0
{
1627
0
    if (!mxCBXDuration->get_text().isEmpty())
1628
0
    {
1629
0
        double duration_value = static_cast<double>(mxCBXDuration->get_value(FieldUnit::NONE));
1630
0
        if(duration_value <= 0.0)
1631
0
            mxCBXDuration->set_value(1, FieldUnit::NONE);
1632
0
        else
1633
0
            mxCBXDuration->set_value(duration_value, FieldUnit::NONE);
1634
0
    }
1635
0
}
1636
1637
void CustomAnimationDurationTabPage::update( STLPropertySet* pSet )
1638
0
{
1639
0
    auto nPos = mxLBStart->get_active();
1640
0
    if (nPos != -1)
1641
0
    {
1642
0
        sal_Int16 nStart;
1643
0
        sal_Int16 nOldStart = -1;
1644
1645
0
        switch( nPos )
1646
0
        {
1647
0
        case 1: nStart = EffectNodeType::WITH_PREVIOUS; break;
1648
0
        case 2: nStart = EffectNodeType::AFTER_PREVIOUS; break;
1649
0
        default:
1650
0
            nStart = EffectNodeType::ON_CLICK; break;
1651
0
        }
1652
1653
0
        if(mpSet->getPropertyState( nHandleStart ) != STLPropertyState::Ambiguous)
1654
0
            mpSet->getPropertyValue( nHandleStart ) >>= nOldStart;
1655
1656
0
        if( nStart != nOldStart )
1657
0
            pSet->setPropertyValue( nHandleStart, Any( nStart ) );
1658
0
    }
1659
1660
0
    {
1661
0
        double fBegin = static_cast<double>(mxMFStartDelay->get_value(FieldUnit::NONE)) / 10.0;
1662
0
        double fOldBegin = -1.0;
1663
1664
0
        if( mpSet->getPropertyState( nHandleBegin ) != STLPropertyState::Ambiguous )
1665
0
            mpSet->getPropertyValue( nHandleBegin ) >>= fOldBegin;
1666
1667
0
        if( fBegin != fOldBegin )
1668
0
            pSet->setPropertyValue( nHandleBegin, Any( fBegin ) );
1669
0
    }
1670
1671
0
    nPos = mxCBRepeat->get_active();
1672
0
    if (nPos != -1 || !mxCBRepeat->get_active_text().isEmpty())
1673
0
    {
1674
0
        Any aRepeatCount;
1675
0
        Any aEnd;
1676
1677
0
        switch( nPos )
1678
0
        {
1679
0
        case 0:
1680
0
            break;
1681
1682
0
        case 6:
1683
0
            {
1684
0
                Event aEvent;
1685
0
                aEvent.Trigger = EventTrigger::ON_NEXT;
1686
0
                aEvent.Repeat = 0;
1687
0
                aEnd <<= aEvent;
1688
0
            }
1689
0
            [[fallthrough]];
1690
0
        case 7:
1691
0
            aRepeatCount <<= Timing_INDEFINITE;
1692
0
            break;
1693
0
        default:
1694
0
            {
1695
0
                OUString aText(mxCBRepeat->get_text(nPos));
1696
0
                if( !aText.isEmpty() )
1697
0
                    aRepeatCount <<= aText.toDouble();
1698
0
            }
1699
0
        }
1700
1701
0
        Any aOldRepeatCount( aRepeatCount );
1702
0
        if( mpSet->getPropertyState( nHandleRepeat ) != STLPropertyState::Ambiguous )
1703
0
            aOldRepeatCount = mpSet->getPropertyValue( nHandleRepeat );
1704
1705
0
        if( aRepeatCount != aOldRepeatCount )
1706
0
            pSet->setPropertyValue( nHandleRepeat, aRepeatCount );
1707
1708
0
        Any aOldEnd( aEnd );
1709
0
        if( mpSet->getPropertyState( nHandleEnd ) != STLPropertyState::Ambiguous )
1710
0
            aOldEnd = mpSet->getPropertyValue( nHandleEnd );
1711
1712
0
        if( aEnd != aOldEnd )
1713
0
            pSet->setPropertyValue( nHandleEnd, aEnd );
1714
0
    }
1715
1716
0
    double fDuration = -1.0;
1717
1718
0
    if (!mxCBXDuration->get_text().isEmpty())
1719
0
    {
1720
0
        double duration_value = static_cast<double>(mxCBXDuration->get_value(FieldUnit::NONE));
1721
1722
0
        if(duration_value > 0)
1723
0
            fDuration = duration_value/100.0;
1724
0
    }
1725
1726
0
    if( fDuration != -1.0 )
1727
0
    {
1728
0
        double fOldDuration = -1;
1729
1730
0
        if( mpSet->getPropertyState( nHandleDuration ) != STLPropertyState::Ambiguous )
1731
0
            mpSet->getPropertyValue( nHandleDuration ) >>= fOldDuration;
1732
1733
0
        if( fDuration != fOldDuration )
1734
0
            pSet->setPropertyValue( nHandleDuration, Any( fDuration ) );
1735
0
    }
1736
1737
0
    if (mxCBXRewind->get_state() != TRISTATE_INDET)
1738
0
    {
1739
0
        sal_Int16 nFill = mxCBXRewind->get_active() ? AnimationFill::REMOVE : AnimationFill::HOLD;
1740
1741
0
        bool bSet = true;
1742
1743
0
        if( mpSet->getPropertyState( nHandleRewind ) != STLPropertyState::Ambiguous )
1744
0
        {
1745
0
            sal_Int16 nOldFill = 0;
1746
0
            mpSet->getPropertyValue( nHandleRewind ) >>= nOldFill;
1747
0
            bSet = nFill != nOldFill;
1748
0
        }
1749
1750
0
        if( bSet )
1751
0
            pSet->setPropertyValue( nHandleRewind, Any( nFill ) );
1752
0
    }
1753
1754
0
    Reference< XShape > xTrigger;
1755
1756
0
    if (mxRBInteractive->get_active())
1757
0
    {
1758
0
        nPos = mxLBTrigger->get_active();
1759
0
        if (nPos != -1)
1760
0
        {
1761
0
            sal_Int32 nShape = mxLBTrigger->get_id(nPos).toInt32();
1762
1763
0
            Reference< XDrawPage > xCurrentPage;
1764
0
            mpSet->getPropertyValue( nHandleCurrentPage ) >>= xCurrentPage;
1765
1766
0
            if( xCurrentPage.is() && (nShape >= 0) && (nShape < xCurrentPage->getCount()) )
1767
0
                xCurrentPage->getByIndex( nShape ) >>= xTrigger;
1768
0
        }
1769
0
    }
1770
1771
0
    if (xTrigger.is() || mxRBClickSequence->get_active())
1772
0
    {
1773
0
        Any aNewValue( xTrigger );
1774
0
        Any aOldValue;
1775
1776
0
        if( mpSet->getPropertyState( nHandleTrigger ) != STLPropertyState::Ambiguous )
1777
0
            aOldValue = mpSet->getPropertyValue( nHandleTrigger );
1778
1779
0
        if( aNewValue != aOldValue )
1780
0
            pSet->setPropertyValue( nHandleTrigger, aNewValue );
1781
0
    }
1782
0
}
1783
1784
class CustomAnimationTextAnimTabPage
1785
{
1786
public:
1787
    CustomAnimationTextAnimTabPage(weld::Container* pParent, const STLPropertySet* pSet);
1788
1789
    void update( STLPropertySet* pSet );
1790
1791
    void updateControlStates();
1792
    DECL_LINK(implSelectHdl, weld::ComboBox&, void);
1793
1794
private:
1795
    const STLPropertySet* mpSet;
1796
    bool mbHasVisibleShapes;
1797
1798
    std::unique_ptr<weld::Builder> mxBuilder;
1799
    std::unique_ptr<weld::Container> mxContainer;
1800
    std::unique_ptr<weld::ComboBox> mxLBGroupText;
1801
    std::unique_ptr<weld::CheckButton> mxCBXGroupAuto;
1802
    std::unique_ptr<weld::MetricSpinButton> mxMFGroupAuto;
1803
    std::unique_ptr<weld::CheckButton> mxCBXAnimateForm;
1804
    std::unique_ptr<weld::CheckButton> mxCBXReverse;
1805
};
1806
1807
CustomAnimationTextAnimTabPage::CustomAnimationTextAnimTabPage(weld::Container* pParent, const STLPropertySet* pSet)
1808
0
    : mpSet(pSet)
1809
0
    , mbHasVisibleShapes(true)
1810
0
    , mxBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/customanimationtexttab.ui"_ustr))
1811
0
    , mxContainer(mxBuilder->weld_container(u"TextAnimationTab"_ustr))
1812
0
    , mxLBGroupText(mxBuilder->weld_combo_box(u"group_text_list"_ustr))
1813
0
    , mxCBXGroupAuto(mxBuilder->weld_check_button(u"auto_after"_ustr))
1814
0
    , mxMFGroupAuto(mxBuilder->weld_metric_spin_button(u"auto_after_value"_ustr,FieldUnit::SECOND))
1815
0
    , mxCBXAnimateForm(mxBuilder->weld_check_button(u"animate_shape"_ustr))
1816
0
    , mxCBXReverse(mxBuilder->weld_check_button(u"reverse_order"_ustr))
1817
0
{
1818
0
    mxLBGroupText->connect_changed(LINK(this, CustomAnimationTextAnimTabPage, implSelectHdl));
1819
1820
0
    if( pSet->getPropertyState( nHandleTextGrouping ) != STLPropertyState::Ambiguous )
1821
0
    {
1822
0
        sal_Int32 nTextGrouping = 0;
1823
0
        if( pSet->getPropertyValue( nHandleTextGrouping ) >>= nTextGrouping )
1824
0
            mxLBGroupText->set_active(nTextGrouping + 1);
1825
0
    }
1826
1827
0
    if( pSet->getPropertyState( nHandleHasVisibleShape ) != STLPropertyState::Ambiguous )
1828
0
        pSet->getPropertyValue( nHandleHasVisibleShape ) >>= mbHasVisibleShapes;
1829
1830
0
    if( pSet->getPropertyState( nHandleTextGroupingAuto ) != STLPropertyState::Ambiguous )
1831
0
    {
1832
0
        double fTextGroupingAuto = 0.0;
1833
0
        if( pSet->getPropertyValue( nHandleTextGroupingAuto ) >>= fTextGroupingAuto )
1834
0
        {
1835
0
            mxCBXGroupAuto->set_active(fTextGroupingAuto >= 0.0);
1836
0
            if( fTextGroupingAuto >= 0.0 )
1837
0
                mxMFGroupAuto->set_value(static_cast<::tools::Long>(fTextGroupingAuto*10), FieldUnit::NONE);
1838
0
        }
1839
0
    }
1840
0
    else
1841
0
    {
1842
0
        mxCBXGroupAuto->set_state( TRISTATE_INDET );
1843
0
    }
1844
1845
0
    mxCBXAnimateForm->set_state( TRISTATE_INDET );
1846
0
    if( pSet->getPropertyState( nHandleAnimateForm ) != STLPropertyState::Ambiguous )
1847
0
    {
1848
0
        bool bAnimateForm = false;
1849
0
        if( pSet->getPropertyValue( nHandleAnimateForm ) >>= bAnimateForm )
1850
0
        {
1851
0
            mxCBXAnimateForm->set_active( bAnimateForm );
1852
0
        }
1853
0
    }
1854
0
    else
1855
0
    {
1856
0
        mxCBXAnimateForm->set_sensitive(false);
1857
0
    }
1858
1859
0
    mxCBXReverse->set_state(TRISTATE_INDET);
1860
0
    if( pSet->getPropertyState( nHandleTextReverse ) != STLPropertyState::Ambiguous )
1861
0
    {
1862
0
        bool bTextReverse = false;
1863
0
        if( pSet->getPropertyValue( nHandleTextReverse ) >>= bTextReverse )
1864
0
        {
1865
0
            mxCBXReverse->set_active( bTextReverse );
1866
0
        }
1867
0
    }
1868
1869
0
    if( pSet->getPropertyState( nHandleMaxParaDepth ) == STLPropertyState::Direct )
1870
0
    {
1871
0
        sal_Int32 nMaxParaDepth = 0;
1872
0
        pSet->getPropertyValue( nHandleMaxParaDepth ) >>= nMaxParaDepth;
1873
0
        nMaxParaDepth += 1;
1874
1875
0
        sal_Int32 nPos = 6;
1876
0
        while( (nPos > 2) && (nPos > nMaxParaDepth) )
1877
0
        {
1878
0
            mxLBGroupText->remove(nPos);
1879
0
            nPos--;
1880
0
        }
1881
0
    }
1882
1883
0
    updateControlStates();
1884
0
}
1885
1886
void CustomAnimationTextAnimTabPage::update( STLPropertySet* pSet )
1887
0
{
1888
0
    auto nPos = mxLBGroupText->get_active();
1889
0
    if (nPos != -1)
1890
0
    {
1891
0
        sal_Int32 nTextGrouping = nPos - 1;
1892
0
        sal_Int32 nOldGrouping = -2;
1893
1894
0
        if(mpSet->getPropertyState( nHandleTextGrouping ) != STLPropertyState::Ambiguous)
1895
0
            mpSet->getPropertyValue( nHandleTextGrouping ) >>= nOldGrouping;
1896
1897
0
        if( nTextGrouping != nOldGrouping )
1898
0
            pSet->setPropertyValue( nHandleTextGrouping, Any( nTextGrouping ) );
1899
0
    }
1900
1901
0
    if (nPos != 0)
1902
0
    {
1903
0
        bool bTextReverse = mxCBXReverse->get_active();
1904
0
        bool bOldTextReverse = !bTextReverse;
1905
1906
0
        if(mpSet->getPropertyState( nHandleTextReverse ) != STLPropertyState::Ambiguous)
1907
0
            mpSet->getPropertyValue( nHandleTextReverse ) >>= bOldTextReverse;
1908
1909
0
        if( bTextReverse != bOldTextReverse )
1910
0
            pSet->setPropertyValue( nHandleTextReverse, Any( bTextReverse ) );
1911
1912
0
        if( nPos > 1 )
1913
0
        {
1914
0
            double fTextGroupingAuto = mxCBXGroupAuto->get_active() ? mxMFGroupAuto->get_value(FieldUnit::NONE) / 10.0 : -1.0;
1915
0
            double fOldTextGroupingAuto = -2.0;
1916
1917
0
            if(mpSet->getPropertyState( nHandleTextGroupingAuto ) != STLPropertyState::Ambiguous)
1918
0
                mpSet->getPropertyValue( nHandleTextGroupingAuto ) >>= fOldTextGroupingAuto;
1919
1920
0
            if( fTextGroupingAuto != fOldTextGroupingAuto )
1921
0
                pSet->setPropertyValue( nHandleTextGroupingAuto, Any( fTextGroupingAuto ) );
1922
0
        }
1923
0
    }
1924
    //#i120049# impress crashes when modifying the "Random effects" animation
1925
    //effect's trigger condition to "Start effect on click of".
1926
    //If this control is disabled, we should ignore its value
1927
0
    if (mxCBXAnimateForm->get_sensitive())
1928
0
    {
1929
0
        bool bAnimateForm = mxCBXAnimateForm->get_active();
1930
0
        bool bOldAnimateForm = !bAnimateForm;
1931
1932
0
        if(mpSet->getPropertyState( nHandleAnimateForm ) != STLPropertyState::Ambiguous)
1933
0
            mpSet->getPropertyValue( nHandleAnimateForm ) >>= bOldAnimateForm;
1934
1935
0
        if( bAnimateForm != bOldAnimateForm )
1936
0
            pSet->setPropertyValue( nHandleAnimateForm, Any( bAnimateForm ) );
1937
0
    }
1938
0
}
1939
1940
void CustomAnimationTextAnimTabPage::updateControlStates()
1941
0
{
1942
0
    auto nPos = mxLBGroupText->get_active();
1943
1944
0
    mxCBXGroupAuto->set_sensitive( nPos > 1 );
1945
0
    mxMFGroupAuto->set_sensitive( nPos > 1 );
1946
0
    mxCBXReverse->set_sensitive( nPos > 0 );
1947
1948
0
    if( !mbHasVisibleShapes && nPos > 0 )
1949
0
    {
1950
0
        mxCBXAnimateForm->set_active(false);
1951
0
        mxCBXAnimateForm->set_sensitive(false);
1952
0
    }
1953
0
    else
1954
0
    {
1955
0
        mxCBXAnimateForm->set_sensitive(true);
1956
0
    }
1957
0
}
1958
1959
IMPL_LINK_NOARG(CustomAnimationTextAnimTabPage, implSelectHdl, weld::ComboBox&, void)
1960
0
{
1961
0
    updateControlStates();
1962
0
}
1963
1964
CustomAnimationDialog::CustomAnimationDialog(weld::Window* pParent, std::unique_ptr<STLPropertySet> pSet, const OUString& rPage)
1965
0
    : GenericDialogController(pParent, u"modules/simpress/ui/customanimationproperties.ui"_ustr, u"CustomAnimationProperties"_ustr)
1966
0
    , mxSet(std::move(pSet))
1967
0
    , mxTabControl(m_xBuilder->weld_notebook(u"tabcontrol"_ustr))
1968
0
    , mxDurationTabPage(new CustomAnimationDurationTabPage(mxTabControl->get_page(u"timing"_ustr), mxSet.get()))
1969
0
    , mxEffectTabPage(new CustomAnimationEffectTabPage(mxTabControl->get_page(u"effect"_ustr), m_xDialog.get(), mxSet.get()))
1970
0
{
1971
0
    bool bHasText = false;
1972
0
    if( mxSet->getPropertyState( nHandleHasText ) != STLPropertyState::Ambiguous )
1973
0
        mxSet->getPropertyValue( nHandleHasText ) >>= bHasText;
1974
1975
0
    if( bHasText )
1976
0
    {
1977
0
        mxTextAnimTabPage.reset(new CustomAnimationTextAnimTabPage(mxTabControl->get_page(u"textanim"_ustr), mxSet.get()));
1978
0
    }
1979
0
    else
1980
0
    {
1981
0
        mxTabControl->remove_page(u"textanim"_ustr);
1982
0
    }
1983
1984
0
    if (!rPage.isEmpty())
1985
0
        mxTabControl->set_current_page(rPage);
1986
0
}
1987
1988
CustomAnimationDialog::~CustomAnimationDialog()
1989
0
{
1990
0
}
1991
1992
STLPropertySet* CustomAnimationDialog::getResultSet()
1993
0
{
1994
0
    mxResultSet = createDefaultSet();
1995
1996
0
    mxEffectTabPage->update( mxResultSet.get() );
1997
0
    mxDurationTabPage->update( mxResultSet.get() );
1998
0
    if (mxTextAnimTabPage)
1999
0
        mxTextAnimTabPage->update( mxResultSet.get() );
2000
2001
0
    return mxResultSet.get();
2002
0
}
2003
2004
std::unique_ptr<STLPropertySet> CustomAnimationDialog::createDefaultSet()
2005
0
{
2006
0
    Any aEmpty;
2007
2008
0
    std::unique_ptr<STLPropertySet> pSet(new STLPropertySet());
2009
0
    pSet->setPropertyDefaultValue( nHandleMaxParaDepth, Any( sal_Int32(-1) ) );
2010
2011
0
    pSet->setPropertyDefaultValue( nHandleHasAfterEffect, Any( false ) );
2012
0
    pSet->setPropertyDefaultValue( nHandleAfterEffectOnNextEffect, Any( false ) );
2013
0
    pSet->setPropertyDefaultValue( nHandleDimColor, aEmpty );
2014
0
    pSet->setPropertyDefaultValue( nHandleIterateType, Any( sal_Int16(0) ) );
2015
0
    pSet->setPropertyDefaultValue( nHandleIterateInterval, Any( 0.0 ) );
2016
2017
0
    pSet->setPropertyDefaultValue( nHandleStart, Any( sal_Int16(EffectNodeType::ON_CLICK) ) );
2018
0
    pSet->setPropertyDefaultValue( nHandleBegin, Any( 0.0 ) );
2019
0
    pSet->setPropertyDefaultValue( nHandleDuration, Any( 2.0 ) );
2020
0
    pSet->setPropertyDefaultValue( nHandleRepeat, aEmpty );
2021
0
    pSet->setPropertyDefaultValue( nHandleRewind, Any( AnimationFill::HOLD ) );
2022
2023
0
    pSet->setPropertyDefaultValue( nHandleEnd, aEmpty );
2024
2025
0
    pSet->setPropertyDefaultValue( nHandlePresetId, aEmpty );
2026
0
    pSet->setPropertyDefaultValue( nHandleProperty1Type, Any( nPropertyTypeNone ) );
2027
0
    pSet->setPropertyDefaultValue( nHandleProperty1Value, aEmpty );
2028
0
    pSet->setPropertyDefaultValue( nHandleProperty2Type, Any( nPropertyTypeNone ) );
2029
0
    pSet->setPropertyDefaultValue( nHandleProperty2Value, aEmpty );
2030
0
    pSet->setPropertyDefaultValue( nHandleAccelerate, aEmpty );
2031
0
    pSet->setPropertyDefaultValue( nHandleDecelerate, aEmpty );
2032
0
    pSet->setPropertyDefaultValue( nHandleAutoReverse, aEmpty );
2033
0
    pSet->setPropertyDefaultValue( nHandleTrigger, aEmpty );
2034
2035
0
    pSet->setPropertyDefaultValue( nHandleHasText, Any( false ) );
2036
0
    pSet->setPropertyDefaultValue( nHandleHasVisibleShape, Any( false ) );
2037
0
    pSet->setPropertyDefaultValue( nHandleTextGrouping, Any( sal_Int32(-1) ) );
2038
0
    pSet->setPropertyDefaultValue( nHandleAnimateForm, Any( true ) );
2039
0
    pSet->setPropertyDefaultValue( nHandleTextGroupingAuto, Any( -1.0 ) );
2040
0
    pSet->setPropertyDefaultValue( nHandleTextReverse, Any( false ) );
2041
2042
0
    pSet->setPropertyDefaultValue( nHandleCurrentPage, aEmpty );
2043
2044
0
    pSet->setPropertyDefaultValue( nHandleSoundURL, aEmpty );
2045
0
    pSet->setPropertyDefaultValue( nHandleSoundVolume, Any( 1.0) );
2046
0
    pSet->setPropertyDefaultValue( nHandleSoundEndAfterSlide, Any( sal_Int32(0) ) );
2047
2048
0
    pSet->setPropertyDefaultValue( nHandleCommand, Any( sal_Int16(0) ) );
2049
0
    return pSet;
2050
0
}
2051
2052
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)
2053
0
{
2054
0
    std::unique_ptr<SdPropertySubControl> pSubControl;
2055
0
    switch( nType )
2056
0
    {
2057
0
    case nPropertyTypeDirection:
2058
0
    case nPropertyTypeSpokes:
2059
0
    case nPropertyTypeZoom:
2060
0
        pSubControl.reset( new SdPresetPropertyBox( pLabel, pParent, rValue, rPresetId, rModifyHdl ) );
2061
0
        break;
2062
2063
0
    case nPropertyTypeColor:
2064
0
    case nPropertyTypeFillColor:
2065
0
    case nPropertyTypeFirstColor:
2066
0
    case nPropertyTypeCharColor:
2067
0
    case nPropertyTypeLineColor:
2068
0
        pSubControl.reset( new SdColorPropertyBox( pLabel, pParent, pTopLevel, rValue, rModifyHdl ) );
2069
0
        break;
2070
2071
0
    case nPropertyTypeFont:
2072
0
        pSubControl.reset( new SdFontPropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2073
0
        break;
2074
2075
0
    case nPropertyTypeCharHeight:
2076
0
        pSubControl.reset( new SdCharHeightPropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2077
0
        break;
2078
2079
0
    case nPropertyTypeRotate:
2080
0
        pSubControl.reset( new SdRotationPropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2081
0
        break;
2082
2083
0
    case nPropertyTypeTransparency:
2084
0
        pSubControl.reset( new SdTransparencyPropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2085
0
        break;
2086
2087
0
    case nPropertyTypeScale:
2088
0
        pSubControl.reset( new SdScalePropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2089
0
        break;
2090
2091
0
    case nPropertyTypeCharDecoration:
2092
0
        pSubControl.reset( new SdFontStylePropertyBox( pLabel, pParent, rValue, rModifyHdl ) );
2093
0
        break;
2094
0
    }
2095
2096
0
    return pSubControl;
2097
0
}
2098
2099
}
2100
2101
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */