Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/dlg/animobjs.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 <time.h>
21
#include <svl/eitem.hxx>
22
#include <svl/intitem.hxx>
23
#include <svx/svdograf.hxx>
24
#include <svx/svdogrp.hxx>
25
#include <svx/svdpagv.hxx>
26
#include <sfx2/dispatch.hxx>
27
#include <sfx2/progress.hxx>
28
#include <vcl/animate/Animation.hxx>
29
#include <vcl/animate/AnimationFrame.hxx>
30
#include <vcl/help.hxx>
31
#include <vcl/svapp.hxx>
32
#include <vcl/weld/Builder.hxx>
33
#include <vcl/weld/MessageDialog.hxx>
34
#include <vcl/weld/weld.hxx>
35
#include <vcl/virdev.hxx>
36
37
#include <anminfo.hxx>
38
#include <animobjs.hxx>
39
#include <app.hrc>
40
#include <strings.hrc>
41
#include <sdresid.hxx>
42
#include <View.hxx>
43
#include <drawdoc.hxx>
44
#include <sdpage.hxx>
45
46
#include <ViewShell.hxx>
47
48
#include <vcl/settings.hxx>
49
50
#include <EffectMigration.hxx>
51
52
#include <algorithm>
53
54
using namespace ::com::sun::star;
55
56
namespace sd {
57
58
/**
59
 *  SdDisplay - Control
60
 */
61
SdDisplay::SdDisplay()
62
0
    : aScale(1, 1)
63
0
{
64
0
}
65
66
SdDisplay::~SdDisplay()
67
0
{
68
0
}
69
70
void SdDisplay::SetBitmap( Bitmap const * pBmp )
71
0
{
72
0
    if( pBmp )
73
0
    {
74
0
        aBitmap = *pBmp;
75
0
    }
76
0
    else
77
0
    {
78
0
        const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
79
0
        const Color aFillColor = rStyles.GetFieldColor();
80
0
        aBitmap.Erase(aFillColor);
81
0
    }
82
0
}
83
84
void SdDisplay::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
85
0
{
86
0
    auto popIt = rRenderContext.ScopedPush(vcl::PushFlags::MAPMODE);
87
88
0
    rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
89
0
    const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
90
0
    rRenderContext.SetBackground( Wallpaper( rStyles.GetFieldColor() ) );
91
0
    rRenderContext.Erase();
92
93
0
    Point aPt;
94
0
    Size aSize = GetOutputSizePixel();
95
96
0
    Size aBmpSize = aBitmap.GetSizePixel();
97
0
    aBmpSize.setWidth( static_cast<::tools::Long>( static_cast<double>(aBmpSize.Width()) * static_cast<double>(aScale) ) );
98
0
    aBmpSize.setHeight( static_cast<::tools::Long>( static_cast<double>(aBmpSize.Height()) * static_cast<double>(aScale) ) );
99
100
0
    if( aBmpSize.Width() < aSize.Width() )
101
0
        aPt.setX( ( aSize.Width() - aBmpSize.Width() ) / 2 );
102
0
    if( aBmpSize.Height() < aSize.Height() )
103
0
        aPt.setY( ( aSize.Height() - aBmpSize.Height() ) / 2 );
104
105
0
    aBitmap.Draw(&rRenderContext, aPt, aBmpSize);
106
0
}
107
108
void SdDisplay::SetScale( const Fraction& rFrac )
109
0
{
110
0
    aScale = rFrac;
111
0
}
112
113
void SdDisplay::SetDrawingArea(weld::DrawingArea* pDrawingArea)
114
0
{
115
0
    CustomWidgetController::SetDrawingArea(pDrawingArea);
116
0
    Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(147, 87), MapMode(MapUnit::MapAppFont)));
117
0
    pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
118
0
    SetOutputSizePixel(aSize);
119
0
}
120
121
/**
122
 *  AnimationWindow - FloatingWindow
123
 */
124
AnimationWindow::AnimationWindow(SfxBindings* pInBindings, SfxChildWindow *pCW, vcl::Window* pParent)
125
0
    : SfxDockingWindow(pInBindings, pCW, pParent,
126
0
        u"DockingAnimation"_ustr, u"modules/simpress/ui/dockinganimation.ui"_ustr)
127
0
    , m_xCtlDisplay(new SdDisplay)
128
0
    , m_xCtlDisplayWin(new weld::CustomWeld(*m_xBuilder, u"preview"_ustr, *m_xCtlDisplay))
129
0
    , m_xBtnFirst(m_xBuilder->weld_button(u"first"_ustr))
130
0
    , m_xBtnReverse(m_xBuilder->weld_button(u"prev"_ustr))
131
0
    , m_xBtnStop(m_xBuilder->weld_button(u"stop"_ustr))
132
0
    , m_xBtnPlay(m_xBuilder->weld_button(u"next"_ustr))
133
0
    , m_xBtnLast(m_xBuilder->weld_button(u"last"_ustr))
134
0
    , m_xNumFldBitmap(m_xBuilder->weld_spin_button(u"numbitmap"_ustr))
135
0
    , m_xTimeField(m_xBuilder->weld_formatted_spin_button(u"duration"_ustr))
136
0
    , m_xFormatter(new weld::TimeFormatter(*m_xTimeField))
137
0
    , m_xLbLoopCount(m_xBuilder->weld_combo_box(u"loopcount"_ustr))
138
0
    , m_xBtnGetOneObject(m_xBuilder->weld_button(u"getone"_ustr))
139
0
    , m_xBtnGetAllObjects(m_xBuilder->weld_button(u"getall"_ustr))
140
0
    , m_xBtnRemoveBitmap(m_xBuilder->weld_button(u"delone"_ustr))
141
0
    , m_xBtnRemoveAll(m_xBuilder->weld_button(u"delall"_ustr))
142
0
    , m_xFiCount(m_xBuilder->weld_label(u"count"_ustr))
143
0
    , m_xRbtGroup(m_xBuilder->weld_radio_button(u"group"_ustr))
144
0
    , m_xRbtBitmap(m_xBuilder->weld_radio_button(u"bitmap"_ustr))
145
0
    , m_xFtAdjustment(m_xBuilder->weld_label(u"alignmentft"_ustr))
146
0
    , m_xLbAdjustment(m_xBuilder->weld_combo_box(u"alignment"_ustr))
147
0
    , m_xBtnCreateGroup(m_xBuilder->weld_button(u"create"_ustr))
148
0
    , m_xBtnHelp(m_xBuilder->weld_button(u"help"_ustr))
149
0
    , m_nCurrentFrame(EMPTY_FRAMELIST)
150
0
    , bMovie(false)
151
0
    , bAllObjects(false)
152
0
{
153
0
    SetText(SdResId(STR_ANIMATION_DIALOG_TITLE));
154
155
0
    m_xFormatter->SetDuration(true);
156
0
    m_xFormatter->SetTimeFormat(TimeFieldFormat::F_SEC_CS);
157
0
    m_xFormatter->EnableEmptyField(false);
158
159
    // create new document with page
160
0
    pMyDoc.reset( new SdDrawDocument(DocumentType::Impress, nullptr) );
161
0
    rtl::Reference<SdPage> pPage = pMyDoc->AllocSdPage(false);
162
0
    pMyDoc->InsertPage(pPage.get());
163
164
0
    pControllerItem.reset( new AnimationControllerItem( SID_ANIMATOR_STATE, this, pInBindings ) );
165
166
0
    m_xBtnFirst->connect_clicked( LINK( this, AnimationWindow, ClickFirstHdl ) );
167
0
    m_xBtnReverse->connect_clicked( LINK( this, AnimationWindow, ClickPlayHdl ) );
168
0
    m_xBtnStop->connect_clicked( LINK( this, AnimationWindow, ClickStopHdl ) );
169
0
    m_xBtnPlay->connect_clicked( LINK( this, AnimationWindow, ClickPlayHdl ) );
170
0
    m_xBtnLast->connect_clicked( LINK( this, AnimationWindow, ClickLastHdl ) );
171
172
0
    m_xBtnGetOneObject->connect_clicked( LINK( this, AnimationWindow, ClickGetObjectHdl ) );
173
0
    m_xBtnGetAllObjects->connect_clicked( LINK( this, AnimationWindow, ClickGetObjectHdl ) );
174
0
    m_xBtnRemoveBitmap->connect_clicked( LINK( this, AnimationWindow, ClickRemoveBitmapHdl ) );
175
0
    m_xBtnRemoveAll->connect_clicked( LINK( this, AnimationWindow, ClickRemoveBitmapHdl ) );
176
177
0
    m_xRbtGroup->connect_toggled( LINK( this, AnimationWindow, ClickRbtHdl ) );
178
0
    m_xRbtBitmap->connect_toggled( LINK( this, AnimationWindow, ClickRbtHdl ) );
179
0
    m_xBtnCreateGroup->connect_clicked( LINK( this, AnimationWindow, ClickCreateGroupHdl ) );
180
0
    m_xBtnHelp->connect_clicked( LINK( this, AnimationWindow, ClickHelpHdl ) );
181
0
    m_xNumFldBitmap->connect_value_changed( LINK( this, AnimationWindow, ModifyBitmapHdl ) );
182
0
    m_xTimeField->connect_value_changed( LINK( this, AnimationWindow, ModifyTimeHdl ) );
183
184
0
    SetMinOutputSizePixel(GetOptimalSize());
185
186
0
    ResetAttrs();
187
188
    // the animator is empty; no animation group can be created
189
0
    m_xBtnCreateGroup->set_sensitive(false);
190
0
}
Unexecuted instantiation: sd::AnimationWindow::AnimationWindow(SfxBindings*, SfxChildWindow*, vcl::Window*)
Unexecuted instantiation: sd::AnimationWindow::AnimationWindow(SfxBindings*, SfxChildWindow*, vcl::Window*)
191
192
AnimationWindow::~AnimationWindow()
193
0
{
194
0
    disposeOnce();
195
0
}
196
197
void AnimationWindow::dispose()
198
0
{
199
0
    pControllerItem.reset();
200
201
0
    m_FrameList.clear();
202
0
    m_nCurrentFrame = EMPTY_FRAMELIST;
203
204
    // delete the clones
205
0
    pMyDoc.reset();
206
207
0
    m_xCtlDisplayWin.reset();
208
0
    m_xCtlDisplay.reset();
209
0
    m_xBtnFirst.reset();
210
0
    m_xBtnReverse.reset();
211
0
    m_xBtnStop.reset();
212
0
    m_xBtnPlay.reset();
213
0
    m_xBtnLast.reset();
214
0
    m_xNumFldBitmap.reset();
215
0
    m_xFormatter.reset();
216
0
    m_xTimeField.reset();
217
0
    m_xLbLoopCount.reset();
218
0
    m_xBtnGetOneObject.reset();
219
0
    m_xBtnGetAllObjects.reset();
220
0
    m_xBtnRemoveBitmap.reset();
221
0
    m_xBtnRemoveAll.reset();
222
0
    m_xFiCount.reset();
223
0
    m_xRbtGroup.reset();
224
0
    m_xRbtBitmap.reset();
225
0
    m_xFtAdjustment.reset();
226
0
    m_xLbAdjustment.reset();
227
0
    m_xBtnCreateGroup.reset();
228
0
    m_xBtnHelp.reset();
229
0
    SfxDockingWindow::dispose();
230
0
}
231
232
IMPL_LINK_NOARG(AnimationWindow, ClickFirstHdl, weld::Button&, void)
233
0
{
234
0
    m_nCurrentFrame = (m_FrameList.empty()) ? EMPTY_FRAMELIST : 0;
235
0
    UpdateControl();
236
0
}
237
238
IMPL_LINK_NOARG(AnimationWindow, ClickStopHdl, weld::Button&, void)
239
0
{
240
0
    bMovie = false;
241
0
}
242
243
IMPL_LINK( AnimationWindow, ClickPlayHdl, weld::Button&, rButton, void )
244
0
{
245
0
    ScopeLockGuard aGuard( maPlayLock );
246
247
0
    bMovie = true;
248
0
    bool bDisableCtrls = false;
249
0
    size_t const nCount = m_FrameList.size();
250
0
    bool bReverse = &rButton == m_xBtnReverse.get();
251
252
    // it is difficult to find it later on
253
0
    bool bRbtGroupEnabled = m_xRbtGroup->get_sensitive();
254
0
    bool bBtnGetAllObjectsEnabled = m_xBtnGetAllObjects->get_sensitive();
255
0
    bool bBtnGetOneObjectEnabled = m_xBtnGetOneObject->get_sensitive();
256
257
    // calculate overall time
258
0
    ::tools::Long nFullTime;
259
0
    if( m_xRbtBitmap->get_active() )
260
0
    {
261
0
        ::tools::Time aTime(::tools::Time::EMPTY);
262
0
        for (size_t i = 0; i < nCount; ++i)
263
0
        {
264
0
            aTime += m_FrameList[i].second;
265
0
        }
266
0
        nFullTime  = aTime.GetMSFromTime();
267
0
    }
268
0
    else
269
0
    {
270
0
        nFullTime = nCount * 100;
271
0
    }
272
273
    // StatusBarManager from 1 second
274
0
    std::unique_ptr<SfxProgress> pProgress;
275
0
    if( nFullTime >= 1000 )
276
0
    {
277
0
        bDisableCtrls = true;
278
0
        m_xBtnStop->set_sensitive(true);
279
0
        pProgress.reset(new SfxProgress( nullptr, u"Animator:"_ustr, nFullTime )); // "Animator:" here we should think about something smart
280
0
    }
281
282
0
    sal_uLong nTmpTime = 0;
283
0
    size_t i = 0;
284
0
    bool bCount = i < nCount;
285
0
    if (bCount)
286
0
    {
287
0
        if( bReverse )
288
0
            i = nCount - 1;
289
290
0
        while (bMovie)
291
0
        {
292
            // make list and view consistent
293
0
            assert(i < m_FrameList.size());
294
0
            m_nCurrentFrame = i;
295
296
0
            UpdateControl(bDisableCtrls);
297
298
0
            if( m_xRbtBitmap->get_active() )
299
0
            {
300
0
                ::tools::Time const & rTime = m_FrameList[i].second;
301
302
0
                m_xFormatter->SetTime( rTime );
303
0
                sal_uLong nTime = rTime.GetMSFromTime();
304
305
0
                WaitInEffect( nTime, nTmpTime, pProgress.get() );
306
0
                nTmpTime += nTime;
307
0
            }
308
0
            else
309
0
            {
310
0
                WaitInEffect( 100, nTmpTime, pProgress.get() );
311
0
                nTmpTime += 100;
312
0
            }
313
0
            if( bReverse )
314
0
            {
315
0
                if (i == 0)
316
0
                {
317
                    // Terminate loop.
318
0
                    bCount = false;
319
0
                }
320
0
                else
321
0
                {
322
0
                    --i;
323
0
                }
324
0
            }
325
0
            else
326
0
            {
327
0
                i++;
328
0
                if (i >= nCount)
329
0
                {
330
                    // Terminate loop.
331
0
                    bCount = false;
332
                    // Move i back into valid range.
333
0
                    i = nCount - 1;
334
0
                }
335
0
            }
336
337
0
            if (!bCount)
338
0
                break;
339
0
        }
340
0
    }
341
342
    // to re-enable the controls
343
0
    bMovie = false;
344
0
    if (nCount > 0)
345
0
    {
346
0
        assert(i == m_nCurrentFrame);
347
0
        UpdateControl();
348
0
    }
349
350
0
    if( pProgress )
351
0
    {
352
0
        pProgress.reset();
353
0
        m_xBtnStop->set_sensitive(false);
354
0
    }
355
356
0
    m_xRbtGroup->set_sensitive( bRbtGroupEnabled );
357
0
    m_xBtnGetAllObjects->set_sensitive( bBtnGetAllObjectsEnabled );
358
0
    m_xBtnGetOneObject->set_sensitive( bBtnGetOneObjectEnabled );
359
0
}
360
361
IMPL_LINK_NOARG(AnimationWindow, ClickLastHdl, weld::Button&, void)
362
0
{
363
0
    m_nCurrentFrame =
364
0
        (m_FrameList.empty()) ? EMPTY_FRAMELIST : m_FrameList.size() - 1 ;
365
0
    UpdateControl();
366
0
}
367
368
IMPL_LINK_NOARG(AnimationWindow, ClickRbtHdl, weld::Toggleable&, void)
369
0
{
370
0
    if (m_FrameList.empty() || m_xRbtGroup->get_active())
371
0
    {
372
0
        m_xTimeField->set_text( OUString() );
373
0
        m_xTimeField->set_sensitive( false );
374
0
        m_xLbLoopCount->set_sensitive( false );
375
0
    }
376
0
    else if (m_xRbtBitmap->get_active())
377
0
    {
378
0
        sal_uLong n = m_xNumFldBitmap->get_value();
379
0
        if( n > 0 )
380
0
        {
381
0
            ::tools::Time const & rTime = m_FrameList[n - 1].second;
382
0
            m_xFormatter->SetTime( rTime );
383
0
            m_xFormatter->ReFormat();
384
0
        }
385
0
        m_xTimeField->set_sensitive(true);
386
0
        m_xLbLoopCount->set_sensitive(true);
387
0
    }
388
0
}
389
390
IMPL_LINK(AnimationWindow, ClickHelpHdl, weld::Button&, rButton, void)
391
0
{
392
0
    if (Help* pHelp = Application::GetHelp())
393
0
        pHelp->Start(m_xContainer->get_help_id(), &rButton);
394
0
}
395
396
IMPL_LINK( AnimationWindow, ClickGetObjectHdl, weld::Button&, rBtn, void )
397
0
{
398
0
    bAllObjects = &rBtn == m_xBtnGetAllObjects.get();
399
400
    // Code now in AddObj()
401
0
    SfxBoolItem aItem( SID_ANIMATOR_ADD, true );
402
403
0
    GetBindings().GetDispatcher()->ExecuteList(
404
0
        SID_ANIMATOR_ADD, SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem });
405
0
}
406
407
IMPL_LINK( AnimationWindow, ClickRemoveBitmapHdl, weld::Button&, rBtn, void )
408
0
{
409
0
    SdPage*     pPage = pMyDoc->GetSdPage(0, PageKind::Standard);
410
0
    rtl::Reference<SdrObject> pObject;
411
412
    // tdf#95298 check m_nCurrentFrame for EMPTY_FRAMELIST to avoid out-of-bound array access
413
0
    if (&rBtn == m_xBtnRemoveBitmap.get() && EMPTY_FRAMELIST  != m_nCurrentFrame)
414
0
    {
415
0
        m_FrameList.erase(m_FrameList.begin() + m_nCurrentFrame);
416
417
0
        pObject = pPage->GetObj(m_nCurrentFrame);
418
        // Through acquisition of the AnimatedGIFs, objects does not need to
419
        // exist.
420
0
        if( pObject )
421
0
        {
422
0
            pObject = pPage->RemoveObject(m_nCurrentFrame);
423
0
            DBG_ASSERT(pObject, "Clone not found during deletion");
424
0
            pObject.clear();
425
0
            pPage->RecalcObjOrdNums();
426
0
        }
427
428
0
        if (m_nCurrentFrame >= m_FrameList.size())
429
0
        {
430
            // tdf#95298 last frame was deleted, try to use the one before it or go on empty state
431
0
            m_nCurrentFrame = m_FrameList.empty() ? EMPTY_FRAMELIST : m_FrameList.size() - 1;
432
0
        }
433
0
    }
434
0
    else // delete everything
435
0
    {
436
0
        std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetFrameWeld(),
437
0
                                                   VclMessageType::Warning, VclButtonsType::YesNo,
438
0
                                                   SdResId(STR_ASK_DELETE_ALL_PICTURES)));
439
0
        short nReturn = xWarn->run();
440
441
0
        if( nReturn == RET_YES )
442
0
        {
443
            // clear frame list
444
0
            for (size_t i = m_FrameList.size(); i > 0; )
445
0
            {
446
0
                --i;
447
0
                pObject = pPage->GetObj( i );
448
0
                if( pObject )
449
0
                {
450
0
                    pObject = pPage->RemoveObject( i );
451
0
                    DBG_ASSERT(pObject, "Clone not found during deletion");
452
0
                    pObject.clear();
453
                    //pPage->RecalcObjOrdNums();
454
0
                }
455
0
            }
456
0
            m_FrameList.clear();
457
0
            m_nCurrentFrame = EMPTY_FRAMELIST;
458
0
        }
459
0
    }
460
461
    // can we create an animation group
462
0
    if (m_FrameList.empty())
463
0
    {
464
0
        m_xBtnCreateGroup->set_sensitive(false);
465
        // if previous disabled by acquisition of AnimatedGIFs:
466
        //m_xRbtBitmap->set_sensitive(true);
467
0
        m_xRbtGroup->set_sensitive(true);
468
0
    }
469
470
    // calculate and set zoom for DisplayWin
471
0
    Fraction aFrac(GetScale());
472
0
    m_xCtlDisplay->SetScale(aFrac);
473
474
0
    UpdateControl();
475
0
}
476
477
IMPL_LINK_NOARG(AnimationWindow, ClickCreateGroupHdl, weld::Button&, void)
478
0
{
479
    // Code now in CreatePresObj()
480
0
    SfxBoolItem aItem( SID_ANIMATOR_CREATE, true );
481
482
0
    GetBindings().GetDispatcher()->ExecuteList(SID_ANIMATOR_CREATE,
483
0
            SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem });
484
0
}
485
486
IMPL_LINK_NOARG(AnimationWindow, ModifyBitmapHdl, weld::SpinButton&, void)
487
0
{
488
0
    sal_uLong nBmp = m_xNumFldBitmap->get_value();
489
490
0
    if (nBmp > m_FrameList.size())
491
0
    {
492
0
        nBmp = m_FrameList.size();
493
0
    }
494
495
0
    m_nCurrentFrame = nBmp - 1;
496
497
0
    UpdateControl();
498
0
}
499
500
IMPL_LINK_NOARG(AnimationWindow, ModifyTimeHdl, weld::FormattedSpinButton&, void)
501
0
{
502
0
    sal_uLong nPos = m_xNumFldBitmap->get_value() - 1;
503
504
0
    ::tools::Time & rTime = m_FrameList[nPos].second;
505
506
0
    rTime = m_xFormatter->GetTime();
507
0
}
508
509
void AnimationWindow::UpdateControl(bool const bDisableCtrls)
510
0
{
511
    // tdf#95298 check m_nCurrentFrame for EMPTY_FRAMELIST to avoid out-of-bound array access
512
0
    if (!m_FrameList.empty() && EMPTY_FRAMELIST != m_nCurrentFrame)
513
0
    {
514
0
        Bitmap aBmp(m_FrameList[m_nCurrentFrame].first);
515
516
0
        SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard);
517
0
        SdrObject *const pObject = pPage->GetObj(m_nCurrentFrame);
518
0
        if( pObject )
519
0
        {
520
0
            ScopedVclPtrInstance< VirtualDevice > pVD;
521
0
            ::tools::Rectangle       aObjRect( pObject->GetCurrentBoundRect() );
522
0
            Size            aObjSize( aObjRect.GetSize() );
523
0
            Point           aOrigin( -aObjRect.Left(), -aObjRect.Top() );
524
0
            MapMode         aMap( pVD->GetMapMode() );
525
0
            aMap.SetMapUnit( MapUnit::Map100thMM );
526
0
            aMap.SetOrigin( aOrigin );
527
0
            pVD->SetMapMode( aMap );
528
0
            pVD->SetOutputSize( aObjSize );
529
0
            const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
530
0
            pVD->SetBackground( Wallpaper( rStyles.GetFieldColor() ) );
531
0
            pVD->SetDrawMode( rStyles.GetHighContrastMode()
532
0
                ? sd::OUTPUT_DRAWMODE_CONTRAST
533
0
                : sd::OUTPUT_DRAWMODE_COLOR );
534
0
            pVD->Erase();
535
0
            pObject->SingleObjectPainter( *pVD );
536
0
            aBmp = pVD->GetBitmap( aObjRect.TopLeft(), aObjSize );
537
0
        }
538
539
0
        m_xCtlDisplay->SetBitmap(&aBmp);
540
0
    }
541
0
    else
542
0
    {
543
0
        m_xCtlDisplay->SetBitmap(nullptr);
544
0
    }
545
546
0
    m_xCtlDisplay->Invalidate();
547
548
0
    m_xFiCount->set_label(OUString::number(
549
0
                m_FrameList.size()));
550
551
0
    if (!m_FrameList.empty() && !bMovie)
552
0
    {
553
0
        assert(m_nCurrentFrame != EMPTY_FRAMELIST && "only arises when m_FrameList.empty()");
554
555
0
        size_t nIndex = m_nCurrentFrame + 1;
556
0
        m_xNumFldBitmap->set_value(nIndex);
557
558
        // if there is at least 1 object in the list
559
0
        m_xBtnFirst->set_sensitive(true);
560
0
        m_xBtnReverse->set_sensitive(true);
561
0
        m_xBtnPlay->set_sensitive(true);
562
0
        m_xBtnLast->set_sensitive(true);
563
0
        m_xNumFldBitmap->set_sensitive(true);
564
0
        m_xTimeField->set_sensitive(true);
565
0
        m_xLbLoopCount->set_sensitive(true);
566
0
        m_xBtnRemoveBitmap->set_sensitive(true);
567
0
        m_xBtnRemoveAll->set_sensitive(true);
568
0
    }
569
0
    else
570
0
    {
571
        // if no object is in the list
572
0
        m_xBtnFirst->set_sensitive( false );
573
0
        m_xBtnReverse->set_sensitive( false );
574
0
        m_xBtnPlay->set_sensitive( false );
575
0
        m_xBtnLast->set_sensitive( false );
576
0
        m_xNumFldBitmap->set_sensitive( false );
577
0
        m_xTimeField->set_sensitive( false );
578
0
        m_xLbLoopCount->set_sensitive( false );
579
0
        m_xBtnRemoveBitmap->set_sensitive( false );
580
0
        m_xBtnRemoveAll->set_sensitive( false );
581
0
    }
582
583
0
    if( bMovie && bDisableCtrls )
584
0
    {
585
0
        m_xBtnGetOneObject->set_sensitive( false );
586
0
        m_xBtnGetAllObjects->set_sensitive( false );
587
0
        m_xRbtGroup->set_sensitive( false );
588
0
        m_xRbtBitmap->set_sensitive( false );
589
0
        m_xBtnCreateGroup->set_sensitive( false );
590
0
        m_xFtAdjustment->set_sensitive( false );
591
0
        m_xLbAdjustment->set_sensitive( false );
592
0
    }
593
0
    else
594
0
    {
595
        // enable 'group object' only if it is not an Animated GIF
596
0
        if (m_FrameList.empty())
597
0
        {
598
0
            m_xRbtGroup->set_sensitive(true);
599
0
        }
600
601
0
        m_xRbtBitmap->set_sensitive(true);
602
0
        m_xBtnCreateGroup->set_sensitive(!m_FrameList.empty());
603
0
        m_xFtAdjustment->set_sensitive(true);
604
0
        m_xLbAdjustment->set_sensitive(true);
605
0
    }
606
607
0
    ClickRbtHdl(*m_xRbtGroup);
608
0
}
609
610
void AnimationWindow::ResetAttrs()
611
0
{
612
0
    m_xRbtGroup->set_active(true);
613
0
    m_xLbAdjustment->set_active( BA_CENTER );
614
    // LoopCount
615
0
    m_xLbLoopCount->set_active( m_xLbLoopCount->get_count() - 1);
616
617
0
    UpdateControl();
618
0
}
619
620
void AnimationWindow::WaitInEffect( sal_uLong nMilliSeconds, sal_uLong nTime,
621
                                    SfxProgress* pProgress ) const
622
0
{
623
0
    sal_uInt64 aEnd = ::tools::Time::GetSystemTicks() + nMilliSeconds;
624
0
    sal_uInt64 aCurrent = ::tools::Time::GetSystemTicks();
625
0
    while (aCurrent < aEnd)
626
0
    {
627
0
        aCurrent = ::tools::Time::GetSystemTicks();
628
629
0
        if( pProgress )
630
0
            pProgress->SetState( nTime + nMilliSeconds + aCurrent - aEnd );
631
632
0
        Application::Reschedule();
633
634
0
        if( !bMovie )
635
0
            return;
636
0
    }
637
0
}
638
639
Fraction AnimationWindow::GetScale()
640
0
{
641
0
    Fraction aFrac;
642
0
    size_t const nCount = m_FrameList.size();
643
0
    if (nCount > 0)
644
0
    {
645
0
        Size aBmpSize(0, 0);
646
0
        for (size_t i = 0; i < nCount; i++)
647
0
        {
648
0
            Bitmap const & rBitmap = m_FrameList[i].first;
649
0
            Size aTempSize( rBitmap.GetSizePixel() );
650
0
            aBmpSize.setWidth( std::max( aBmpSize.Width(), aTempSize.Width() ) );
651
0
            aBmpSize.setHeight( std::max( aBmpSize.Height(), aTempSize.Height() ) );
652
0
        }
653
654
0
        aBmpSize.AdjustWidth(10 );
655
0
        aBmpSize.AdjustHeight(10 );
656
657
0
        Size aDisplaySize(m_xCtlDisplay->GetOutputSizePixel());
658
659
0
        aFrac = Fraction( std::min( static_cast<double>(aDisplaySize.Width()) / static_cast<double>(aBmpSize.Width()),
660
0
                             static_cast<double>(aDisplaySize.Height()) / static_cast<double>(aBmpSize.Height()) ) );
661
0
    }
662
0
    return aFrac;
663
0
}
664
665
void AnimationWindow::Resize()
666
0
{
667
0
    SfxDockingWindow::Resize();
668
0
    Fraction aFrac(GetScale());
669
0
    m_xCtlDisplay->SetScale(aFrac);
670
0
}
671
672
bool AnimationWindow::Close()
673
0
{
674
0
    if( maPlayLock.isLocked() )
675
0
    {
676
0
        return false;
677
0
    }
678
0
    else
679
0
    {
680
0
        SfxBoolItem aItem( SID_ANIMATION_OBJECTS, false );
681
682
0
        GetBindings().GetDispatcher()->ExecuteList(
683
0
            SID_ANIMATION_OBJECTS, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
684
0
            { &aItem });
685
686
0
        SfxDockingWindow::Close();
687
688
0
        return true;
689
0
    }
690
0
}
691
692
void AnimationWindow::AddObj (::sd::View& rView )
693
0
{
694
    // finish text entry mode to ensure that bitmap is identical with object
695
0
    if( rView.IsTextEdit() )
696
0
        rView.SdrEndTextEdit();
697
698
    // clone object(s) and insert the clone(s) into the list
699
0
    const SdrMarkList& rMarkList   = rView.GetMarkedObjectList();
700
0
    const size_t nMarkCount = rMarkList.GetMarkCount();
701
0
    SdPage*            pPage       = pMyDoc->GetSdPage(0, PageKind::Standard);
702
0
    const size_t nCloneCount = pPage->GetObjCount();
703
704
0
    if (nMarkCount <= 0)
705
0
        return;
706
707
    // If it is ONE animation object or one group object, which was
708
    // 'individually taken', we insert the objects separately
709
0
    bool bAnimObj = false;
710
0
    if( nMarkCount == 1 )
711
0
    {
712
0
        SdrMark*            pMark = rMarkList.GetMark(0);
713
0
        SdrObject*          pObject = pMark->GetMarkedSdrObj();
714
0
        SdAnimationInfo*    pAnimInfo = SdDrawDocument::GetAnimationInfo( pObject );
715
0
        SdrInventor         nInv = pObject->GetObjInventor();
716
0
        SdrObjKind          nId = pObject->GetObjIdentifier();
717
718
        // Animated Bitmap (GIF)
719
0
        if( nInv == SdrInventor::Default && nId == SdrObjKind::Graphic && static_cast<SdrGrafObj*>( pObject )->IsAnimated() )
720
0
        {
721
0
            const SdrGrafObj*   pGrafObj = static_cast<SdrGrafObj*>(pObject);
722
0
            Graphic             aGraphic( pGrafObj->GetTransformedGraphic() );
723
0
            sal_uInt16              nCount = 0;
724
725
0
            if( aGraphic.IsAnimated() )
726
0
                nCount = aGraphic.GetAnimation().Count();
727
728
0
            if( nCount > 0 )
729
0
            {
730
0
                const Animation aAnimation( aGraphic.GetAnimation() );
731
732
0
                for( sal_uInt16 i = 0; i < nCount; i++ )
733
0
                {
734
0
                    const AnimationFrame& rAnimationFrame = aAnimation.Get( i );
735
736
                    // LoopCount
737
0
                    if( i == 0 )
738
0
                    {
739
0
                        sal_uInt32 nLoopCount = aAnimation.GetLoopCount();
740
741
0
                        if( !nLoopCount ) // endless
742
0
                            m_xLbLoopCount->set_active( m_xLbLoopCount->get_count() - 1);
743
0
                        else
744
0
                            m_xLbLoopCount->set_active_text(OUString::number( nLoopCount ) );
745
0
                    }
746
747
0
                    ::tools::Long nTime = rAnimationFrame.mnWait;
748
0
                    ::tools::Time aTime( 0, 0, nTime / 100, nTime % 100 );
749
0
                    size_t nIndex = m_nCurrentFrame + 1;
750
0
                    m_FrameList.insert(
751
0
                            m_FrameList.begin() + nIndex,
752
0
                            ::std::make_pair(rAnimationFrame.maBitmap, aTime));
753
754
                    // increment => next one inserted after this one
755
0
                    ++m_nCurrentFrame;
756
0
                }
757
                // if an animated GIF is taken, only such one can be created
758
0
                m_xRbtBitmap->set_active(true);
759
0
                m_xRbtGroup->set_sensitive( false );
760
0
                bAnimObj = true;
761
0
            }
762
0
        }
763
0
        else if( bAllObjects || ( pAnimInfo && pAnimInfo->mbIsMovie ) )
764
0
        {
765
            // several objects
766
0
            SdrObjList* pObjList = static_cast<SdrObjGroup*>(pObject)->GetSubList();
767
768
0
            for (const rtl::Reference<SdrObject>& pSnapShot : *pObjList)
769
0
            {
770
0
                Bitmap aBitmap(SdrExchangeView::GetObjGraphic(*pSnapShot).GetBitmap());
771
0
                size_t nIndex = m_nCurrentFrame + 1;
772
0
                m_FrameList.insert(
773
0
                        m_FrameList.begin() + nIndex,
774
0
                        ::std::make_pair(aBitmap, m_xFormatter->GetTime()));
775
776
                // increment => next one inserted after this one
777
0
                ++m_nCurrentFrame;
778
779
                // Clone
780
0
                pPage->InsertObject(
781
0
                    pSnapShot->CloneSdrObject(pPage->getSdrModelFromSdrPage()).get(),
782
0
                    m_nCurrentFrame);
783
0
            }
784
0
            bAnimObj = true;
785
0
        }
786
0
    }
787
    // also one single animated object
788
0
    if( !bAnimObj && !( bAllObjects && nMarkCount > 1 ) )
789
0
    {
790
0
        Bitmap aBitmap(rView.GetAllMarkedGraphic().GetBitmap());
791
792
0
        ::tools::Time aTime( m_xFormatter->GetTime() );
793
794
0
        size_t nIndex = m_nCurrentFrame + 1;
795
0
        m_FrameList.insert(
796
0
                m_FrameList.begin() + nIndex,
797
0
                ::std::make_pair(aBitmap, aTime));
798
0
    }
799
800
    // one single object
801
0
    if( nMarkCount == 1 && !bAnimObj )
802
0
    {
803
0
        SdrMark*    pMark   = rMarkList.GetMark(0);
804
0
        SdrObject*  pObject = pMark->GetMarkedSdrObj();
805
0
        rtl::Reference<SdrObject> pClone(pObject->CloneSdrObject(pPage->getSdrModelFromSdrPage()));
806
0
        size_t nIndex = m_nCurrentFrame + 1;
807
0
        pPage->InsertObject(pClone.get(), nIndex);
808
0
    }
809
    // several objects: group the clones
810
0
    else if (nMarkCount > 1)
811
0
    {
812
        // take objects separately
813
0
        if( bAllObjects )
814
0
        {
815
0
            for( size_t nObject= 0; nObject < nMarkCount; ++nObject )
816
0
            {
817
                // Clone
818
0
                SdrObject* pObject(rMarkList.GetMark(nObject)->GetMarkedSdrObj());
819
0
                Bitmap aBitmap(SdrExchangeView::GetObjGraphic(*pObject).GetBitmap());
820
0
                size_t nIndex = m_nCurrentFrame + 1;
821
0
                m_FrameList.insert(
822
0
                    m_FrameList.begin() + nIndex,
823
0
                    ::std::make_pair(aBitmap, m_xFormatter->GetTime()));
824
825
                // increment => next one inserted after this one
826
0
                ++m_nCurrentFrame;
827
828
0
                pPage->InsertObject(
829
0
                    pObject->CloneSdrObject(pPage->getSdrModelFromSdrPage()).get(),
830
0
                    m_nCurrentFrame);
831
0
            }
832
0
            bAnimObj = true; // that we don't change again
833
0
        }
834
0
        else
835
0
        {
836
0
            rtl::Reference<SdrObjGroup> pCloneGroup = new SdrObjGroup(rView.getSdrModelFromSdrView());
837
0
            SdrObjList*  pObjList    = pCloneGroup->GetSubList();
838
839
0
            for (size_t nObject= 0; nObject < nMarkCount; ++nObject)
840
0
            {
841
0
                pObjList->InsertObject(
842
0
                    rMarkList.GetMark(nObject)->GetMarkedSdrObj()->CloneSdrObject(
843
0
                        pPage->getSdrModelFromSdrPage()).get());
844
0
            }
845
846
0
            size_t nIndex = m_nCurrentFrame + 1;
847
0
            pPage->InsertObject(pCloneGroup.get(), nIndex);
848
0
        }
849
0
    }
850
851
0
    if( !bAnimObj )
852
0
    {
853
0
        ++m_nCurrentFrame;
854
0
    }
855
856
    // if there was nothing in the animator before but now is something
857
    // there, we can create an animation group
858
0
    if (nCloneCount == 0 && !m_FrameList.empty())
859
0
    {
860
0
        m_xBtnCreateGroup->set_sensitive(true);
861
0
    }
862
863
    // calculate and set zoom for DisplayWin
864
0
    Fraction aFrac( GetScale() );
865
0
    m_xCtlDisplay->SetScale(aFrac);
866
867
0
    UpdateControl();
868
0
}
869
870
void AnimationWindow::CreateAnimObj (::sd::View& rView )
871
0
{
872
0
    vcl::Window* pOutWin = rView.GetFirstOutputDevice()->GetOwnerWindow(); // GetWin( 0 );
873
0
    DBG_ASSERT( pOutWin, "Window does not exist!" );
874
875
    // find window center
876
0
    const MapMode       aMap100( MapUnit::Map100thMM );
877
0
    Size                aMaxSizeLog;
878
0
    Size                aMaxSizePix;
879
0
    Size                aTemp( pOutWin->GetOutputSizePixel() );
880
0
    const Point         aWindowCenter( pOutWin->PixelToLogic( Point( aTemp.Width() >> 1, aTemp.Height() >> 1 ) ) );
881
0
    const OutputDevice* pDefDev = Application::GetDefaultDevice();
882
0
    const size_t nCount = m_FrameList.size();
883
0
    BitmapAdjustment    eBA = static_cast<BitmapAdjustment>(m_xLbAdjustment->get_active());
884
885
    // find biggest bitmap
886
0
    for (size_t i = 0; i < nCount; ++i)
887
0
    {
888
0
        const Bitmap&   rBmp = m_FrameList[i].first;
889
0
        const Graphic   aGraphic( rBmp );
890
0
        Size            aTmpSizeLog;
891
0
        const Size      aTmpSizePix( rBmp.GetSizePixel() );
892
893
0
        if ( aGraphic.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel )
894
0
            aTmpSizeLog = pDefDev->PixelToLogic( aGraphic.GetPrefSize(), aMap100 );
895
0
        else
896
0
            aTmpSizeLog = OutputDevice::LogicToLogic( aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), aMap100 );
897
898
0
        aMaxSizeLog.setWidth( std::max( aMaxSizeLog.Width(), aTmpSizeLog.Width() ) );
899
0
        aMaxSizeLog.setHeight( std::max( aMaxSizeLog.Height(), aTmpSizeLog.Height() ) );
900
901
0
        aMaxSizePix.setWidth( std::max( aMaxSizePix.Width(), aTmpSizePix.Width() ) );
902
0
        aMaxSizePix.setHeight( std::max( aMaxSizePix.Height(), aTmpSizePix.Height() ) );
903
0
    }
904
905
0
    SdrPageView* pPV = rView.GetSdrPageView();
906
907
0
    if( m_xRbtBitmap->get_active() )
908
0
    {
909
        // create bitmap group (Animated GIF)
910
0
        Animation   aAnimation;
911
0
        Point       aPt;
912
913
0
        for (size_t i = 0; i < nCount; ++i)
914
0
        {
915
0
            ::tools::Time const & rTime = m_FrameList[i].second;
916
0
            ::tools::Long  nTime = rTime.GetNanoSec();
917
0
            nTime += rTime.GetSec() * 100;
918
919
0
            Bitmap const & rBitmap = m_FrameList[i].first;
920
921
            // calculate offset for the specified direction
922
0
            const Size aBitmapSize( rBitmap.GetSizePixel() );
923
924
0
            switch( eBA )
925
0
            {
926
0
                case BA_LEFT_UP:
927
0
                break;
928
929
0
                case BA_LEFT:
930
0
                    aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 );
931
0
                break;
932
933
0
                case BA_LEFT_DOWN:
934
0
                    aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() );
935
0
                break;
936
937
0
                case BA_UP:
938
0
                    aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 );
939
0
                break;
940
941
0
                case BA_CENTER:
942
0
                    aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 );
943
0
                    aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 );
944
0
                break;
945
946
0
                case BA_DOWN:
947
0
                    aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 );
948
0
                    aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() );
949
0
                break;
950
951
0
                case BA_RIGHT_UP:
952
0
                    aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() );
953
0
                break;
954
955
0
                case BA_RIGHT:
956
0
                    aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() );
957
0
                    aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 );
958
0
                break;
959
960
0
                case BA_RIGHT_DOWN:
961
0
                    aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() );
962
0
                    aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() );
963
0
                break;
964
965
0
            }
966
967
            // find LoopCount (number of passes)
968
0
            AnimationFrame aAnimationFrame;
969
0
            sal_uInt32 nLoopCount = 0;
970
0
            sal_Int32 nPos = m_xLbLoopCount->get_active();
971
972
0
            if( nPos != -1 && nPos != m_xLbLoopCount->get_count() - 1 ) // endless
973
0
                nLoopCount = m_xLbLoopCount->get_active_text().toUInt32();
974
975
0
            aAnimationFrame.maBitmap = rBitmap;
976
0
            aAnimationFrame.maPositionPixel = aPt;
977
0
            aAnimationFrame.maSizePixel = aBitmapSize;
978
0
            aAnimationFrame.mnWait = nTime;
979
0
            aAnimationFrame.meDisposal = Disposal::Back;
980
0
            aAnimationFrame.mbUserInput = false;
981
982
0
            aAnimation.Insert( aAnimationFrame );
983
0
            aAnimation.SetDisplaySizePixel( aMaxSizePix );
984
0
            aAnimation.SetLoopCount( nLoopCount );
985
0
        }
986
987
0
        rtl::Reference<SdrGrafObj> pGrafObj = new SdrGrafObj(
988
0
            rView.getSdrModelFromSdrView(),
989
0
            Graphic(aAnimation));
990
0
        const Point aOrg( aWindowCenter.X() - ( aMaxSizeLog.Width() >> 1 ), aWindowCenter.Y() - ( aMaxSizeLog.Height() >> 1 ) );
991
992
0
        pGrafObj->SetLogicRect( ::tools::Rectangle( aOrg, aMaxSizeLog ) );
993
0
        rView.InsertObjectAtView( pGrafObj.get(), *pPV, SdrInsertFlags::SETDEFLAYER);
994
0
    }
995
0
    else
996
0
    {
997
        // calculate offset for the specified direction
998
0
        Size aOffset;
999
0
        SdrObject * pClone = nullptr;
1000
0
        SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard);
1001
1002
0
        for (size_t i = 0; i < nCount; ++i)
1003
0
        {
1004
0
            pClone = pPage->GetObj(i);
1005
0
            ::tools::Rectangle aRect( pClone->GetSnapRect() );
1006
1007
0
            switch( eBA )
1008
0
            {
1009
0
                case BA_LEFT_UP:
1010
0
                break;
1011
1012
0
                case BA_LEFT:
1013
0
                    aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 );
1014
0
                break;
1015
1016
0
                case BA_LEFT_DOWN:
1017
0
                    aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() );
1018
0
                break;
1019
1020
0
                case BA_UP:
1021
0
                    aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 );
1022
0
                break;
1023
1024
0
                case BA_CENTER:
1025
0
                    aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 );
1026
0
                    aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 );
1027
0
                break;
1028
1029
0
                case BA_DOWN:
1030
0
                    aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 );
1031
0
                    aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() );
1032
0
                break;
1033
1034
0
                case BA_RIGHT_UP:
1035
0
                    aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() );
1036
0
                break;
1037
1038
0
                case BA_RIGHT:
1039
0
                    aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() );
1040
0
                    aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 );
1041
0
                break;
1042
1043
0
                case BA_RIGHT_DOWN:
1044
0
                    aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() );
1045
0
                    aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() );
1046
0
                break;
1047
1048
0
            }
1049
            // Unfortunately, SetSnapRect is not implemented for ellipses !!!
1050
0
            Point aMovePt( aWindowCenter + Point( aOffset.Width(), aOffset.Height() ) - aRect.TopLeft() );
1051
0
            Size aMoveSize( aMovePt.X(), aMovePt.Y() );
1052
0
            pClone->NbcMove( aMoveSize );
1053
0
        }
1054
1055
        // #i42894# Caution(!) variable pPage looks right, but it is a page from the local
1056
        // document the dialog is using (!), so get the target page from the target view
1057
0
        SdPage* pTargetSdPage = dynamic_cast< SdPage* >(rView.GetSdrPageView() ? rView.GetSdrPageView()->GetPage() : nullptr);
1058
1059
0
        if(pTargetSdPage)
1060
0
        {
1061
            // create animation group
1062
0
            rtl::Reference<SdrObjGroup> pGroup   = new SdrObjGroup(rView.getSdrModelFromSdrView());
1063
0
            SdrObjList*  pObjList = pGroup->GetSubList();
1064
1065
0
            for (size_t i = 0; i < nCount; ++i)
1066
0
            {
1067
                // the clone remains in the animation; we insert a clone of the
1068
                // clone into the group
1069
0
                pClone = pPage->GetObj(i);
1070
0
                rtl::Reference<SdrObject> pCloneOfClone(pClone->CloneSdrObject(pTargetSdPage->getSdrModelFromSdrPage()));
1071
                //SdrObject* pCloneOfClone = pPage->GetObj(i)->Clone();
1072
0
                pObjList->InsertObject(pCloneOfClone.get());
1073
0
            }
1074
1075
            // until now the top left corner of the group is in the window center;
1076
            // correct the position by half of the size of the group
1077
0
            aTemp = aMaxSizeLog;
1078
0
            aTemp.setHeight( - aTemp.Height() / 2 );
1079
0
            aTemp.setWidth( - aTemp.Width() / 2 );
1080
0
            pGroup->NbcMove(aTemp);
1081
1082
            // #i42894# create needed SMIL stuff and move child objects to page directly (see
1083
            // comments at EffectMigration::CreateAnimatedGroup why this has to be done).
1084
0
            EffectMigration::CreateAnimatedGroup(*pGroup, *pTargetSdPage);
1085
0
        }
1086
0
    }
1087
1088
0
    ClickFirstHdl(*m_xBtnFirst);
1089
0
}
1090
1091
void AnimationWindow::DataChanged( const DataChangedEvent& rDCEvt )
1092
0
{
1093
0
    SfxDockingWindow::DataChanged( rDCEvt );
1094
1095
0
    if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1096
0
    {
1097
0
        UpdateControl();
1098
0
    }
1099
0
}
1100
1101
/**
1102
 * ControllerItem for Animator
1103
 */
1104
AnimationControllerItem::AnimationControllerItem(
1105
    sal_uInt16 _nId,
1106
    AnimationWindow* pAnimWin,
1107
    SfxBindings*    _pBindings)
1108
0
    : SfxControllerItem( _nId, *_pBindings ),
1109
0
      pAnimationWin( pAnimWin )
1110
0
{
1111
0
}
1112
1113
void AnimationControllerItem::StateChangedAtToolBoxControl( sal_uInt16 nSId,
1114
                        SfxItemState eState, const SfxPoolItem* pItem )
1115
0
{
1116
0
    if( eState >= SfxItemState::DEFAULT && nSId == SID_ANIMATOR_STATE )
1117
0
    {
1118
0
        const SfxUInt16Item* pStateItem = dynamic_cast< const SfxUInt16Item*>( pItem );
1119
0
        assert(pStateItem); //SfxUInt16Item expected
1120
0
        if (pStateItem)
1121
0
        {
1122
0
            sal_uInt16 nState = pStateItem->GetValue();
1123
0
            pAnimationWin->m_xBtnGetOneObject->set_sensitive( nState & 1 );
1124
0
            pAnimationWin->m_xBtnGetAllObjects->set_sensitive( nState & 2 );
1125
0
        }
1126
0
    }
1127
0
}
1128
1129
} // end of namespace sd
1130
1131
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */