1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <com/sun/star/animations/XAnimationNode.hpp>
23 #include <com/sun/star/animations/XTimeContainer.hpp>
24 #include <com/sun/star/animations/XAudio.hpp>
25 #include <com/sun/star/drawing/XShape.hpp>
26 #include <com/sun/star/util/XChangesListener.hpp>
27 #include <rtl/ref.hxx>
28 #include <vcl/timer.hxx>
29 #include <tools/long.hxx>
41 enum class EValue
{ To
, By
};
43 class CustomAnimationEffect
;
45 class CustomAnimationPreset
;
46 typedef std::shared_ptr
< CustomAnimationPreset
> CustomAnimationPresetPtr
;
48 typedef std::shared_ptr
< CustomAnimationEffect
> CustomAnimationEffectPtr
;
50 typedef std::list
< CustomAnimationEffectPtr
> EffectSequence
;
52 class EffectSequenceHelper
;
54 class CustomAnimationEffect final
56 friend class MainSequence
;
57 friend class EffectSequenceHelper
;
60 CustomAnimationEffect( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
);
61 ~CustomAnimationEffect();
63 const css::uno::Reference
< css::animations::XAnimationNode
>& getNode() const { return mxNode
; }
64 void setNode( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
);
65 void replaceNode( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
);
67 CustomAnimationEffectPtr
clone() const;
70 const OUString
& getPresetId() const { return maPresetId
; }
71 const OUString
& getPresetSubType() const { return maPresetSubType
; }
72 const OUString
& getProperty() const { return maProperty
; }
74 sal_Int16
getPresetClass() const { return mnPresetClass
; }
75 void setPresetClassAndId( sal_Int16 nPresetClass
, const OUString
& rPresetId
);
77 sal_Int16
getNodeType() const { return mnNodeType
; }
78 void setNodeType( sal_Int16 nNodeType
);
80 css::uno::Any
getRepeatCount() const;
81 void setRepeatCount( const css::uno::Any
& rRepeatCount
);
83 css::uno::Any
getEnd() const;
84 void setEnd( const css::uno::Any
& rEnd
);
86 sal_Int16
getFill() const { return mnFill
; }
87 void setFill( sal_Int16 nFill
);
89 double getBegin() const { return mfBegin
; }
90 void setBegin( double fBegin
);
92 double getDuration() const { return mfDuration
; }
93 void setDuration( double fDuration
);
95 double getAbsoluteDuration() const { return mfAbsoluteDuration
; }
97 sal_Int16
getIterateType() const { return mnIterateType
; }
98 void setIterateType( sal_Int16 nIterateType
);
100 double getIterateInterval() const { return mfIterateInterval
; }
101 void setIterateInterval( double fIterateInterval
);
103 const css::uno::Any
& getTarget() const { return maTarget
; }
104 void setTarget( const css::uno::Any
& rTarget
);
106 bool hasAfterEffect() const { return mbHasAfterEffect
; }
107 void setHasAfterEffect( bool bHasAfterEffect
) { mbHasAfterEffect
= bHasAfterEffect
; }
109 const css::uno::Any
& getDimColor() const { return maDimColor
; }
110 void setDimColor( const css::uno::Any
& rDimColor
) { maDimColor
= rDimColor
; }
112 bool IsAfterEffectOnNext() const { return mbAfterEffectOnNextEffect
; }
113 void setAfterEffectOnNext( bool bOnNextEffect
) { mbAfterEffectOnNextEffect
= bOnNextEffect
; }
115 sal_Int32
getParaDepth() const { return mnParaDepth
; }
117 bool hasText() const { return mbHasText
; }
119 sal_Int16
getCommand() const { return mnCommand
; }
121 double getAcceleration() const { return mfAcceleration
; }
122 void setAcceleration( double fAcceleration
);
124 double getDecelerate() const { return mfDecelerate
; }
125 void setDecelerate( double fDecelerate
);
127 bool getAutoReverse() const { return mbAutoReverse
; }
128 void setAutoReverse( bool bAutoReverse
);
130 css::uno::Any
getProperty( sal_Int32 nNodeType
, std::u16string_view rAttributeName
, EValue eValue
);
131 bool setProperty( sal_Int32 nNodeType
, std::u16string_view rAttributeName
, EValue eValue
, const css::uno::Any
& rValue
);
133 css::uno::Any
getTransformationProperty( sal_Int32 nTransformType
, EValue eValue
);
134 bool setTransformationProperty( sal_Int32 nTransformType
, EValue eValue
, const css::uno::Any
& rValue
);
136 css::uno::Any
getColor( sal_Int32 nIndex
);
137 void setColor( sal_Int32 nIndex
, const css::uno::Any
& rColor
);
139 sal_Int32
getGroupId() const { return mnGroupId
; }
140 void setGroupId( sal_Int32 nGroupId
);
142 sal_Int16
getTargetSubItem() const { return mnTargetSubItem
; }
143 void setTargetSubItem( sal_Int16 nSubItem
);
145 OUString
getPath() const;
146 void setPath( const OUString
& rPath
);
148 bool checkForText( const std::vector
<sal_Int32
>* paragraphNumberingLevel
= nullptr );
149 bool calculateIterateDuration();
151 void setAudio( const css::uno::Reference
< css::animations::XAudio
>& xAudio
);
152 bool getStopAudio() const;
154 void createAudio( const css::uno::Any
& rSource
);
156 const css::uno::Reference
< css::animations::XAudio
>& getAudio() const { return mxAudio
; }
158 EffectSequenceHelper
* getEffectSequence() const { return mpEffectSequence
; }
161 /// @throws css::uno::Exception
162 css::uno::Reference
< css::animations::XAnimationNode
> createAfterEffectNode() const;
163 css::uno::Reference
< css::drawing::XShape
> getTargetShape() const;
166 static sal_Int32
get_node_type( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
);
167 static sal_Int32
getNumberOfSubitems( const css::uno::Any
& aTarget
, sal_Int16 nIterateType
);
169 rtl::Reference
<SdrPathObj
> createSdrPathObjFromPath(SdrModel
& rTargetModel
);
170 void updateSdrPathObjFromPath( SdrPathObj
& rPathObj
);
171 void updatePathFromSdrPathObj( const SdrPathObj
& rPathObj
);
174 void setEffectSequence( EffectSequenceHelper
* pSequence
) { mpEffectSequence
= pSequence
; }
176 sal_Int16 mnNodeType
;
178 OUString maPresetSubType
;
180 sal_Int16 mnPresetClass
;
183 double mfDuration
; // this is the maximum duration of the subeffects
184 double mfAbsoluteDuration
; // this is the maximum duration of the subeffects including possible iterations
186 sal_Int16 mnIterateType
;
187 double mfIterateInterval
;
188 sal_Int32 mnParaDepth
;
190 double mfAcceleration
;
193 sal_Int16 mnTargetSubItem
;
196 EffectSequenceHelper
* mpEffectSequence
;
198 css::uno::Reference
< css::animations::XAnimationNode
> mxNode
;
199 css::uno::Reference
< css::animations::XAudio
> mxAudio
;
200 css::uno::Any maTarget
;
202 bool mbHasAfterEffect
;
203 css::uno::Any maDimColor
;
204 bool mbAfterEffectOnNextEffect
;
207 struct stl_CustomAnimationEffect_search_node_predict
209 stl_CustomAnimationEffect_search_node_predict( const css::uno::Reference
< css::animations::XAnimationNode
>& xSearchNode
);
210 bool operator()( const CustomAnimationEffectPtr
& pEffect
) const;
211 const css::uno::Reference
< css::animations::XAnimationNode
>& mxSearchNode
;
214 /** this listener is implemented by UI components to track changes in the animation core */
215 class ISequenceListener
218 virtual void notify_change() = 0;
221 ~ISequenceListener() {}
224 /** this class keeps track of a group of animations that build up
225 a text animation for a single shape */
226 class CustomAnimationTextGroup
228 friend class EffectSequenceHelper
;
231 CustomAnimationTextGroup( const css::uno::Reference
< css::drawing::XShape
>& rTarget
, sal_Int32 nGroupId
);
234 void addEffect( CustomAnimationEffectPtr
const & pEffect
);
236 const EffectSequence
& getEffects() const { return maEffects
; }
238 /* -1: as single object, 0: all at once, n > 0: by n Th paragraph */
239 sal_Int32
getTextGrouping() const { return mnTextGrouping
; }
241 bool getAnimateForm() const { return mbAnimateForm
; }
242 bool getTextReverse() const { return mbTextReverse
; }
243 double getTextGroupingAuto() const { return mfGroupingAuto
; }
246 EffectSequence maEffects
;
247 css::uno::Reference
< css::drawing::XShape
> maTarget
;
249 enum { PARA_LEVELS
= 5 };
251 sal_Int32 mnTextGrouping
;
254 double mfGroupingAuto
;
255 sal_Int32 mnLastPara
;
256 sal_Int8 mnDepthFlags
[PARA_LEVELS
];
260 typedef std::shared_ptr
< CustomAnimationTextGroup
> CustomAnimationTextGroupPtr
;
261 typedef std::map
< sal_Int32
, CustomAnimationTextGroupPtr
> CustomAnimationTextGroupMap
;
263 class SD_DLLPUBLIC EffectSequenceHelper
265 friend class MainSequence
;
268 SAL_DLLPRIVATE
EffectSequenceHelper();
269 SAL_DLLPRIVATE
EffectSequenceHelper( css::uno::Reference
< css::animations::XTimeContainer
> xSequenceRoot
);
270 SAL_DLLPRIVATE
virtual ~EffectSequenceHelper();
272 SAL_DLLPRIVATE
virtual css::uno::Reference
< css::animations::XAnimationNode
> getRootNode();
274 SAL_DLLPRIVATE CustomAnimationEffectPtr
append( const CustomAnimationPresetPtr
& pDescriptor
, const css::uno::Any
& rTarget
, double fDuration
);
275 SAL_DLLPRIVATE CustomAnimationEffectPtr
append( const SdrPathObj
& rPathObj
, const css::uno::Any
& rTarget
, double fDuration
, const OUString
& rPresetId
);
276 void append( const CustomAnimationEffectPtr
& pEffect
);
277 SAL_DLLPRIVATE
void replace( const CustomAnimationEffectPtr
& pEffect
, const CustomAnimationPresetPtr
& pDescriptor
, double fDuration
);
278 SAL_DLLPRIVATE
void replace( const CustomAnimationEffectPtr
& pEffect
, const CustomAnimationPresetPtr
& pDescriptor
, const OUString
& rPresetSubType
, double fDuration
);
279 SAL_DLLPRIVATE
void remove( const CustomAnimationEffectPtr
& pEffect
);
280 SAL_DLLPRIVATE
void moveToBeforeEffect( const CustomAnimationEffectPtr
& pEffect
, const CustomAnimationEffectPtr
& pInsertBefore
);
282 SAL_DLLPRIVATE
void create( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
);
283 SAL_DLLPRIVATE
void createEffectsequence( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
);
284 SAL_DLLPRIVATE
void processAfterEffect( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
);
285 SAL_DLLPRIVATE
void createEffects( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
);
287 SAL_DLLPRIVATE sal_Int32
getCount() const { return sal::static_int_cast
< sal_Int32
>( maEffects
.size() ); }
289 SAL_DLLPRIVATE
virtual CustomAnimationEffectPtr
findEffect( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
) const;
291 SAL_DLLPRIVATE
virtual bool disposeShape( const css::uno::Reference
< css::drawing::XShape
>& xShape
);
292 SAL_DLLPRIVATE
virtual void insertTextRange( const css::uno::Any
& aTarget
);
293 SAL_DLLPRIVATE
virtual void disposeTextRange( const css::uno::Any
& aTarget
);
294 SAL_DLLPRIVATE
virtual bool hasEffect( const css::uno::Reference
< css::drawing::XShape
>& xShape
);
295 SAL_DLLPRIVATE
virtual void onTextChanged( const css::uno::Reference
< css::drawing::XShape
>& xShape
);
297 /** this method rebuilds the animation nodes */
298 SAL_DLLPRIVATE
virtual void rebuild();
300 SAL_DLLPRIVATE
EffectSequence::iterator
getBegin() { return maEffects
.begin(); }
301 SAL_DLLPRIVATE
EffectSequence::iterator
getEnd() { return maEffects
.end(); }
302 SAL_DLLPRIVATE
EffectSequence::iterator
find( const CustomAnimationEffectPtr
& pEffect
);
304 SAL_DLLPRIVATE EffectSequence
& getSequence() { return maEffects
; }
306 SAL_DLLPRIVATE
void addListener( ISequenceListener
* pListener
);
307 SAL_DLLPRIVATE
void removeListener( ISequenceListener
* pListener
);
309 // text group methods
311 SAL_DLLPRIVATE CustomAnimationTextGroupPtr
findGroup( sal_Int32 nGroupId
);
312 CustomAnimationTextGroupPtr
createTextGroup(const CustomAnimationEffectPtr
& pEffect
,
313 sal_Int32 nTextGrouping
, double fTextGroupingAuto
,
314 bool bAnimateForm
, bool bTextReverse
);
315 SAL_DLLPRIVATE
void setTextGrouping( const CustomAnimationTextGroupPtr
& pTextGroup
, sal_Int32 nTextGrouping
);
316 SAL_DLLPRIVATE
void setAnimateForm( const CustomAnimationTextGroupPtr
& pTextGroup
, bool bAnimateForm
);
317 SAL_DLLPRIVATE
void setTextGroupingAuto( const CustomAnimationTextGroupPtr
& pTextGroup
, double fTextGroupingAuto
);
318 SAL_DLLPRIVATE
void setTextReverse( const CustomAnimationTextGroupPtr
& pTextGroup
, bool bAnimateForm
);
320 SAL_DLLPRIVATE sal_Int32
getSequenceType() const { return mnSequenceType
; }
322 SAL_DLLPRIVATE
const css::uno::Reference
< css::drawing::XShape
>& getTriggerShape() const { return mxEventSource
; }
323 SAL_DLLPRIVATE
void setTriggerShape( const css::uno::Reference
< css::drawing::XShape
>& xTrigger
) { mxEventSource
= xTrigger
; }
325 SAL_DLLPRIVATE
virtual sal_Int32
getOffsetFromEffect( const CustomAnimationEffectPtr
& xEffect
) const;
326 SAL_DLLPRIVATE
virtual CustomAnimationEffectPtr
getEffectFromOffset( sal_Int32 nOffset
) const;
329 SAL_DLLPRIVATE
virtual void implRebuild();
330 SAL_DLLPRIVATE
virtual void reset();
332 SAL_DLLPRIVATE
void createTextGroupParagraphEffects( const CustomAnimationTextGroupPtr
& pTextGroup
, const CustomAnimationEffectPtr
& pEffect
, bool bUsed
);
334 SAL_DLLPRIVATE
void notify_listeners();
336 SAL_DLLPRIVATE
void updateTextGroups();
338 SAL_DLLPRIVATE
bool getParagraphNumberingLevels( const css::uno::Reference
< css::drawing::XShape
>& xShape
, std::vector
< sal_Int32
>& rParagraphNumberingLevel
);
341 css::uno::Reference
< css::animations::XTimeContainer
> mxSequenceRoot
;
342 EffectSequence maEffects
;
343 std::list
< ISequenceListener
* > maListeners
;
344 CustomAnimationTextGroupMap maGroupMap
;
345 sal_Int32 mnSequenceType
;
346 css::uno::Reference
< css::drawing::XShape
> mxEventSource
;
351 class InteractiveSequence final
: public EffectSequenceHelper
353 friend class MainSequence
;
354 friend class MainSequenceChangeGuard
;
357 InteractiveSequence( const css::uno::Reference
< css::animations::XTimeContainer
>& xSequenceRoot
, MainSequence
* pMainSequence
);
359 /** this method rebuilds the animation nodes */
360 virtual void rebuild() override
;
363 virtual void implRebuild() override
;
365 MainSequence
* mpMainSequence
;
368 typedef std::shared_ptr
< InteractiveSequence
> InteractiveSequencePtr
;
369 typedef std::vector
< InteractiveSequencePtr
> InteractiveSequenceVector
;
371 class MainSequence final
: public EffectSequenceHelper
, public ISequenceListener
373 friend class UndoAnimation
;
374 friend class MainSequenceRebuildGuard
;
375 friend class MainSequenceChangeGuard
;
379 MainSequence( const css::uno::Reference
< css::animations::XAnimationNode
>& xTimingRootNode
);
380 virtual ~MainSequence() override
;
382 virtual css::uno::Reference
< css::animations::XAnimationNode
> getRootNode() override
;
383 void reset( const css::uno::Reference
< css::animations::XAnimationNode
>& xTimingRootNode
);
385 /** this method rebuilds the animation nodes */
386 virtual void rebuild() override
;
388 virtual CustomAnimationEffectPtr
findEffect( const css::uno::Reference
< css::animations::XAnimationNode
>& xNode
) const override
;
390 virtual bool disposeShape( const css::uno::Reference
< css::drawing::XShape
>& xShape
) override
;
391 virtual void insertTextRange( const css::uno::Any
& aTarget
) override
;
392 virtual void disposeTextRange( const css::uno::Any
& aTarget
) override
;
393 virtual bool hasEffect( const css::uno::Reference
< css::drawing::XShape
>& xShape
) override
;
394 virtual void onTextChanged( const css::uno::Reference
< css::drawing::XShape
>& xShape
) override
;
396 const InteractiveSequenceVector
& getInteractiveSequenceVector() const { return maInteractiveSequenceVector
; }
398 virtual void notify_change() override
;
400 bool setTrigger( const CustomAnimationEffectPtr
& pEffect
, const css::uno::Reference
< css::drawing::XShape
>& xTriggerShape
);
402 /** starts a timer that recreates the internal structure from the API core after 1 second */
403 void startRecreateTimer();
405 /** starts a timer that rebuilds the API core from the internal structure after 1 second */
406 void startRebuildTimer();
408 virtual sal_Int32
getOffsetFromEffect( const CustomAnimationEffectPtr
& xEffect
) const override
;
409 virtual CustomAnimationEffectPtr
getEffectFromOffset( sal_Int32 nOffset
) const override
;
412 /** permits rebuilds until unlockRebuilds() is called. All rebuild calls during a locked sequence are
413 process after unlockRebuilds() call. lockRebuilds() and unlockRebuilds() calls can be nested. */
415 void unlockRebuilds();
417 DECL_LINK(onTimerHdl
, Timer
*, void);
419 virtual void implRebuild() override
;
423 void createMainSequence();
424 virtual void reset() override
;
426 InteractiveSequencePtr
createInteractiveSequence( const css::uno::Reference
< css::drawing::XShape
>& xShape
);
428 InteractiveSequenceVector maInteractiveSequenceVector
;
430 css::uno::Reference
< css::util::XChangesListener
> mxChangesListener
;
431 css::uno::Reference
< css::animations::XTimeContainer
> mxTimingRootNode
;
436 ::tools::Long mnRebuildLockGuard
;
437 bool mbPendingRebuildRequest
;
438 sal_Int32 mbIgnoreChanges
;
441 typedef std::shared_ptr
< MainSequence
> MainSequencePtr
;
443 class MainSequenceRebuildGuard
446 MainSequenceRebuildGuard( MainSequencePtr pMainSequence
);
447 ~MainSequenceRebuildGuard();
450 MainSequencePtr mpMainSequence
;
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */