Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/draw/animexp.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
21
#include <com/sun/star/beans/XPropertySet.hpp>
22
#include <com/sun/star/drawing/XShape.hpp>
23
#include <com/sun/star/lang/XServiceInfo.hpp>
24
#include <com/sun/star/presentation/AnimationSpeed.hpp>
25
#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
26
27
#include <sax/tools/converter.hxx>
28
#include <sal/log.hxx>
29
#include <comphelper/diagnose_ex.hxx>
30
31
#include <list>
32
#include <comphelper/extract.hxx>
33
#include <xmloff/xmltoken.hxx>
34
#include <xmloff/xmlnamespace.hxx>
35
#include <xmloff/xmluconv.hxx>
36
#include <xmloff/xmlexp.hxx>
37
#include <anim.hxx>
38
39
40
using namespace ::cppu;
41
using namespace ::com::sun::star;
42
using namespace ::com::sun::star::uno;
43
using namespace ::com::sun::star::drawing;
44
using namespace ::com::sun::star::beans;
45
using namespace ::com::sun::star::lang;
46
using namespace ::com::sun::star::presentation;
47
using namespace ::xmloff::token;
48
49
namespace {
50
51
struct Effect
52
{
53
    XMLEffect meKind;
54
    XMLEffectDirection meDirection;
55
    sal_Int16 mnStartScale;
56
    bool mbIn;
57
};
58
59
}
60
61
const Effect AnimationEffectMap[] =
62
{
63
    { EK_none, ED_none,             -1, true }, // AnimationEffect_NONE
64
    { EK_fade, ED_from_left,        -1, true }, // AnimationEffect_FADE_FROM_LEFT
65
    { EK_fade, ED_from_top,         -1, true }, // AnimationEffect_FADE_FROM_TOP
66
    { EK_fade, ED_from_right,       -1, true }, // AnimationEffect_FADE_FROM_RIGHT
67
    { EK_fade, ED_from_bottom,      -1, true }, // AnimationEffect_FADE_FROM_BOTTOM
68
    { EK_fade, ED_to_center,        -1, true }, // AnimationEffect_FADE_TO_CENTER
69
    { EK_fade, ED_from_center,      -1, true }, // AnimationEffect_FADE_FROM_CENTER
70
    { EK_move, ED_from_left,        -1, true }, // AnimationEffect_MOVE_FROM_LEFT
71
    { EK_move, ED_from_top,         -1, true }, // AnimationEffect_MOVE_FROM_TOP
72
    { EK_move, ED_from_right,       -1, true }, // AnimationEffect_MOVE_FROM_RIGHT
73
    { EK_move, ED_from_bottom,      -1, true }, // AnimationEffect_MOVE_FROM_BOTTOM
74
    { EK_stripes, ED_vertical,      -1, true }, // AnimationEffect_VERTICAL_STRIPES
75
    { EK_stripes, ED_horizontal,    -1, true }, // AnimationEffect_HORIZONTAL_STRIPES
76
    { EK_fade, ED_clockwise,        -1, true }, // AnimationEffect_CLOCKWISE
77
    { EK_fade, ED_cclockwise,       -1, true }, // AnimationEffect_COUNTERCLOCKWISE
78
    { EK_fade, ED_from_upperleft,   -1, true }, // AnimationEffect_FADE_FROM_UPPERLEFT
79
    { EK_fade, ED_from_upperright,  -1, true }, // AnimationEffect_FADE_FROM_UPPERRIGHT
80
    { EK_fade, ED_from_lowerleft,   -1, true }, // AnimationEffect_FADE_FROM_LOWERLEFT
81
    { EK_fade, ED_from_lowerright,  -1, true }, // AnimationEffect_FADE_FROM_LOWERRIGHT
82
    { EK_close,ED_vertical,         -1, true }, // AnimationEffect_CLOSE_VERTICAL
83
    { EK_close,ED_horizontal,       -1, true }, // AnimationEffect_CLOSE_HORIZONTAL
84
    { EK_open, ED_vertical,         -1, true }, // AnimationEffect_OPEN_VERTICAL
85
    { EK_open, ED_horizontal,       -1, true }, // AnimationEffect_OPEN_HORIZONTAL
86
    { EK_move, ED_path,             -1, true }, // AnimationEffect_PATH
87
    { EK_move, ED_to_left,          -1, false },// AnimationEffect_MOVE_TO_LEFT
88
    { EK_move, ED_to_top,           -1, false },// AnimationEffect_MOVE_TO_TOP
89
    { EK_move, ED_to_right,         -1, false },// AnimationEffect_MOVE_TO_RIGHT
90
    { EK_move, ED_to_bottom,        -1, false },// AnimationEffect_MOVE_TO_BOTTOM
91
    { EK_fade, ED_spiral_inward_left,   -1, true }, // AnimationEffect_SPIRALIN_LEFT
92
    { EK_fade, ED_spiral_inward_right,  -1, true }, // AnimationEffect_SPIRALIN_RIGHT
93
    { EK_fade, ED_spiral_outward_left,  -1, true }, // AnimationEffect_SPIRALOUT_LEFT
94
    { EK_fade, ED_spiral_outward_right, -1, true }, // AnimationEffect_SPIRALOUT_RIGHT
95
    { EK_dissolve, ED_none,         -1, true }, // AnimationEffect_DISSOLVE
96
    { EK_wavyline, ED_from_left,    -1, true }, // AnimationEffect_WAVYLINE_FROM_LEFT
97
    { EK_wavyline, ED_from_top,     -1, true }, // AnimationEffect_WAVYLINE_FROM_TOP
98
    { EK_wavyline, ED_from_right,   -1, true }, // AnimationEffect_WAVYLINE_FROM_RIGHT
99
    { EK_wavyline, ED_from_bottom,  -1, true }, // AnimationEffect_WAVYLINE_FROM_BOTTOM
100
    { EK_random, ED_none,           -1, true }, // AnimationEffect_RANDOM
101
    { EK_lines, ED_vertical,        -1, true }, // AnimationEffect_VERTICAL_LINES
102
    { EK_lines, ED_horizontal,      -1, true }, // AnimationEffect_HORIZONTAL_LINES
103
    { EK_laser, ED_from_left,       -1, true }, // AnimationEffect_LASER_FROM_LEFT
104
    { EK_laser, ED_from_top,        -1, true }, // AnimationEffect_LASER_FROM_TOP
105
    { EK_laser, ED_from_right,      -1, true }, // AnimationEffect_LASER_FROM_RIGHT
106
    { EK_laser, ED_from_bottom,     -1, true }, // AnimationEffect_LASER_FROM_BOTTOM
107
    { EK_laser, ED_from_upperleft,  -1, true }, // AnimationEffect_LASER_FROM_UPPERLEFT
108
    { EK_laser, ED_from_upperright, -1, true }, // AnimationEffect_LASER_FROM_UPPERRIGHT
109
    { EK_laser, ED_from_lowerleft,  -1, true }, // AnimationEffect_LASER_FROM_LOWERLEFT
110
    { EK_laser, ED_from_lowerright, -1, true }, // AnimationEffect_LASER_FROM_LOWERRIGHT
111
    { EK_appear,ED_none,            -1, true }, // AnimationEffect_APPEAR
112
    { EK_hide,  ED_none,            -1, false },// AnimationEffect_HIDE
113
    { EK_move,  ED_from_upperleft,  -1, true }, // AnimationEffect_MOVE_FROM_UPPERLEFT
114
    { EK_move,  ED_from_upperright, -1, true }, // AnimationEffect_MOVE_FROM_UPPERRIGHT
115
    { EK_move,  ED_from_lowerright, -1, true }, // AnimationEffect_MOVE_FROM_LOWERRIGHT
116
    { EK_move,  ED_from_lowerleft,  -1, true }, // AnimationEffect_MOVE_FROM_LOWERLEFT
117
    { EK_move,  ED_to_upperleft,    -1, false },// AnimationEffect_MOVE_TO_UPPERLEFT
118
    { EK_move,  ED_to_upperright,   -1, false },// AnimationEffect_MOVE_TO_UPPERRIGHT
119
    { EK_move,  ED_to_lowerright,   -1, false },// AnimationEffect_MOVE_TO_LOWERRIGHT
120
    { EK_move,  ED_to_lowerleft,    -1, false },// AnimationEffect_MOVE_TO_LOWERLEFT
121
    { EK_move_short, ED_from_left,  -1, true }, // AnimationEffect_MOVE_SHORT_FROM_LEFT
122
    { EK_move_short, ED_from_upperleft, -1, true }, // AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT
123
    { EK_move_short, ED_from_top,       -1, true }, // AnimationEffect_MOVE_SHORT_FROM_TOP
124
    { EK_move_short, ED_from_upperright,-1, true }, // AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT
125
    { EK_move_short, ED_from_right,     -1, true }, // AnimationEffect_MOVE_SHORT_FROM_RIGHT
126
    { EK_move_short, ED_from_lowerright,-1, true }, // AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT
127
    { EK_move_short, ED_from_bottom,    -1, true }, // AnimationEffect_MOVE_SHORT_FROM_BOTTOM
128
    { EK_move_short, ED_from_lowerleft, -1, true }, // AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT
129
    { EK_move_short, ED_to_left,        -1, false },// AnimationEffect_MOVE_SHORT_TO_LEFT
130
    { EK_move_short, ED_to_upperleft,   -1, false },// AnimationEffect_MOVE_SHORT_TO_UPPERLEFT
131
    { EK_move_short, ED_to_top,         -1, false },// AnimationEffect_MOVE_SHORT_TO_TOP
132
    { EK_move_short, ED_to_upperright,  -1, false },// AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT
133
    { EK_move_short, ED_to_right,       -1, false },// AnimationEffect_MOVE_SHORT_TO_RIGHT
134
    { EK_move_short, ED_to_lowerright,  -1, false },// AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT
135
    { EK_move_short, ED_to_bottom,      -1, false },// AnimationEffect_MOVE_SHORT_TO_BOTTOM
136
    { EK_move_short, ED_to_lowerleft,   -1, false },// AnimationEffect_MOVE_SHORT_TO_LOWERLEFT
137
    { EK_checkerboard, ED_vertical,     -1, true }, // AnimationEffect_VERTICAL_CHECKERBOARD
138
    { EK_checkerboard, ED_horizontal,   -1, true }, // AnimationEffect_HORIZONTAL_CHECKERBOARD
139
    { EK_rotate, ED_horizontal,     -1, true }, // AnimationEffect_HORIZONTAL_ROTATE
140
    { EK_rotate, ED_vertical,       -1, true }, // AnimationEffect_VERTICAL_ROTATE
141
    { EK_stretch,ED_horizontal,     -1, true }, // AnimationEffect_HORIZONTAL_STRETCH
142
    { EK_stretch,ED_vertical,       -1, true }, // AnimationEffect_VERTICAL_STRETCH
143
    { EK_stretch,ED_from_left,      -1, true }, // AnimationEffect_STRETCH_FROM_LEFT
144
    { EK_stretch,ED_from_upperleft, -1, true }, // AnimationEffect_STRETCH_FROM_UPPERLEFT
145
    { EK_stretch,ED_from_top,       -1, true }, // AnimationEffect_STRETCH_FROM_TOP
146
    { EK_stretch,ED_from_upperright,-1, true }, // AnimationEffect_STRETCH_FROM_UPPERRIGHT
147
    { EK_stretch,ED_from_right,     -1, true }, // AnimationEffect_STRETCH_FROM_RIGHT
148
    { EK_stretch,ED_from_lowerright,-1, true }, // AnimationEffect_STRETCH_FROM_LOWERRIGHT
149
    { EK_stretch,ED_from_bottom,    -1, true }, // AnimationEffect_STRETCH_FROM_BOTTOM
150
    { EK_stretch,ED_from_lowerleft, -1, true }, // AnimationEffect_STRETCH_FROM_LOWERLEFT
151
    { EK_move,  ED_none,             0, true }, // AnimationEffect_ZOOM_IN
152
    { EK_move,  ED_none,            50, true }, // AnimationEffect_ZOOM_IN_SMALL
153
    { EK_move,  ED_spiral_inward_left,   0, true }, // AnimationEffect_ZOOM_IN_SPIRAL
154
    { EK_move,  ED_none,           400, true }, // AnimationEffect_ZOOM_OUT
155
    { EK_move,  ED_none,           200, true }, // AnimationEffect_ZOOM_OUT_SMALL
156
    { EK_move,  ED_spiral_inward_left, 400, true }, // AnimationEffect_ZOOM_OUT_SPIRAL
157
    { EK_move,  ED_from_left,        0, true }, // AnimationEffect_ZOOM_IN_FROM_LEFT
158
    { EK_move,  ED_from_upperleft,   0, true }, // AnimationEffect_ZOOM_IN_FROM_UPPERLEFT
159
    { EK_move,  ED_from_top,         0, true }, // AnimationEffect_ZOOM_IN_FROM_TOP
160
    { EK_move,  ED_from_upperright,  0, true }, // AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT
161
    { EK_move,  ED_from_right,       0, true }, // AnimationEffect_ZOOM_IN_FROM_RIGHT
162
    { EK_move,  ED_from_lowerright,  0, true }, // AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT
163
    { EK_move,  ED_from_bottom,      0, true }, // AnimationEffect_ZOOM_IN_FROM_BOTTOM
164
    { EK_move,  ED_from_lowerleft,   0, true }, // AnimationEffect_ZOOM_IN_FROM_LOWERLEFT
165
    { EK_move,  ED_from_center,      0, true }, // AnimationEffect_ZOOM_IN_FROM_CENTER
166
    { EK_move,  ED_from_left,      400, true }, // AnimationEffect_ZOOM_OUT_FROM_LEFT
167
    { EK_move,  ED_from_upperleft, 400, true }, // AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT
168
    { EK_move,  ED_from_top,       400, true }, // AnimationEffect_ZOOM_OUT_FROM_TOP
169
    { EK_move,  ED_from_upperright,400, true }, // AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT
170
    { EK_move,  ED_from_right,     400, true }, // AnimationEffect_ZOOM_OUT_FROM_RIGHT
171
    { EK_move,  ED_from_lowerright,400, true }, // AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT
172
    { EK_move,  ED_from_bottom,    400, true }, // AnimationEffect_ZOOM_OUT_FROM_BOTTOM
173
    { EK_move,  ED_from_lowerleft, 400, true }, // AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT
174
    { EK_move,  ED_from_center,    400, true }  // AnimationEffect_ZOOM_OUT_FROM_CENTER
175
};
176
177
void SdXMLImplSetEffect( AnimationEffect eEffect, XMLEffect& eKind, XMLEffectDirection& eDirection, sal_Int16& nStartScale, bool& bIn )
178
0
{
179
0
    if( eEffect < AnimationEffect_NONE || eEffect > AnimationEffect_ZOOM_OUT_FROM_CENTER )
180
0
    {
181
0
        OSL_FAIL( "unknown animation effect!" );
182
0
        eEffect = AnimationEffect_NONE;
183
0
    }
184
185
0
    const Effect& rEffect = AnimationEffectMap[static_cast<int>(eEffect)];
186
0
    eKind = rEffect.meKind;
187
0
    eDirection = rEffect.meDirection;
188
0
    nStartScale = rEffect.mnStartScale;
189
0
    bIn = rEffect.mbIn;
190
0
}
191
192
namespace {
193
194
enum XMLActionKind : sal_Int8
195
{
196
    XMLE_SHOW,
197
    XMLE_HIDE,
198
    XMLE_DIM,
199
    XMLE_PLAY
200
};
201
202
struct XMLEffectHint
203
{
204
    Reference<XShape> mxShape;
205
    XMLActionKind   meKind;
206
    bool            mbTextEffect;
207
208
    XMLEffect       meEffect;
209
    XMLEffectDirection  meDirection;
210
    sal_Int16       mnStartScale;
211
212
    AnimationSpeed  meSpeed;
213
    OUString        maSoundURL;
214
    sal_Int32       maDimColor;
215
    sal_Int32       mnPresId;
216
    bool        mbPlayFull;
217
218
0
    bool operator<(const XMLEffectHint& rComp) const { return mnPresId < rComp.mnPresId; }
219
220
    XMLEffectHint()
221
0
    :   meKind( XMLE_SHOW ), mbTextEffect( false ),
222
0
        meEffect( EK_none ), meDirection( ED_none ), mnStartScale( -1 ),
223
0
        meSpeed( AnimationSpeed_SLOW ), maDimColor(0),
224
0
        mnPresId( 0 ), mbPlayFull( false )
225
0
        {}
226
};
227
228
}
229
230
class AnimExpImpl
231
{
232
public:
233
    std::list<XMLEffectHint> maEffects;
234
235
    static constexpr OUString gsDimColor = u"DimColor"_ustr;
236
    static constexpr OUString gsDimHide = u"DimHide"_ustr;
237
    static constexpr OUString gsDimPrev = u"DimPrevious"_ustr;
238
    static constexpr OUString gsEffect = u"Effect"_ustr;
239
    static constexpr OUString gsPlayFull = u"PlayFull"_ustr;
240
    static constexpr OUString gsPresOrder = u"PresentationOrder"_ustr;
241
    static constexpr OUString gsSound = u"Sound"_ustr;
242
    static constexpr OUString gsSoundOn = u"SoundOn"_ustr;
243
    static constexpr OUString gsSpeed = u"Speed"_ustr;
244
    static constexpr OUString gsTextEffect = u"TextEffect"_ustr;
245
    static constexpr OUString gsIsAnimation = u"IsAnimation"_ustr;
246
    static constexpr OUString gsAnimPath = u"AnimationPath"_ustr;
247
};
248
249
XMLAnimationsExporter::XMLAnimationsExporter()
250
0
    : mpImpl( new AnimExpImpl )
251
0
{
252
0
}
253
254
XMLAnimationsExporter::~XMLAnimationsExporter()
255
0
{
256
0
}
257
258
void XMLAnimationsExporter::prepare( const Reference< XShape >& xShape )
259
0
{
260
0
    try
261
0
    {
262
        // check for presentation shape service
263
0
        {
264
0
            Reference< XServiceInfo > xServiceInfo( xShape, UNO_QUERY );
265
0
            if( !xServiceInfo.is() || !xServiceInfo->supportsService(u"com.sun.star.presentation.Shape"_ustr) )
266
0
                return;
267
0
        }
268
269
0
        Reference< XPropertySet > xProps( xShape, UNO_QUERY );
270
0
        if( xProps.is() )
271
0
        {
272
0
            AnimationEffect eEffect;
273
0
            xProps->getPropertyValue( AnimExpImpl::gsEffect ) >>= eEffect;
274
0
            if( eEffect == AnimationEffect_PATH )
275
0
            {
276
0
                Reference< XShape > xPath;
277
0
                xProps->getPropertyValue( AnimExpImpl::gsAnimPath ) >>= xPath;
278
0
            }
279
0
        }
280
0
    }
281
0
    catch (const Exception&)
282
0
    {
283
0
        TOOLS_WARN_EXCEPTION("xmloff.draw",
284
0
                             "exception caught while collection animation information!");
285
0
    }
286
0
}
287
288
void XMLAnimationsExporter::collect( const Reference< XShape >& xShape, SvXMLExport& rExport )
289
0
{
290
0
    try
291
0
    {
292
        // check for presentation shape service
293
0
        {
294
0
            Reference< XServiceInfo > xServiceInfo( xShape, UNO_QUERY );
295
0
            if( !xServiceInfo.is() || !xServiceInfo->supportsService(u"com.sun.star.presentation.Shape"_ustr) )
296
0
                return;
297
0
        }
298
299
0
        Reference< XPropertySet > xProps( xShape, UNO_QUERY );
300
0
        if( xProps.is() )
301
0
        {
302
0
            XMLEffectHint aEffect;
303
304
0
            if( any2bool( xProps->getPropertyValue( AnimExpImpl::gsSoundOn ) ) )
305
0
            {
306
0
                xProps->getPropertyValue( AnimExpImpl::gsSound ) >>= aEffect.maSoundURL;
307
0
                xProps->getPropertyValue( AnimExpImpl::gsPlayFull ) >>= aEffect.mbPlayFull;
308
0
            }
309
310
0
            xProps->getPropertyValue( AnimExpImpl::gsPresOrder ) >>= aEffect.mnPresId;
311
0
            xProps->getPropertyValue( AnimExpImpl::gsSpeed ) >>= aEffect.meSpeed;
312
313
314
0
            bool bIsAnimation = false;
315
0
            xProps->getPropertyValue( AnimExpImpl::gsIsAnimation ) >>= bIsAnimation;
316
0
            if( bIsAnimation )
317
0
            {
318
0
                aEffect.meKind = XMLE_PLAY;
319
320
0
                if( !aEffect.mxShape.is() )
321
0
                {
322
0
                    rExport.getInterfaceToIdentifierMapper().registerReference( xShape );
323
0
                    aEffect.mxShape = xShape;
324
0
                }
325
326
0
                mpImpl->maEffects.push_back( aEffect );
327
0
            }
328
329
0
            {
330
0
                AnimationEffect eEffect;
331
0
                xProps->getPropertyValue( AnimExpImpl::gsEffect ) >>= eEffect;
332
0
                if( eEffect != AnimationEffect_NONE )
333
0
                {
334
0
                    bool bIn = true;
335
0
                    SdXMLImplSetEffect( eEffect, aEffect.meEffect, aEffect.meDirection, aEffect.mnStartScale, bIn );
336
337
0
                    aEffect.meKind = bIn ? XMLE_SHOW : XMLE_HIDE;
338
339
0
                    if( !aEffect.mxShape.is() )
340
0
                    {
341
0
                        rExport.getInterfaceToIdentifierMapper().registerReference( xShape );
342
0
                        aEffect.mxShape = xShape;
343
0
                    }
344
345
0
                    if( eEffect == AnimationEffect_PATH )
346
0
                    {
347
0
                        Reference< XShape > xPath;
348
0
                        xProps->getPropertyValue( AnimExpImpl::gsAnimPath ) >>= xPath;
349
0
                        if( xPath.is() )
350
0
                        {
351
// strip                    mpImpl->mxShapeExp->createShapeId( xPath );
352
// strip                    aEffect.mnPathShapeId = mpImpl->mxShapeExp->getShapeId( xPath );
353
0
                        }
354
0
                    }
355
0
                    mpImpl->maEffects.push_back( aEffect );
356
357
0
                    aEffect.maSoundURL.clear();
358
0
                }
359
360
0
                xProps->getPropertyValue( AnimExpImpl::gsTextEffect ) >>= eEffect;
361
0
                if( eEffect != AnimationEffect_NONE )
362
0
                {
363
0
                    bool bIn = true;
364
0
                    SdXMLImplSetEffect( eEffect, aEffect.meEffect, aEffect.meDirection, aEffect.mnStartScale, bIn );
365
0
                    aEffect.meKind = bIn ? XMLE_SHOW : XMLE_HIDE;
366
0
                    aEffect.mbTextEffect = true;
367
368
0
                    if( !aEffect.mxShape.is() )
369
0
                    {
370
0
                        rExport.getInterfaceToIdentifierMapper().registerReference( xShape );
371
0
                        aEffect.mxShape = xShape;
372
0
                    }
373
374
0
                    mpImpl->maEffects.push_back( aEffect );
375
0
                    aEffect.mbTextEffect = false;
376
0
                    aEffect.maSoundURL.clear();
377
0
                }
378
379
0
                bool bDimPrev = false;
380
0
                bool bDimHide = false;
381
0
                xProps->getPropertyValue( AnimExpImpl::gsDimPrev ) >>= bDimPrev;
382
0
                xProps->getPropertyValue( AnimExpImpl::gsDimHide ) >>= bDimHide;
383
0
                if( bDimPrev || bDimHide )
384
0
                {
385
0
                    aEffect.meKind = bDimPrev ? XMLE_DIM : XMLE_HIDE;
386
0
                    aEffect.meEffect = EK_none;
387
0
                    aEffect.meDirection = ED_none;
388
0
                    aEffect.meSpeed = AnimationSpeed_MEDIUM;
389
0
                    if( bDimPrev )
390
0
                    {
391
0
                        xProps->getPropertyValue( AnimExpImpl::gsDimColor )
392
0
                            >>= aEffect.maDimColor;
393
0
                    }
394
395
0
                    if( !aEffect.mxShape.is() )
396
0
                    {
397
0
                        rExport.getInterfaceToIdentifierMapper().registerReference( xShape );
398
0
                        aEffect.mxShape = xShape;
399
0
                    }
400
401
0
                    mpImpl->maEffects.push_back( aEffect );
402
0
                    aEffect.maSoundURL.clear();
403
0
                }
404
0
            }
405
0
        }
406
0
    }
407
0
    catch (const Exception&)
408
0
    {
409
0
        TOOLS_WARN_EXCEPTION("xmloff.draw",
410
0
                             "exception caught while collection animation information!");
411
0
    }
412
0
}
413
414
void XMLAnimationsExporter::exportAnimations( SvXMLExport& rExport )
415
0
{
416
0
    mpImpl->maEffects.sort();
417
418
0
    OUStringBuffer sTmp;
419
420
0
    if( !mpImpl->maEffects.empty() )
421
0
    {
422
0
        SvXMLElementExport aElement( rExport, XML_NAMESPACE_PRESENTATION, XML_ANIMATIONS, true, true );
423
424
0
        for (const auto& rEffect : mpImpl->maEffects)
425
0
        {
426
0
            SAL_WARN_IF( !rEffect.mxShape.is(), "xmloff", "shape id creation failed for animation effect?" );
427
428
0
            rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_SHAPE_ID, rExport.getInterfaceToIdentifierMapper().getIdentifier( rEffect.mxShape ) );
429
430
0
            if( rEffect.meKind == XMLE_DIM )
431
0
            {
432
                // export a dim action;
433
434
0
                ::sax::Converter::convertColor( sTmp, rEffect.maDimColor );
435
0
                rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_COLOR, sTmp.makeStringAndClear() );
436
437
0
                SvXMLElementExport aElem( rExport, XML_NAMESPACE_PRESENTATION, XML_DIM, true, true );
438
0
            }
439
0
            else if( rEffect.meKind == XMLE_PLAY )
440
0
            {
441
0
                if( rEffect.meSpeed != AnimationSpeed_MEDIUM )
442
0
                {
443
0
                    SvXMLUnitConverter::convertEnum( sTmp, rEffect.meSpeed, aXML_AnimationSpeed_EnumMap );
444
0
                    rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SPEED, sTmp.makeStringAndClear() );
445
0
                }
446
447
0
                SvXMLElementExport aElem( rExport, XML_NAMESPACE_PRESENTATION, XML_PLAY, true, true );
448
0
            }
449
0
            else
450
0
            {
451
452
0
                if( rEffect.meEffect != EK_none )
453
0
                {
454
0
                    SvXMLUnitConverter::convertEnum( sTmp, rEffect.meEffect, aXML_AnimationEffect_EnumMap );
455
0
                    rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_EFFECT, sTmp.makeStringAndClear() );
456
0
                }
457
458
0
                if( rEffect.meDirection != ED_none )
459
0
                {
460
0
                    SvXMLUnitConverter::convertEnum( sTmp, rEffect.meDirection, aXML_AnimationDirection_EnumMap );
461
0
                    rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_DIRECTION, sTmp.makeStringAndClear() );
462
0
                }
463
464
0
                if( rEffect.mnStartScale != -1 )
465
0
                {
466
0
                    ::sax::Converter::convertPercent(sTmp, rEffect.mnStartScale);
467
0
                    rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_START_SCALE, sTmp.makeStringAndClear() );
468
0
                }
469
470
0
                if( rEffect.meSpeed != AnimationSpeed_MEDIUM )
471
0
                {
472
0
                    SvXMLUnitConverter::convertEnum( sTmp, rEffect.meSpeed, aXML_AnimationSpeed_EnumMap );
473
0
                    rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SPEED, sTmp.makeStringAndClear() );
474
0
                }
475
476
0
                enum XMLTokenEnum eLocalName;
477
0
                if( rEffect.meKind == XMLE_SHOW )
478
0
                {
479
0
                    if( rEffect.mbTextEffect )
480
0
                        eLocalName = XML_SHOW_TEXT;
481
0
                    else
482
0
                        eLocalName = XML_SHOW_SHAPE;
483
0
                }
484
0
                else
485
0
                {
486
0
                    if( rEffect.mbTextEffect )
487
0
                        eLocalName = XML_HIDE_TEXT;
488
0
                    else
489
0
                        eLocalName = XML_HIDE_SHAPE;
490
0
                }
491
492
0
                SvXMLElementExport aEle( rExport, XML_NAMESPACE_PRESENTATION, eLocalName, true, true );
493
0
                if( !rEffect.maSoundURL.isEmpty() )
494
0
                {
495
0
                    rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, rExport.GetRelativeReference(rEffect.maSoundURL) );
496
0
                    rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
497
0
                    rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_NEW );
498
0
                    rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
499
0
                    if( rEffect.mbPlayFull )
500
0
                        rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PLAY_FULL, XML_TRUE );
501
502
0
                    SvXMLElementExport aElem( rExport, XML_NAMESPACE_PRESENTATION, XML_SOUND, true, true );
503
0
                }
504
0
            }
505
0
        }
506
0
    }
507
508
0
    mpImpl->maEffects.clear();
509
0
}
510
511
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */