Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <tools/debug.hxx>
30 : : #include <com/sun/star/util/XCloneable.hpp>
31 : : #include <com/sun/star/animations/AnimationFill.hpp>
32 : : #include <com/sun/star/container/XEnumerationAccess.hpp>
33 : : #include <com/sun/star/presentation/EffectNodeType.hpp>
34 : : #include <com/sun/star/presentation/EffectCommands.hpp>
35 : : #include <com/sun/star/presentation/EffectPresetClass.hpp>
36 : : #include <com/sun/star/presentation/ParagraphTarget.hpp>
37 : : #include <com/sun/star/lang/XInitialization.hpp>
38 : : #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
39 : : #include <com/sun/star/animations/AnimationNodeType.hpp>
40 : : #include <com/sun/star/animations/XCommand.hpp>
41 : : #include <com/sun/star/animations/AnimationTransformType.hpp>
42 : : #include <com/sun/star/animations/XIterateContainer.hpp>
43 : : #include <com/sun/star/animations/XAnimateTransform.hpp>
44 : : #include <com/sun/star/animations/Event.hpp>
45 : : #include <com/sun/star/animations/EventTrigger.hpp>
46 : : #include <com/sun/star/animations/Timing.hpp>
47 : : #include <com/sun/star/drawing/XDrawPage.hpp>
48 : : #include <com/sun/star/text/XText.hpp>
49 : : #include <com/sun/star/animations/XAnimate.hpp>
50 : : #include <com/sun/star/beans/NamedValue.hpp>
51 : : #include <com/sun/star/beans/XPropertySet.hpp>
52 : : #include <com/sun/star/util/XChangesNotifier.hpp>
53 : : #include <com/sun/star/animations/XAnimateMotion.hpp>
54 : : #include <comphelper/processfactory.hxx>
55 : : #include <comphelper/sequence.hxx>
56 : : #include <com/sun/star/lang/Locale.hpp>
57 : : #include <com/sun/star/i18n/XBreakIterator.hpp>
58 : : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
59 : : #include <com/sun/star/i18n/WordType.hpp>
60 : : #include <com/sun/star/presentation/TextAnimationType.hpp>
61 : :
62 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
63 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
64 : : #include <basegfx/matrix/b2dhommatrix.hxx>
65 : : #include <basegfx/range/b2drange.hxx>
66 : : #include <basegfx/matrix/b2dhommatrixtools.hxx>
67 : :
68 : : #include <algorithm>
69 : :
70 : : #include <cppuhelper/implbase1.hxx>
71 : :
72 : : #include <drawinglayer/geometry/viewinformation2d.hxx>
73 : : #include <svx/sdr/contact/viewcontact.hxx>
74 : : #include <svx/svdopath.hxx>
75 : : #include <svx/svdpage.hxx>
76 : : #include <svx/unoapi.hxx>
77 : : #include "CustomAnimationEffect.hxx"
78 : : #include <CustomAnimationPreset.hxx>
79 : : #include "animations.hxx"
80 : :
81 : : using namespace ::com::sun::star;
82 : : using namespace ::com::sun::star::presentation;
83 : : using namespace ::com::sun::star::animations;
84 : :
85 : : using ::rtl::OUString;
86 : : using ::com::sun::star::uno::Reference;
87 : : using ::com::sun::star::uno::Sequence;
88 : : using ::com::sun::star::uno::XInterface;
89 : : using ::com::sun::star::uno::UNO_QUERY;
90 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
91 : : using ::com::sun::star::uno::Any;
92 : : using ::com::sun::star::uno::makeAny;
93 : : using ::com::sun::star::uno::Exception;
94 : : using ::com::sun::star::uno::RuntimeException;
95 : : using ::com::sun::star::container::XEnumerationAccess;
96 : : using ::com::sun::star::container::XEnumeration;
97 : : using ::com::sun::star::beans::NamedValue;
98 : : using ::com::sun::star::container::XChild;
99 : : using ::com::sun::star::container::XElementAccess;
100 : : using ::com::sun::star::drawing::XShape;
101 : : using ::com::sun::star::lang::XInitialization;
102 : : using ::com::sun::star::drawing::XShapes;
103 : : using ::com::sun::star::drawing::XDrawPage;
104 : : using ::com::sun::star::text::XText;
105 : : using ::com::sun::star::text::XTextRange;
106 : : using ::com::sun::star::beans::XPropertySet;
107 : : using ::com::sun::star::lang::XMultiServiceFactory;
108 : : using ::com::sun::star::util::XCloneable;
109 : : using ::com::sun::star::lang::Locale;
110 : : using ::com::sun::star::util::XChangesNotifier;
111 : : using ::com::sun::star::util::XChangesListener;
112 : :
113 : : namespace sd
114 : : {
115 : : class MainSequenceChangeGuard
116 : : {
117 : : public:
118 : 0 : MainSequenceChangeGuard( EffectSequenceHelper* pSequence )
119 : : {
120 [ # # ]: 0 : mpMainSequence = dynamic_cast< MainSequence* >( pSequence );
121 [ # # ]: 0 : if( mpMainSequence == 0 )
122 : : {
123 [ # # ]: 0 : InteractiveSequence* pI = dynamic_cast< InteractiveSequence* >( pSequence );
124 [ # # ]: 0 : if( pI )
125 : 0 : mpMainSequence = pI->mpMainSequence;
126 : : }
127 : : DBG_ASSERT( mpMainSequence, "sd::MainSequenceChangeGuard::MainSequenceChangeGuard(), no main sequence to guard!" );
128 : :
129 [ # # ]: 0 : if( mpMainSequence )
130 : 0 : mpMainSequence->mbIgnoreChanges++;
131 : 0 : }
132 : :
133 : 0 : ~MainSequenceChangeGuard()
134 : : {
135 [ # # ]: 0 : if( mpMainSequence )
136 : 0 : mpMainSequence->mbIgnoreChanges++;
137 : 0 : }
138 : :
139 : : private:
140 : : MainSequence* mpMainSequence;
141 : : };
142 : :
143 : 0 : CustomAnimationEffect::CustomAnimationEffect( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
144 : : : mnNodeType(-1),
145 : : mnPresetClass(-1),
146 : : mfBegin(-1.0),
147 : : mfDuration(-1.0),
148 : : mfAbsoluteDuration(-1.0),
149 : : mnGroupId(-1),
150 : : mnIterateType(0),
151 : : mfIterateInterval(0.0),
152 : : mnParaDepth( -1 ),
153 : : mbHasText(sal_False),
154 : : mfAcceleration( 1.0 ),
155 : : mfDecelerate( 1.0 ),
156 : : mbAutoReverse(false),
157 : : mnTargetSubItem(0),
158 : : mnCommand(0),
159 : : mpEffectSequence( 0 ),
160 : : mbHasAfterEffect(false),
161 [ # # ]: 0 : mbAfterEffectOnNextEffect(false)
162 : : {
163 [ # # ]: 0 : setNode( xNode );
164 : 0 : }
165 : :
166 : : // --------------------------------------------------------------------
167 : :
168 : 0 : void CustomAnimationEffect::setNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
169 : : {
170 [ # # ]: 0 : mxNode = xNode;
171 : 0 : mxAudio.clear();
172 : :
173 [ # # ][ # # ]: 0 : Sequence< NamedValue > aUserData( mxNode->getUserData() );
174 : 0 : sal_Int32 nLength = aUserData.getLength();
175 : 0 : const NamedValue* p = aUserData.getConstArray();
176 : :
177 [ # # ]: 0 : while( nLength-- )
178 : : {
179 [ # # ]: 0 : if ( p->Name == "node-type" )
180 : : {
181 : 0 : p->Value >>= mnNodeType;
182 : : }
183 [ # # ]: 0 : else if ( p->Name == "preset-id" )
184 : : {
185 : 0 : p->Value >>= maPresetId;
186 : : }
187 [ # # ]: 0 : else if ( p->Name == "preset-sub-type" )
188 : : {
189 : 0 : p->Value >>= maPresetSubType;
190 : : }
191 [ # # ]: 0 : else if ( p->Name == "preset-class" )
192 : : {
193 : 0 : p->Value >>= mnPresetClass;
194 : : }
195 [ # # ]: 0 : else if ( p->Name == "preset-property" )
196 : : {
197 : 0 : p->Value >>= maProperty;
198 : : }
199 [ # # ]: 0 : else if ( p->Name == "group-id" )
200 : : {
201 : 0 : p->Value >>= mnGroupId;
202 : : }
203 : :
204 : 0 : p++;
205 : : }
206 : :
207 : : // get effect start time
208 [ # # ][ # # ]: 0 : mxNode->getBegin() >>= mfBegin;
209 : :
210 [ # # ][ # # ]: 0 : mfAcceleration = mxNode->getAcceleration();
211 [ # # ][ # # ]: 0 : mfDecelerate = mxNode->getDecelerate();
212 [ # # ][ # # ]: 0 : mbAutoReverse = mxNode->getAutoReverse();
213 : :
214 : : // get iteration data
215 [ # # ]: 0 : Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
216 [ # # ]: 0 : if( xIter.is() )
217 : : {
218 [ # # ][ # # ]: 0 : mfIterateInterval = xIter->getIterateInterval();
219 [ # # ][ # # ]: 0 : mnIterateType = xIter->getIterateType();
220 [ # # ][ # # ]: 0 : maTarget = xIter->getTarget();
221 [ # # ][ # # ]: 0 : mnTargetSubItem = xIter->getSubItem();
222 : : }
223 : : else
224 : : {
225 : 0 : mfIterateInterval = 0.0f;
226 : 0 : mnIterateType = 0;
227 : : }
228 : :
229 : : // calculate effect duration and get target shape
230 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
231 [ # # ]: 0 : if( xEnumerationAccess.is() )
232 : : {
233 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
234 [ # # ]: 0 : if( xEnumeration.is() )
235 : : {
236 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
237 : : {
238 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
239 [ # # ]: 0 : if( !xChildNode.is() )
240 : 0 : continue;
241 : :
242 [ # # ][ # # ]: 0 : if( xChildNode->getType() == AnimationNodeType::AUDIO )
[ # # ]
243 : : {
244 [ # # ]: 0 : mxAudio.set( xChildNode, UNO_QUERY );
245 : : }
246 [ # # ][ # # ]: 0 : else if( xChildNode->getType() == AnimationNodeType::COMMAND )
[ # # ]
247 : : {
248 [ # # ]: 0 : Reference< XCommand > xCommand( xChildNode, UNO_QUERY );
249 [ # # ]: 0 : if( xCommand.is() )
250 : : {
251 [ # # ][ # # ]: 0 : mnCommand = xCommand->getCommand();
252 [ # # ]: 0 : if( !maTarget.hasValue() )
253 [ # # ][ # # ]: 0 : maTarget = xCommand->getTarget();
254 : 0 : }
255 : : }
256 : : else
257 : : {
258 : 0 : double fBegin = 0.0;
259 : 0 : double fDuration = 0.0;
260 [ # # ][ # # ]: 0 : xChildNode->getBegin() >>= fBegin;
261 [ # # ][ # # ]: 0 : xChildNode->getDuration() >>= fDuration;
262 : :
263 : 0 : fDuration += fBegin;
264 [ # # ]: 0 : if( fDuration > mfDuration )
265 : 0 : mfDuration = fDuration;
266 : :
267 : : // no target shape yet?
268 [ # # ]: 0 : if( !maTarget.hasValue() )
269 : : {
270 : : // go get it boys!
271 [ # # ]: 0 : Reference< XAnimate > xAnimate( xChildNode, UNO_QUERY );
272 [ # # ]: 0 : if( xAnimate.is() )
273 : : {
274 [ # # ][ # # ]: 0 : maTarget = xAnimate->getTarget();
275 [ # # ][ # # ]: 0 : mnTargetSubItem = xAnimate->getSubItem();
276 : 0 : }
277 : : }
278 : : }
279 [ # # ]: 0 : }
280 : 0 : }
281 : : }
282 : :
283 : 0 : mfAbsoluteDuration = mfDuration;
284 : 0 : double fRepeatCount = 1.0;
285 [ # # ][ # # ]: 0 : if( (mxNode->getRepeatCount()) >>= fRepeatCount )
[ # # ]
286 : 0 : mfAbsoluteDuration *= fRepeatCount;
287 : :
288 [ # # ][ # # ]: 0 : checkForText();
289 : 0 : }
290 : :
291 : : // --------------------------------------------------------------------
292 : :
293 : 0 : sal_Int32 CustomAnimationEffect::getNumberOfSubitems( const Any& aTarget, sal_Int16 nIterateType )
294 : : {
295 : 0 : sal_Int32 nSubItems = 0;
296 : :
297 : : try
298 : : {
299 : : // first get target text
300 : 0 : sal_Int32 nOnlyPara = -1;
301 : :
302 : 0 : Reference< XText > xShape;
303 [ # # ]: 0 : aTarget >>= xShape;
304 [ # # ]: 0 : if( !xShape.is() )
305 : : {
306 [ # # ]: 0 : ParagraphTarget aParaTarget;
307 [ # # ][ # # ]: 0 : if( aTarget >>= aParaTarget )
308 : : {
309 [ # # ]: 0 : xShape.set( aParaTarget.Shape, UNO_QUERY );
310 : 0 : nOnlyPara = aParaTarget.Paragraph;
311 [ # # ]: 0 : }
312 : : }
313 : :
314 : : // now use the break iterator to iterate over the given text
315 : : // and count the sub items
316 : :
317 [ # # ]: 0 : if( xShape.is() )
318 : : {
319 : : // TODO/LATER: Optimize this, don't create a break iterator each time
320 [ # # ]: 0 : Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
321 [ # # ][ # # ]: 0 : Reference < i18n::XBreakIterator > xBI( xMSF->createInstance( "com.sun.star.i18n.BreakIterator" ), UNO_QUERY );
[ # # ]
322 : : DBG_ASSERT( xBI.is(), "sd::CustomAnimationEffect::getNumberOfSubitems(), could not create a 'com.sun.star.i18n.BreakIterator'!" );
323 : :
324 [ # # ]: 0 : if( xBI.is() )
325 : : {
326 [ # # ]: 0 : Reference< XEnumerationAccess > xEA( xShape, UNO_QUERY_THROW );
327 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEA->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
328 : 0 : Locale aLocale;
329 : 0 : const OUString aStrLocaleName( "CharLocale" );
330 : 0 : Reference< XTextRange > xParagraph;
331 : :
332 : 0 : sal_Int32 nPara = 0;
333 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
334 : : {
335 [ # # ][ # # ]: 0 : xEnumeration->nextElement() >>= xParagraph;
[ # # ]
336 : :
337 : : // skip this if its not the only paragraph we want to count
338 [ # # ][ # # ]: 0 : if( (nOnlyPara != -1) && (nOnlyPara != nPara ) )
339 : 0 : continue;
340 : :
341 [ # # ]: 0 : if( nIterateType == TextAnimationType::BY_PARAGRAPH )
342 : : {
343 : 0 : nSubItems++;
344 : : }
345 : : else
346 : : {
347 [ # # ][ # # ]: 0 : const OUString aText( xParagraph->getString() );
348 [ # # ]: 0 : Reference< XPropertySet > xSet( xParagraph, UNO_QUERY_THROW );
349 [ # # ][ # # ]: 0 : xSet->getPropertyValue( aStrLocaleName ) >>= aLocale;
[ # # ]
350 : :
351 : : sal_Int32 nPos;
352 : 0 : const sal_Int32 nEndPos = aText.getLength();
353 : :
354 [ # # ]: 0 : if( nIterateType == TextAnimationType::BY_WORD )
355 : : {
356 [ # # ]: 0 : for( nPos = 0; nPos < nEndPos; nPos++ )
357 : : {
358 [ # # ][ # # ]: 0 : nPos = xBI->getWordBoundary(aText, nPos, aLocale, i18n::WordType::ANY_WORD, sal_True).endPos;
359 : 0 : nSubItems++;
360 : : }
361 : : break;
362 : : }
363 : : else
364 : : {
365 : : sal_Int32 nDone;
366 [ # # ]: 0 : for( nPos = 0; nPos < nEndPos; nPos++ )
367 : : {
368 [ # # ][ # # ]: 0 : nPos = xBI->nextCharacters(aText, nPos, aLocale, i18n::CharacterIteratorMode::SKIPCELL, 0, nDone);
369 : 0 : nSubItems++;
370 : : }
371 [ # # ][ # # ]: 0 : }
372 : : }
373 : :
374 [ # # ]: 0 : if( nPara == nOnlyPara )
375 : 0 : break;
376 : :
377 : 0 : nPara++;
378 : 0 : }
379 : 0 : }
380 [ # # ]: 0 : }
381 : : }
382 : 0 : catch( Exception& )
383 : : {
384 : 0 : nSubItems = 0;
385 : : OSL_FAIL( "sd::CustomAnimationEffect::getNumberOfSubitems(), exception cought!" );
386 : : }
387 : :
388 : 0 : return nSubItems;
389 : : }
390 : :
391 : : // --------------------------------------------------------------------
392 : :
393 [ # # ]: 0 : CustomAnimationEffect::~CustomAnimationEffect()
394 : : {
395 [ # # ]: 0 : }
396 : :
397 : : // --------------------------------------------------------------------
398 : :
399 : 0 : CustomAnimationEffectPtr CustomAnimationEffect::clone() const
400 : : {
401 [ # # ]: 0 : Reference< XCloneable > xCloneable( mxNode, UNO_QUERY_THROW );
402 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xNode( xCloneable->createClone(), UNO_QUERY_THROW );
[ # # ]
403 [ # # ][ # # ]: 0 : CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xNode ) );
[ # # ]
404 : 0 : pEffect->setEffectSequence( getEffectSequence() );
405 : 0 : return pEffect;
406 : : }
407 : :
408 : : // --------------------------------------------------------------------
409 : :
410 : 0 : sal_Int32 CustomAnimationEffect::get_node_type( const Reference< XAnimationNode >& xNode )
411 : : {
412 : 0 : sal_Int16 nNodeType = -1;
413 : :
414 [ # # ]: 0 : if( xNode.is() )
415 : : {
416 [ # # ][ # # ]: 0 : Sequence< NamedValue > aUserData( xNode->getUserData() );
417 : 0 : sal_Int32 nLength = aUserData.getLength();
418 [ # # ]: 0 : if( nLength )
419 : : {
420 : 0 : const NamedValue* p = aUserData.getConstArray();
421 [ # # ]: 0 : while( nLength-- )
422 : : {
423 [ # # ]: 0 : if ( p->Name == "node-type" )
424 : : {
425 : 0 : p->Value >>= nNodeType;
426 : 0 : break;
427 : : }
428 : 0 : p++;
429 : : }
430 [ # # ]: 0 : }
431 : : }
432 : :
433 : 0 : return nNodeType;
434 : : }
435 : :
436 : : // --------------------------------------------------------------------
437 : :
438 : 0 : void CustomAnimationEffect::setPresetClass( sal_Int16 nPresetClass )
439 : : {
440 [ # # ]: 0 : if( mnPresetClass != nPresetClass )
441 : : {
442 : 0 : mnPresetClass = nPresetClass;
443 [ # # ]: 0 : if( mxNode.is() )
444 : : {
445 : : // first try to find a "preset-class" entry in the user data
446 : : // and change it
447 [ # # ][ # # ]: 0 : Sequence< NamedValue > aUserData( mxNode->getUserData() );
448 : 0 : sal_Int32 nLength = aUserData.getLength();
449 : 0 : bool bFound = false;
450 [ # # ]: 0 : if( nLength )
451 : : {
452 [ # # ]: 0 : NamedValue* p = aUserData.getArray();
453 [ # # ]: 0 : while( nLength-- )
454 : : {
455 [ # # ]: 0 : if ( p->Name == "preset-class" )
456 : : {
457 [ # # ]: 0 : p->Value <<= mnPresetClass;
458 : 0 : bFound = true;
459 : 0 : break;
460 : : }
461 : 0 : p++;
462 : : }
463 : : }
464 : :
465 : : // no "node-type" entry inside user data, so add it
466 [ # # ]: 0 : if( !bFound )
467 : : {
468 : 0 : nLength = aUserData.getLength();
469 [ # # ]: 0 : aUserData.realloc( nLength + 1);
470 [ # # ]: 0 : aUserData[nLength].Name = "preset-class";
471 [ # # ][ # # ]: 0 : aUserData[nLength].Value <<= mnPresetClass;
472 : : }
473 : :
474 [ # # ][ # # ]: 0 : mxNode->setUserData( aUserData );
[ # # ]
475 : : }
476 : : }
477 : 0 : }
478 : :
479 : 0 : void CustomAnimationEffect::setNodeType( sal_Int16 nNodeType )
480 : : {
481 [ # # ]: 0 : if( mnNodeType != nNodeType )
482 : : {
483 : 0 : mnNodeType = nNodeType;
484 [ # # ]: 0 : if( mxNode.is() )
485 : : {
486 : : // first try to find a "node-type" entry in the user data
487 : : // and change it
488 [ # # ][ # # ]: 0 : Sequence< NamedValue > aUserData( mxNode->getUserData() );
489 : 0 : sal_Int32 nLength = aUserData.getLength();
490 : 0 : bool bFound = false;
491 [ # # ]: 0 : if( nLength )
492 : : {
493 [ # # ]: 0 : NamedValue* p = aUserData.getArray();
494 [ # # ]: 0 : while( nLength-- )
495 : : {
496 [ # # ]: 0 : if ( p->Name == "node-type" )
497 : : {
498 [ # # ]: 0 : p->Value <<= mnNodeType;
499 : 0 : bFound = true;
500 : 0 : break;
501 : : }
502 : 0 : p++;
503 : : }
504 : : }
505 : :
506 : : // no "node-type" entry inside user data, so add it
507 [ # # ]: 0 : if( !bFound )
508 : : {
509 : 0 : nLength = aUserData.getLength();
510 [ # # ]: 0 : aUserData.realloc( nLength + 1);
511 [ # # ]: 0 : aUserData[nLength].Name = "node-type";
512 [ # # ][ # # ]: 0 : aUserData[nLength].Value <<= mnNodeType;
513 : : }
514 : :
515 [ # # ][ # # ]: 0 : mxNode->setUserData( aUserData );
[ # # ]
516 : : }
517 : : }
518 : 0 : }
519 : :
520 : : // --------------------------------------------------------------------
521 : :
522 : 0 : void CustomAnimationEffect::setGroupId( sal_Int32 nGroupId )
523 : : {
524 : 0 : mnGroupId = nGroupId;
525 [ # # ]: 0 : if( mxNode.is() )
526 : : {
527 : : // first try to find a "group-id" entry in the user data
528 : : // and change it
529 [ # # ][ # # ]: 0 : Sequence< NamedValue > aUserData( mxNode->getUserData() );
530 : 0 : sal_Int32 nLength = aUserData.getLength();
531 : 0 : bool bFound = false;
532 [ # # ]: 0 : if( nLength )
533 : : {
534 [ # # ]: 0 : NamedValue* p = aUserData.getArray();
535 [ # # ]: 0 : while( nLength-- )
536 : : {
537 [ # # ]: 0 : if ( p->Name == "group-id" )
538 : : {
539 [ # # ]: 0 : p->Value <<= mnGroupId;
540 : 0 : bFound = true;
541 : 0 : break;
542 : : }
543 : 0 : p++;
544 : : }
545 : : }
546 : :
547 : : // no "node-type" entry inside user data, so add it
548 [ # # ]: 0 : if( !bFound )
549 : : {
550 : 0 : nLength = aUserData.getLength();
551 [ # # ]: 0 : aUserData.realloc( nLength + 1);
552 [ # # ]: 0 : aUserData[nLength].Name = "group-id";
553 [ # # ][ # # ]: 0 : aUserData[nLength].Value <<= mnGroupId;
554 : : }
555 : :
556 [ # # ][ # # ]: 0 : mxNode->setUserData( aUserData );
[ # # ]
557 : : }
558 : 0 : }
559 : :
560 : : // --------------------------------------------------------------------
561 : :
562 : : /** checks if the text for this effect has changed and updates internal flags.
563 : : returns true if something changed.
564 : : */
565 : 0 : bool CustomAnimationEffect::checkForText()
566 : : {
567 : 0 : bool bChange = false;
568 : :
569 : 0 : Reference< XText > xText;
570 : :
571 [ # # ][ # # ]: 0 : if( maTarget.getValueType() == ::getCppuType((const ParagraphTarget*)0) )
572 : : {
573 : : // calc para depth
574 [ # # ]: 0 : ParagraphTarget aParaTarget;
575 [ # # ]: 0 : maTarget >>= aParaTarget;
576 : :
577 [ # # ][ # # ]: 0 : xText = Reference< XText >::query( aParaTarget.Shape );
578 : :
579 : : // get paragraph
580 [ # # ]: 0 : if( xText.is() )
581 : : {
582 [ # # ]: 0 : Reference< XEnumerationAccess > xEA( xText, UNO_QUERY );
583 [ # # ]: 0 : if( xEA.is() )
584 : : {
585 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEA->createEnumeration(), UNO_QUERY );
[ # # ]
586 [ # # ]: 0 : if( xEnumeration.is() )
587 : : {
588 [ # # ][ # # ]: 0 : sal_Bool bHasText = xEnumeration->hasMoreElements();
589 : 0 : bChange |= bHasText != mbHasText;
590 : 0 : mbHasText = bHasText;
591 : :
592 : 0 : sal_Int32 nPara = aParaTarget.Paragraph;
593 : :
594 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() && nPara-- )
[ # # ][ # # ]
[ # # ]
595 [ # # ][ # # ]: 0 : xEnumeration->nextElement();
596 : :
597 [ # # ][ # # ]: 0 : if( xEnumeration->hasMoreElements() )
[ # # ]
598 : : {
599 : 0 : Reference< XPropertySet > xParaSet;
600 [ # # ][ # # ]: 0 : xEnumeration->nextElement() >>= xParaSet;
[ # # ]
601 [ # # ]: 0 : if( xParaSet.is() )
602 : : {
603 : 0 : sal_Int32 nParaDepth = 0;
604 : 0 : const OUString strNumberingLevel( "NumberingLevel" );
605 [ # # ][ # # ]: 0 : xParaSet->getPropertyValue( strNumberingLevel ) >>= nParaDepth;
606 : 0 : bChange |= nParaDepth != mnParaDepth;
607 : 0 : mnParaDepth = nParaDepth;
608 : 0 : }
609 : : }
610 : 0 : }
611 : 0 : }
612 [ # # ]: 0 : }
613 : : }
614 : : else
615 : : {
616 [ # # ]: 0 : maTarget >>= xText;
617 [ # # ][ # # ]: 0 : sal_Bool bHasText = xText.is() && !xText->getString().isEmpty();
[ # # ][ # # ]
[ # # ][ # # ]
618 : 0 : bChange |= bHasText != mbHasText;
619 : 0 : mbHasText = bHasText;
620 : : }
621 : :
622 [ # # ]: 0 : bChange |= calculateIterateDuration();
623 : 0 : return bChange;
624 : : }
625 : :
626 : 0 : bool CustomAnimationEffect::calculateIterateDuration()
627 : : {
628 : 0 : bool bChange = false;
629 : :
630 : : // if we have an iteration, we must also calculate the
631 : : // 'true' container duration, that is
632 : : // ( ( is form animated ) ? [contained effects duration] : 0 ) +
633 : : // ( [number of animated children] - 1 ) * [interval-delay] + [contained effects duration]
634 [ # # ]: 0 : Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
635 [ # # ]: 0 : if( xIter.is() )
636 : : {
637 : 0 : double fDuration = mfDuration;
638 : 0 : const double fSubEffectDuration = mfDuration;
639 : :
640 [ # # ]: 0 : if( mnTargetSubItem != ShapeAnimationSubType::ONLY_BACKGROUND ) // does not make sense for iterate container but better check
641 : : {
642 [ # # ]: 0 : const sal_Int32 nSubItems = getNumberOfSubitems( maTarget, mnIterateType );
643 [ # # ]: 0 : if( nSubItems )
644 : : {
645 : 0 : const double f = (nSubItems-1) * mfIterateInterval;
646 : 0 : fDuration += f;
647 : : }
648 : : }
649 : :
650 : : // if we also animate the form first, we have to add the
651 : : // sub effect duration to the whole effect duration
652 [ # # ]: 0 : if( mnTargetSubItem == ShapeAnimationSubType::AS_WHOLE )
653 : 0 : fDuration += fSubEffectDuration;
654 : :
655 : 0 : bChange |= fDuration != mfAbsoluteDuration;
656 : 0 : mfAbsoluteDuration = fDuration;
657 : : }
658 : :
659 : 0 : return bChange;
660 : : }
661 : :
662 : : // --------------------------------------------------------------------
663 : :
664 : 0 : void CustomAnimationEffect::setTarget( const ::com::sun::star::uno::Any& rTarget )
665 : : {
666 : : try
667 : : {
668 : 0 : maTarget = rTarget;
669 : :
670 : : // first, check special case for random node
671 [ # # ]: 0 : Reference< XInitialization > xInit( mxNode, UNO_QUERY );
672 [ # # ]: 0 : if( xInit.is() )
673 : : {
674 [ # # ]: 0 : const Sequence< Any > aArgs( &maTarget, 1 );
675 [ # # ][ # # ]: 0 : xInit->initialize( aArgs );
[ # # ]
676 : : }
677 : : else
678 : : {
679 [ # # ]: 0 : Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
680 [ # # ]: 0 : if( xIter.is() )
681 : : {
682 [ # # ][ # # ]: 0 : xIter->setTarget(maTarget);
683 : : }
684 : : else
685 : : {
686 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
687 [ # # ]: 0 : if( xEnumerationAccess.is() )
688 : : {
689 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
690 [ # # ]: 0 : if( xEnumeration.is() )
691 : : {
692 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
693 : : {
694 [ # # ][ # # ]: 0 : const Any aElem( xEnumeration->nextElement() );
695 [ # # ]: 0 : Reference< XAnimate > xAnimate( aElem, UNO_QUERY );
696 [ # # ]: 0 : if( xAnimate.is() )
697 [ # # ][ # # ]: 0 : xAnimate->setTarget( rTarget );
698 : : else
699 : : {
700 [ # # ]: 0 : Reference< XCommand > xCommand( aElem, UNO_QUERY );
701 [ # # ]: 0 : if( xCommand.is() )
702 [ # # ][ # # ]: 0 : xCommand->setTarget( rTarget );
703 : : }
704 : 0 : }
705 : 0 : }
706 : 0 : }
707 : 0 : }
708 : : }
709 [ # # ][ # # ]: 0 : checkForText();
710 : : }
711 : 0 : catch( Exception& )
712 : : {
713 : : OSL_FAIL( "sd::CustomAnimationEffect::setTarget(), exception cought!" );
714 : : }
715 : 0 : }
716 : :
717 : : // --------------------------------------------------------------------
718 : :
719 : 0 : void CustomAnimationEffect::setTargetSubItem( sal_Int16 nSubItem )
720 : : {
721 : : try
722 : : {
723 : 0 : mnTargetSubItem = nSubItem;
724 : :
725 [ # # ]: 0 : Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
726 [ # # ]: 0 : if( xIter.is() )
727 : : {
728 [ # # ][ # # ]: 0 : xIter->setSubItem(mnTargetSubItem);
729 : : }
730 : : else
731 : : {
732 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
733 [ # # ]: 0 : if( xEnumerationAccess.is() )
734 : : {
735 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
736 [ # # ]: 0 : if( xEnumeration.is() )
737 : : {
738 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
739 : : {
740 [ # # ][ # # ]: 0 : Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
741 [ # # ]: 0 : if( xAnimate.is() )
742 [ # # ][ # # ]: 0 : xAnimate->setSubItem( mnTargetSubItem );
743 : 0 : }
744 : 0 : }
745 : 0 : }
746 [ # # ]: 0 : }
747 : : }
748 : 0 : catch( Exception& )
749 : : {
750 : : OSL_FAIL( "sd::CustomAnimationEffect::setTargetSubItem(), exception cought!" );
751 : : }
752 : 0 : }
753 : :
754 : : // --------------------------------------------------------------------
755 : :
756 : 0 : void CustomAnimationEffect::setDuration( double fDuration )
757 : : {
758 [ # # ][ # # ]: 0 : if( (mfDuration != -1.0) && (mfDuration != fDuration) ) try
759 : : {
760 : 0 : double fScale = fDuration / mfDuration;
761 : 0 : mfDuration = fDuration;
762 : 0 : double fRepeatCount = 1.0;
763 [ # # ]: 0 : getRepeatCount() >>= fRepeatCount;
764 : 0 : mfAbsoluteDuration = mfDuration * fRepeatCount;
765 : :
766 : : // calculate effect duration and get target shape
767 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
768 [ # # ]: 0 : if( xEnumerationAccess.is() )
769 : : {
770 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
771 [ # # ]: 0 : if( xEnumeration.is() )
772 : : {
773 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
774 : : {
775 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
776 [ # # ]: 0 : if( !xChildNode.is() )
777 : 0 : continue;
778 : :
779 : :
780 : 0 : double fChildBegin = 0.0;
781 [ # # ][ # # ]: 0 : xChildNode->getBegin() >>= fChildBegin;
782 [ # # ]: 0 : if( fChildBegin != 0.0 )
783 : : {
784 : 0 : fChildBegin *= fScale;
785 [ # # ][ # # ]: 0 : xChildNode->setBegin( makeAny( fChildBegin ) );
[ # # ]
786 : : }
787 : :
788 : 0 : double fChildDuration = 0.0;
789 [ # # ][ # # ]: 0 : xChildNode->getDuration() >>= fChildDuration;
790 [ # # ]: 0 : if( fChildDuration != 0.0 )
791 : : {
792 : 0 : fChildDuration *= fScale;
793 [ # # ][ # # ]: 0 : xChildNode->setDuration( makeAny( fChildDuration ) );
[ # # ]
794 : : }
795 [ # # ]: 0 : }
796 : 0 : }
797 : : }
798 [ # # ][ # # ]: 0 : calculateIterateDuration();
799 : : }
800 : 0 : catch( Exception& )
801 : : {
802 : : OSL_FAIL( "sd::CustomAnimationEffect::setDuration(), exception cought!" );
803 : : }
804 : 0 : }
805 : :
806 : : // --------------------------------------------------------------------
807 : :
808 : 0 : void CustomAnimationEffect::setBegin( double fBegin )
809 : : {
810 [ # # ]: 0 : if( mxNode.is() ) try
811 : : {
812 : 0 : mfBegin = fBegin;
813 [ # # ][ # # ]: 0 : mxNode->setBegin( makeAny( fBegin ) );
[ # # ][ # # ]
814 : : }
815 : 0 : catch( Exception& )
816 : : {
817 : : OSL_FAIL( "sd::CustomAnimationEffect::setBegin(), exception cought!" );
818 : : }
819 : 0 : }
820 : :
821 : : // --------------------------------------------------------------------
822 : :
823 : 0 : void CustomAnimationEffect::setAcceleration( double fAcceleration )
824 : : {
825 [ # # ]: 0 : if( mxNode.is() ) try
826 : : {
827 : 0 : mfAcceleration = fAcceleration;
828 [ # # ][ # # ]: 0 : mxNode->setAcceleration( fAcceleration );
829 : : }
830 : 0 : catch( Exception& )
831 : : {
832 : : OSL_FAIL( "sd::CustomAnimationEffect::setAcceleration(), exception cought!" );
833 : : }
834 [ # # ]: 0 : }
835 : : // --------------------------------------------------------------------
836 : :
837 : 0 : void CustomAnimationEffect::setDecelerate( double fDecelerate )
838 : : {
839 [ # # ]: 0 : if( mxNode.is() ) try
840 : : {
841 : 0 : mfDecelerate = fDecelerate;
842 [ # # ][ # # ]: 0 : mxNode->setDecelerate( fDecelerate );
843 : : }
844 : 0 : catch( Exception& )
845 : : {
846 : : OSL_FAIL( "sd::CustomAnimationEffect::setDecelerate(), exception cought!" );
847 : : }
848 [ # # ]: 0 : }
849 : :
850 : : // --------------------------------------------------------------------
851 : :
852 : 0 : void CustomAnimationEffect::setAutoReverse( sal_Bool bAutoReverse )
853 : : {
854 [ # # ]: 0 : if( mxNode.is() ) try
855 : : {
856 : 0 : mbAutoReverse = bAutoReverse;
857 [ # # ][ # # ]: 0 : mxNode->setAutoReverse( bAutoReverse );
858 : : }
859 : 0 : catch( Exception& )
860 : : {
861 : : OSL_FAIL( "sd::CustomAnimationEffect::setAutoReverse(), exception cought!" );
862 : : }
863 [ # # ]: 0 : }
864 : :
865 : : // --------------------------------------------------------------------
866 : :
867 : 0 : void CustomAnimationEffect::replaceNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
868 : : {
869 : 0 : sal_Int16 nNodeType = mnNodeType;
870 : 0 : Any aTarget = maTarget;
871 : :
872 : 0 : double fBegin = mfBegin;
873 : 0 : double fDuration = mfDuration;
874 : 0 : double fAcceleration = mfAcceleration;
875 : 0 : double fDecelerate = mfDecelerate ;
876 : 0 : sal_Bool bAutoReverse = mbAutoReverse;
877 : 0 : Reference< XAudio > xAudio( mxAudio );
878 : 0 : sal_Int16 nIterateType = mnIterateType;
879 : 0 : double fIterateInterval = mfIterateInterval;
880 : 0 : sal_Int16 nSubItem = mnTargetSubItem;
881 : :
882 [ # # ]: 0 : setNode( xNode );
883 : :
884 [ # # ]: 0 : setAudio( xAudio );
885 [ # # ]: 0 : setNodeType( nNodeType );
886 [ # # ]: 0 : setTarget( aTarget );
887 [ # # ]: 0 : setTargetSubItem( nSubItem );
888 [ # # ]: 0 : setDuration( fDuration );
889 [ # # ]: 0 : setBegin( fBegin );
890 : :
891 [ # # ]: 0 : setAcceleration( fAcceleration );
892 [ # # ]: 0 : setDecelerate( fDecelerate );
893 [ # # ]: 0 : setAutoReverse( bAutoReverse );
894 : :
895 [ # # ]: 0 : if( nIterateType != mnIterateType )
896 [ # # ]: 0 : setIterateType( nIterateType );
897 : :
898 [ # # ][ # # ]: 0 : if( mnIterateType && ( fIterateInterval != mfIterateInterval ) )
899 [ # # ]: 0 : setIterateInterval( fIterateInterval );
900 : 0 : }
901 : :
902 : : // --------------------------------------------------------------------
903 : :
904 : 0 : Reference< XShape > CustomAnimationEffect::getTargetShape() const
905 : : {
906 : 0 : Reference< XShape > xShape;
907 [ # # ]: 0 : maTarget >>= xShape;
908 [ # # ]: 0 : if( !xShape.is() )
909 : : {
910 [ # # ]: 0 : ParagraphTarget aParaTarget;
911 [ # # ][ # # ]: 0 : if( maTarget >>= aParaTarget )
912 [ # # ][ # # ]: 0 : xShape = aParaTarget.Shape;
913 : : }
914 : :
915 : 0 : return xShape;
916 : : }
917 : :
918 : : // --------------------------------------------------------------------
919 : :
920 : 0 : Any CustomAnimationEffect::getRepeatCount() const
921 : : {
922 [ # # ]: 0 : if( mxNode.is() )
923 : : {
924 : 0 : return mxNode->getRepeatCount();
925 : : }
926 : : else
927 : : {
928 : 0 : Any aAny;
929 : 0 : return aAny;
930 : : }
931 : : }
932 : :
933 : : // --------------------------------------------------------------------
934 : :
935 : 0 : Any CustomAnimationEffect::getEnd() const
936 : : {
937 [ # # ]: 0 : if( mxNode.is() )
938 : : {
939 : 0 : return mxNode->getEnd();
940 : : }
941 : : else
942 : : {
943 : 0 : Any aAny;
944 : 0 : return aAny;
945 : : }
946 : : }
947 : :
948 : : // --------------------------------------------------------------------
949 : :
950 : 0 : sal_Int16 CustomAnimationEffect::getFill() const
951 : : {
952 [ # # ]: 0 : if( mxNode.is() )
953 : 0 : return mxNode->getFill();
954 : : else
955 : 0 : return 0;
956 : : }
957 : :
958 : : // --------------------------------------------------------------------
959 : :
960 : 0 : void CustomAnimationEffect::setRepeatCount( const Any& rRepeatCount )
961 : : {
962 [ # # ]: 0 : if( mxNode.is() )
963 : : {
964 [ # # ][ # # ]: 0 : mxNode->setRepeatCount( rRepeatCount );
965 : 0 : double fRepeatCount = 1.0;
966 : 0 : rRepeatCount >>= fRepeatCount;
967 : 0 : mfAbsoluteDuration = mfDuration * fRepeatCount;
968 : : }
969 : 0 : }
970 : :
971 : : // --------------------------------------------------------------------
972 : :
973 : 0 : void CustomAnimationEffect::setEnd( const Any& rEnd )
974 : : {
975 [ # # ]: 0 : if( mxNode.is() )
976 : 0 : mxNode->setEnd( rEnd );
977 : 0 : }
978 : :
979 : : // --------------------------------------------------------------------
980 : :
981 : 0 : void CustomAnimationEffect::setFill( sal_Int16 nFill )
982 : : {
983 [ # # ]: 0 : if( mxNode.is() )
984 : 0 : mxNode->setFill( nFill );
985 : 0 : }
986 : :
987 : : // --------------------------------------------------------------------
988 : :
989 : 0 : Reference< XAnimationNode > CustomAnimationEffect::createAfterEffectNode() const throw (Exception)
990 : : {
991 : : DBG_ASSERT( mbHasAfterEffect, "sd::CustomAnimationEffect::createAfterEffectNode(), this node has no after effect!" );
992 : :
993 [ # # ]: 0 : Reference< XMultiServiceFactory > xMsf( ::comphelper::getProcessServiceFactory() );
994 : :
995 : 0 : const char* pServiceName = maDimColor.hasValue() ?
996 [ # # ]: 0 : "com.sun.star.animations.AnimateColor" : "com.sun.star.animations.AnimateSet";
997 : :
998 [ # # ][ # # ]: 0 : Reference< XAnimate > xAnimate( xMsf->createInstance(OUString::createFromAscii(pServiceName) ), UNO_QUERY_THROW );
[ # # ]
999 : :
1000 : 0 : Any aTo;
1001 : 0 : OUString aAttributeName;
1002 : :
1003 [ # # ]: 0 : if( maDimColor.hasValue() )
1004 : : {
1005 : 0 : aTo = maDimColor;
1006 : 0 : aAttributeName = "DimColor";
1007 : : }
1008 : : else
1009 : : {
1010 [ # # ]: 0 : aTo = makeAny( (sal_Bool)sal_False );
1011 : 0 : aAttributeName = "Visibility";
1012 : : }
1013 : :
1014 : 0 : Any aBegin;
1015 [ # # ]: 0 : if( !mbAfterEffectOnNextEffect ) // sameClick
1016 : : {
1017 : 0 : Event aEvent;
1018 : :
1019 [ # # ]: 0 : aEvent.Source <<= getNode();
1020 : 0 : aEvent.Trigger = EventTrigger::END_EVENT;
1021 : 0 : aEvent.Repeat = 0;
1022 : :
1023 [ # # ]: 0 : aBegin <<= aEvent;
1024 : : }
1025 : : else
1026 : : {
1027 [ # # ]: 0 : aBegin <<= (double)0.0;
1028 : : }
1029 : :
1030 [ # # ][ # # ]: 0 : xAnimate->setBegin( aBegin );
1031 [ # # ][ # # ]: 0 : xAnimate->setTo( aTo );
1032 [ # # ][ # # ]: 0 : xAnimate->setAttributeName( aAttributeName );
1033 : :
1034 [ # # ][ # # ]: 0 : xAnimate->setDuration( makeAny( (double)0.001 ) );
[ # # ]
1035 [ # # ][ # # ]: 0 : xAnimate->setFill( AnimationFill::HOLD );
1036 [ # # ][ # # ]: 0 : xAnimate->setTarget( maTarget );
1037 : :
1038 [ # # ]: 0 : return Reference< XAnimationNode >( xAnimate, UNO_QUERY_THROW );
1039 : : }
1040 : :
1041 : : // --------------------------------------------------------------------
1042 : :
1043 : 0 : void CustomAnimationEffect::setIterateType( sal_Int16 nIterateType )
1044 : : {
1045 [ # # ]: 0 : if( mnIterateType != nIterateType ) try
1046 : : {
1047 : : // do we need to exchange the container node?
1048 [ # # ][ # # ]: 0 : if( (mnIterateType == 0) || (nIterateType == 0) )
1049 : : {
1050 : 0 : sal_Int16 nTargetSubItem = mnTargetSubItem;
1051 : :
1052 [ # # ]: 0 : Reference< XMultiServiceFactory > xMsf( ::comphelper::getProcessServiceFactory() );
1053 : : const char * pServiceName =
1054 [ # # ]: 0 : nIterateType ? "com.sun.star.animations.IterateContainer" : "com.sun.star.animations.ParallelTimeContainer";
1055 : : Reference< XTimeContainer > xNewContainer(
1056 [ # # ][ # # ]: 0 : xMsf->createInstance( OUString::createFromAscii(pServiceName) ), UNO_QUERY_THROW );
[ # # ]
1057 : :
1058 [ # # ]: 0 : Reference< XTimeContainer > xOldContainer( mxNode, UNO_QUERY_THROW );
1059 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY_THROW );
1060 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
1061 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
1062 : : {
1063 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
[ # # ]
1064 [ # # ][ # # ]: 0 : xOldContainer->removeChild( xChildNode );
1065 [ # # ][ # # ]: 0 : xNewContainer->appendChild( xChildNode );
1066 : 0 : }
1067 : :
1068 [ # # ]: 0 : Reference< XAnimationNode > xNewNode( xNewContainer, UNO_QUERY_THROW );
1069 : :
1070 [ # # ][ # # ]: 0 : xNewNode->setBegin( mxNode->getBegin() );
[ # # ][ # # ]
1071 [ # # ][ # # ]: 0 : xNewNode->setDuration( mxNode->getDuration() );
[ # # ][ # # ]
1072 [ # # ][ # # ]: 0 : xNewNode->setEnd( mxNode->getEnd() );
[ # # ][ # # ]
1073 [ # # ][ # # ]: 0 : xNewNode->setEndSync( mxNode->getEndSync() );
[ # # ][ # # ]
1074 [ # # ][ # # ]: 0 : xNewNode->setRepeatCount( mxNode->getRepeatCount() );
[ # # ][ # # ]
1075 [ # # ][ # # ]: 0 : xNewNode->setFill( mxNode->getFill() );
[ # # ][ # # ]
1076 [ # # ][ # # ]: 0 : xNewNode->setFillDefault( mxNode->getFillDefault() );
[ # # ][ # # ]
1077 [ # # ][ # # ]: 0 : xNewNode->setRestart( mxNode->getRestart() );
[ # # ][ # # ]
1078 [ # # ][ # # ]: 0 : xNewNode->setRestartDefault( mxNode->getRestartDefault() );
[ # # ][ # # ]
1079 [ # # ][ # # ]: 0 : xNewNode->setAcceleration( mxNode->getAcceleration() );
[ # # ][ # # ]
1080 [ # # ][ # # ]: 0 : xNewNode->setDecelerate( mxNode->getDecelerate() );
[ # # ][ # # ]
1081 [ # # ][ # # ]: 0 : xNewNode->setAutoReverse( mxNode->getAutoReverse() );
[ # # ][ # # ]
1082 [ # # ][ # # ]: 0 : xNewNode->setRepeatDuration( mxNode->getRepeatDuration() );
[ # # ][ # # ]
1083 [ # # ][ # # ]: 0 : xNewNode->setEndSync( mxNode->getEndSync() );
[ # # ][ # # ]
1084 [ # # ][ # # ]: 0 : xNewNode->setRepeatCount( mxNode->getRepeatCount() );
[ # # ][ # # ]
1085 [ # # ][ # # ]: 0 : xNewNode->setUserData( mxNode->getUserData() );
[ # # ][ # # ]
[ # # ]
1086 : :
1087 [ # # ]: 0 : mxNode = xNewNode;
1088 : :
1089 : 0 : Any aTarget;
1090 [ # # ]: 0 : if( nIterateType )
1091 : : {
1092 [ # # ]: 0 : Reference< XIterateContainer > xIter( mxNode, UNO_QUERY_THROW );
1093 [ # # ][ # # ]: 0 : xIter->setTarget(maTarget);
1094 [ # # ][ # # ]: 0 : xIter->setSubItem( nTargetSubItem );
1095 : : }
1096 : : else
1097 : : {
1098 : 0 : aTarget = maTarget;
1099 : : }
1100 : :
1101 [ # # ]: 0 : Reference< XEnumerationAccess > xEA( mxNode, UNO_QUERY_THROW );
1102 [ # # ][ # # ]: 0 : Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
1103 [ # # ][ # # ]: 0 : while( xE->hasMoreElements() )
[ # # ]
1104 : : {
1105 [ # # ][ # # ]: 0 : Reference< XAnimate > xAnimate( xE->nextElement(), UNO_QUERY );
[ # # ]
1106 [ # # ]: 0 : if( xAnimate.is() )
1107 : : {
1108 [ # # ][ # # ]: 0 : xAnimate->setTarget( aTarget );
1109 [ # # ][ # # ]: 0 : xAnimate->setSubItem( nTargetSubItem );
1110 : : }
1111 : 0 : }
1112 : : }
1113 : :
1114 : 0 : mnIterateType = nIterateType;
1115 : :
1116 : : // if we have an iteration container, we must set its type
1117 [ # # ]: 0 : if( mnIterateType )
1118 : : {
1119 [ # # ]: 0 : Reference< XIterateContainer > xIter( mxNode, UNO_QUERY_THROW );
1120 [ # # ][ # # ]: 0 : xIter->setIterateType( nIterateType );
[ # # ]
1121 : : }
1122 : :
1123 [ # # ]: 0 : checkForText();
1124 : : }
1125 : 0 : catch( Exception& )
1126 : : {
1127 : : OSL_FAIL( "sd::CustomAnimationEffect::setIterateType(), Exception cought!" );
1128 : : }
1129 : 0 : }
1130 : :
1131 : : // --------------------------------------------------------------------
1132 : :
1133 : 0 : void CustomAnimationEffect::setIterateInterval( double fIterateInterval )
1134 : : {
1135 [ # # ]: 0 : if( mfIterateInterval != fIterateInterval )
1136 : : {
1137 [ # # ]: 0 : Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
1138 : :
1139 : : DBG_ASSERT( xIter.is(), "sd::CustomAnimationEffect::setIterateInterval(), not an iteration node" );
1140 [ # # ]: 0 : if( xIter.is() )
1141 : : {
1142 : 0 : mfIterateInterval = fIterateInterval;
1143 [ # # ][ # # ]: 0 : xIter->setIterateInterval( fIterateInterval );
1144 : : }
1145 : :
1146 [ # # ]: 0 : calculateIterateDuration();
1147 : : }
1148 : 0 : }
1149 : :
1150 : : // --------------------------------------------------------------------
1151 : :
1152 : 0 : ::rtl::OUString CustomAnimationEffect::getPath() const
1153 : : {
1154 : 0 : ::rtl::OUString aPath;
1155 : :
1156 [ # # ]: 0 : if( mxNode.is() ) try
1157 : : {
1158 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY_THROW );
1159 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
1160 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
1161 : : {
1162 [ # # ][ # # ]: 0 : Reference< XAnimateMotion > xMotion( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1163 [ # # ]: 0 : if( xMotion.is() )
1164 : : {
1165 [ # # ][ # # ]: 0 : xMotion->getPath() >>= aPath;
1166 : : break;
1167 : : }
1168 [ # # ][ # # ]: 0 : }
1169 : : }
1170 [ # # ]: 0 : catch( Exception& )
1171 : : {
1172 : : OSL_FAIL("sd::CustomAnimationEffect::getPath(), exception cought!" );
1173 : : }
1174 : :
1175 : 0 : return aPath;
1176 : : }
1177 : :
1178 : : // --------------------------------------------------------------------
1179 : :
1180 : 0 : void CustomAnimationEffect::setPath( const ::rtl::OUString& rPath )
1181 : : {
1182 [ # # ]: 0 : if( mxNode.is() ) try
1183 : : {
1184 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY_THROW );
1185 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
1186 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
1187 : : {
1188 [ # # ][ # # ]: 0 : Reference< XAnimateMotion > xMotion( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1189 [ # # ]: 0 : if( xMotion.is() )
1190 : : {
1191 : :
1192 : 0 : MainSequenceChangeGuard aGuard( mpEffectSequence );
1193 [ # # ][ # # ]: 0 : xMotion->setPath( Any( rPath ) );
[ # # ]
1194 : 0 : break;
1195 : : }
1196 [ # # ][ # # ]: 0 : }
1197 : : }
1198 : 0 : catch( Exception& )
1199 : : {
1200 : : OSL_FAIL("sd::CustomAnimationEffect::setPath(), exception cought!" );
1201 : : }
1202 : 0 : }
1203 : :
1204 : : // --------------------------------------------------------------------
1205 : :
1206 : 0 : Any CustomAnimationEffect::getProperty( sal_Int32 nNodeType, const OUString& rAttributeName, EValue eValue )
1207 : : {
1208 : 0 : Any aProperty;
1209 [ # # ]: 0 : if( mxNode.is() ) try
1210 : : {
1211 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
1212 [ # # ]: 0 : if( xEnumerationAccess.is() )
1213 : : {
1214 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
1215 [ # # ]: 0 : if( xEnumeration.is() )
1216 : : {
1217 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() && !aProperty.hasValue() )
[ # # ][ # # ]
[ # # ]
1218 : : {
1219 [ # # ][ # # ]: 0 : Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1220 [ # # ]: 0 : if( !xAnimate.is() )
1221 : 0 : continue;
1222 : :
1223 [ # # ][ # # ]: 0 : if( xAnimate->getType() == nNodeType )
[ # # ]
1224 : : {
1225 [ # # ][ # # ]: 0 : if( xAnimate->getAttributeName() == rAttributeName )
[ # # ]
1226 : : {
1227 [ # # # # : 0 : switch( eValue )
# ]
1228 : : {
1229 [ # # ][ # # ]: 0 : case VALUE_FROM: aProperty = xAnimate->getFrom(); break;
1230 [ # # ][ # # ]: 0 : case VALUE_TO: aProperty = xAnimate->getTo(); break;
1231 [ # # ][ # # ]: 0 : case VALUE_BY: aProperty = xAnimate->getBy(); break;
1232 : : case VALUE_FIRST:
1233 : : case VALUE_LAST:
1234 : : {
1235 [ # # ][ # # ]: 0 : Sequence<Any> aValues( xAnimate->getValues() );
1236 [ # # ]: 0 : if( aValues.hasElements() )
1237 [ # # ][ # # ]: 0 : aProperty = aValues[ eValue == VALUE_FIRST ? 0 : aValues.getLength() - 1 ];
[ # # ]
1238 : : }
1239 : 0 : break;
1240 : : }
1241 : : }
1242 : : }
1243 [ # # ]: 0 : }
1244 : 0 : }
1245 [ # # ]: 0 : }
1246 : : }
1247 [ # # ]: 0 : catch( Exception& )
1248 : : {
1249 : : OSL_FAIL("sd::CustomAnimationEffect::getProperty(), exception cought!" );
1250 : : }
1251 : :
1252 : 0 : return aProperty;
1253 : : }
1254 : :
1255 : : // --------------------------------------------------------------------
1256 : :
1257 : 0 : bool CustomAnimationEffect::setProperty( sal_Int32 nNodeType, const OUString& rAttributeName, EValue eValue, const Any& rValue )
1258 : : {
1259 : 0 : bool bChanged = false;
1260 [ # # ]: 0 : if( mxNode.is() ) try
1261 : : {
1262 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
1263 [ # # ]: 0 : if( xEnumerationAccess.is() )
1264 : : {
1265 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
1266 [ # # ]: 0 : if( xEnumeration.is() )
1267 : : {
1268 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
1269 : : {
1270 [ # # ][ # # ]: 0 : Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1271 [ # # ]: 0 : if( !xAnimate.is() )
1272 : 0 : continue;
1273 : :
1274 [ # # ][ # # ]: 0 : if( xAnimate->getType() == nNodeType )
[ # # ]
1275 : : {
1276 [ # # ][ # # ]: 0 : if( xAnimate->getAttributeName() == rAttributeName )
[ # # ]
1277 : : {
1278 [ # # # # : 0 : switch( eValue )
# ]
1279 : : {
1280 : : case VALUE_FROM:
1281 [ # # ][ # # ]: 0 : if( xAnimate->getFrom() != rValue )
[ # # ]
1282 : : {
1283 [ # # ][ # # ]: 0 : xAnimate->setFrom( rValue );
1284 : 0 : bChanged = true;
1285 : : }
1286 : 0 : break;
1287 : : case VALUE_TO:
1288 [ # # ][ # # ]: 0 : if( xAnimate->getTo() != rValue )
[ # # ]
1289 : : {
1290 [ # # ][ # # ]: 0 : xAnimate->setTo( rValue );
1291 : 0 : bChanged = true;
1292 : : }
1293 : 0 : break;
1294 : : case VALUE_BY:
1295 [ # # ][ # # ]: 0 : if( xAnimate->getTo() != rValue )
[ # # ]
1296 : : {
1297 [ # # ][ # # ]: 0 : xAnimate->setBy( rValue );
1298 : 0 : bChanged = true;
1299 : : }
1300 : 0 : break;
1301 : : case VALUE_FIRST:
1302 : : case VALUE_LAST:
1303 : : {
1304 [ # # ][ # # ]: 0 : Sequence<Any> aValues( xAnimate->getValues() );
1305 [ # # ]: 0 : if( !aValues.hasElements() )
1306 [ # # ]: 0 : aValues.realloc(1);
1307 : :
1308 [ # # ]: 0 : sal_Int32 nIndex = eValue == VALUE_FIRST ? 0 : aValues.getLength() - 1;
1309 : :
1310 [ # # ][ # # ]: 0 : if( aValues[ nIndex ] != rValue )
1311 : : {
1312 [ # # ]: 0 : aValues[ nIndex ] = rValue;
1313 [ # # ][ # # ]: 0 : xAnimate->setValues( aValues );
1314 : 0 : bChanged = true;
1315 [ # # ]: 0 : }
1316 : : }
1317 : : }
1318 : : }
1319 : : }
1320 [ # # ]: 0 : }
1321 : 0 : }
1322 [ # # ]: 0 : }
1323 : : }
1324 : 0 : catch( Exception& )
1325 : : {
1326 : : OSL_FAIL("sd::CustomAnimationEffect::setProperty(), exception cought!" );
1327 : : }
1328 : :
1329 : 0 : return bChanged;
1330 : : }
1331 : :
1332 : : // --------------------------------------------------------------------
1333 : :
1334 : 0 : static bool implIsColorAttribute( const OUString& rAttributeName )
1335 : : {
1336 [ # # ][ # # ]: 0 : return rAttributeName == "FillColor" || rAttributeName == "LineColor" || rAttributeName == "CharColor";
[ # # ]
1337 : : }
1338 : :
1339 : : // --------------------------------------------------------------------
1340 : :
1341 : 0 : Any CustomAnimationEffect::getColor( sal_Int32 nIndex )
1342 : : {
1343 : 0 : Any aColor;
1344 [ # # ]: 0 : if( mxNode.is() ) try
1345 : : {
1346 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
1347 [ # # ]: 0 : if( xEnumerationAccess.is() )
1348 : : {
1349 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
1350 [ # # ]: 0 : if( xEnumeration.is() )
1351 : : {
1352 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() && !aColor.hasValue() )
[ # # ][ # # ]
[ # # ]
1353 : : {
1354 [ # # ][ # # ]: 0 : Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1355 [ # # ]: 0 : if( !xAnimate.is() )
1356 : 0 : continue;
1357 : :
1358 [ # # ][ # # ]: 0 : switch( xAnimate->getType() )
[ # # # ]
1359 : : {
1360 : : case AnimationNodeType::SET:
1361 : : case AnimationNodeType::ANIMATE:
1362 [ # # ][ # # ]: 0 : if( !implIsColorAttribute( xAnimate->getAttributeName() ) )
[ # # ][ # # ]
1363 : : break;
1364 : : case AnimationNodeType::ANIMATECOLOR:
1365 [ # # ][ # # ]: 0 : Sequence<Any> aValues( xAnimate->getValues() );
1366 [ # # ]: 0 : if( aValues.hasElements() )
1367 : : {
1368 [ # # ]: 0 : if( aValues.getLength() > nIndex )
1369 [ # # ]: 0 : aColor = aValues[nIndex];
1370 : : }
1371 [ # # ]: 0 : else if( nIndex == 0 )
1372 [ # # ][ # # ]: 0 : aColor = xAnimate->getFrom();
1373 : : else
1374 [ # # ][ # # ]: 0 : aColor = xAnimate->getTo();
[ # # ]
1375 : : }
1376 [ # # ]: 0 : }
1377 : 0 : }
1378 [ # # ]: 0 : }
1379 : : }
1380 [ # # ]: 0 : catch( Exception& )
1381 : : {
1382 : : OSL_FAIL("sd::CustomAnimationEffect::getColor(), exception cought!" );
1383 : : }
1384 : :
1385 : 0 : return aColor;
1386 : : }
1387 : :
1388 : : // --------------------------------------------------------------------
1389 : :
1390 : 0 : void CustomAnimationEffect::setColor( sal_Int32 nIndex, const Any& rColor )
1391 : : {
1392 [ # # ]: 0 : if( mxNode.is() ) try
1393 : : {
1394 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
1395 [ # # ]: 0 : if( xEnumerationAccess.is() )
1396 : : {
1397 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
1398 [ # # ]: 0 : if( xEnumeration.is() )
1399 : : {
1400 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
1401 : : {
1402 [ # # ][ # # ]: 0 : Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1403 [ # # ]: 0 : if( !xAnimate.is() )
1404 : 0 : continue;
1405 : :
1406 [ # # ][ # # ]: 0 : switch( xAnimate->getType() )
[ # # # ]
1407 : : {
1408 : : case AnimationNodeType::SET:
1409 : : case AnimationNodeType::ANIMATE:
1410 [ # # ][ # # ]: 0 : if( !implIsColorAttribute( xAnimate->getAttributeName() ) )
[ # # ][ # # ]
1411 : 0 : break;
1412 : : case AnimationNodeType::ANIMATECOLOR:
1413 : : {
1414 [ # # ][ # # ]: 0 : Sequence<Any> aValues( xAnimate->getValues() );
1415 [ # # ]: 0 : if( aValues.hasElements() )
1416 : : {
1417 [ # # ]: 0 : if( aValues.getLength() > nIndex )
1418 : : {
1419 [ # # ]: 0 : aValues[nIndex] = rColor;
1420 [ # # ][ # # ]: 0 : xAnimate->setValues( aValues );
1421 : : }
1422 : : }
1423 [ # # ][ # # ]: 0 : else if( (nIndex == 0) && xAnimate->getFrom().hasValue() )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1424 [ # # ][ # # ]: 0 : xAnimate->setFrom(rColor);
1425 [ # # ][ # # ]: 0 : else if( (nIndex == 1) && xAnimate->getTo().hasValue() )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1426 [ # # ][ # # ]: 0 : xAnimate->setTo(rColor);
[ # # ]
1427 : : }
1428 : 0 : break;
1429 : :
1430 : : }
1431 [ # # ]: 0 : }
1432 : 0 : }
1433 [ # # ]: 0 : }
1434 : : }
1435 : 0 : catch( Exception& )
1436 : : {
1437 : : OSL_FAIL("sd::CustomAnimationEffect::setColor(), exception cought!" );
1438 : : }
1439 : 0 : }
1440 : :
1441 : : // --------------------------------------------------------------------
1442 : :
1443 : 0 : Any CustomAnimationEffect::getTransformationProperty( sal_Int32 nTransformType, EValue eValue )
1444 : : {
1445 : 0 : Any aProperty;
1446 [ # # ]: 0 : if( mxNode.is() ) try
1447 : : {
1448 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
1449 [ # # ]: 0 : if( xEnumerationAccess.is() )
1450 : : {
1451 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
1452 [ # # ]: 0 : if( xEnumeration.is() )
1453 : : {
1454 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() && !aProperty.hasValue() )
[ # # ][ # # ]
[ # # ]
1455 : : {
1456 [ # # ][ # # ]: 0 : Reference< XAnimateTransform > xTransform( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1457 [ # # ]: 0 : if( !xTransform.is() )
1458 : 0 : continue;
1459 : :
1460 [ # # ][ # # ]: 0 : if( xTransform->getTransformType() == nTransformType )
[ # # ]
1461 : : {
1462 [ # # # # : 0 : switch( eValue )
# ]
1463 : : {
1464 [ # # ][ # # ]: 0 : case VALUE_FROM: aProperty = xTransform->getFrom(); break;
1465 [ # # ][ # # ]: 0 : case VALUE_TO: aProperty = xTransform->getTo(); break;
1466 [ # # ][ # # ]: 0 : case VALUE_BY: aProperty = xTransform->getBy(); break;
1467 : : case VALUE_FIRST:
1468 : : case VALUE_LAST:
1469 : : {
1470 [ # # ][ # # ]: 0 : Sequence<Any> aValues( xTransform->getValues() );
1471 [ # # ]: 0 : if( aValues.hasElements() )
1472 [ # # ][ # # ]: 0 : aProperty = aValues[ eValue == VALUE_FIRST ? 0 : aValues.getLength() - 1 ];
[ # # ]
1473 : : }
1474 : 0 : break;
1475 : : }
1476 : : }
1477 [ # # ]: 0 : }
1478 : 0 : }
1479 [ # # ]: 0 : }
1480 : : }
1481 [ # # ]: 0 : catch( Exception& )
1482 : : {
1483 : : OSL_FAIL("sd::CustomAnimationEffect::getTransformationProperty(), exception cought!" );
1484 : : }
1485 : :
1486 : 0 : return aProperty;
1487 : : }
1488 : :
1489 : : // --------------------------------------------------------------------
1490 : :
1491 : 0 : bool CustomAnimationEffect::setTransformationProperty( sal_Int32 nTransformType, EValue eValue, const Any& rValue )
1492 : : {
1493 : 0 : bool bChanged = false;
1494 [ # # ]: 0 : if( mxNode.is() ) try
1495 : : {
1496 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxNode, UNO_QUERY );
1497 [ # # ]: 0 : if( xEnumerationAccess.is() )
1498 : : {
1499 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
[ # # ]
1500 [ # # ]: 0 : if( xEnumeration.is() )
1501 : : {
1502 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
1503 : : {
1504 [ # # ][ # # ]: 0 : Reference< XAnimateTransform > xTransform( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1505 [ # # ]: 0 : if( !xTransform.is() )
1506 : 0 : continue;
1507 : :
1508 [ # # ][ # # ]: 0 : if( xTransform->getTransformType() == nTransformType )
[ # # ]
1509 : : {
1510 [ # # # # : 0 : switch( eValue )
# ]
1511 : : {
1512 : : case VALUE_FROM:
1513 [ # # ][ # # ]: 0 : if( xTransform->getFrom() != rValue )
[ # # ]
1514 : : {
1515 [ # # ][ # # ]: 0 : xTransform->setFrom( rValue );
1516 : 0 : bChanged = true;
1517 : : }
1518 : 0 : break;
1519 : : case VALUE_TO:
1520 [ # # ][ # # ]: 0 : if( xTransform->getTo() != rValue )
[ # # ]
1521 : : {
1522 [ # # ][ # # ]: 0 : xTransform->setTo( rValue );
1523 : 0 : bChanged = true;
1524 : : }
1525 : 0 : break;
1526 : : case VALUE_BY:
1527 [ # # ][ # # ]: 0 : if( xTransform->getBy() != rValue )
[ # # ]
1528 : : {
1529 [ # # ][ # # ]: 0 : xTransform->setBy( rValue );
1530 : 0 : bChanged = true;
1531 : : }
1532 : 0 : break;
1533 : : case VALUE_FIRST:
1534 : : case VALUE_LAST:
1535 : : {
1536 [ # # ][ # # ]: 0 : Sequence<Any> aValues( xTransform->getValues() );
1537 [ # # ]: 0 : if( !aValues.hasElements() )
1538 [ # # ]: 0 : aValues.realloc(1);
1539 : :
1540 [ # # ]: 0 : sal_Int32 nIndex = eValue == VALUE_FIRST ? 0 : aValues.getLength() - 1;
1541 [ # # ][ # # ]: 0 : if( aValues[nIndex] != rValue )
1542 : : {
1543 [ # # ]: 0 : aValues[nIndex] = rValue;
1544 [ # # ][ # # ]: 0 : xTransform->setValues( aValues );
1545 : 0 : bChanged = true;
1546 [ # # ]: 0 : }
1547 : : }
1548 : : }
1549 : : }
1550 [ # # ]: 0 : }
1551 : 0 : }
1552 [ # # ]: 0 : }
1553 : : }
1554 : 0 : catch( Exception& )
1555 : : {
1556 : : OSL_FAIL("sd::CustomAnimationEffect::setTransformationProperty(), exception cought!" );
1557 : : }
1558 : :
1559 : 0 : return bChanged;
1560 : : }
1561 : :
1562 : : // --------------------------------------------------------------------
1563 : :
1564 : 0 : void CustomAnimationEffect::createAudio( const ::com::sun::star::uno::Any& rSource, double fVolume /* = 1.0 */ )
1565 : : {
1566 : : DBG_ASSERT( !mxAudio.is(), "sd::CustomAnimationEffect::createAudio(), node already has an audio!" );
1567 : :
1568 [ # # ]: 0 : if( !mxAudio.is() ) try
1569 : : {
1570 [ # # ]: 0 : Reference< XMultiServiceFactory > xMsf( ::comphelper::getProcessServiceFactory() );
1571 [ # # ][ # # ]: 0 : Reference< XAudio > xAudio( xMsf->createInstance( "com.sun.star.animations.Audio" ), UNO_QUERY_THROW );
[ # # ]
1572 [ # # ][ # # ]: 0 : xAudio->setSource( rSource );
1573 [ # # ][ # # ]: 0 : xAudio->setVolume( fVolume );
1574 [ # # ][ # # ]: 0 : setAudio( xAudio );
1575 : : }
1576 : 0 : catch( Exception& )
1577 : : {
1578 : : OSL_FAIL("sd::CustomAnimationEffect::createAudio(), exception cought!" );
1579 : : }
1580 : 0 : }
1581 : :
1582 : : // --------------------------------------------------------------------
1583 : :
1584 : 0 : static Reference< XCommand > findCommandNode( const Reference< XAnimationNode >& xRootNode )
1585 : : {
1586 : 0 : Reference< XCommand > xCommand;
1587 : :
1588 [ # # ]: 0 : if( xRootNode.is() ) try
1589 : : {
1590 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
1591 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
1592 [ # # ][ # # ]: 0 : while( !xCommand.is() && xEnumeration->hasMoreElements() )
[ # # ][ # # ]
[ # # ]
1593 : : {
1594 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
1595 [ # # ][ # # ]: 0 : if( xNode.is() && (xNode->getType() == AnimationNodeType::COMMAND) )
[ # # ][ # # ]
[ # # ]
1596 [ # # ]: 0 : xCommand.set( xNode, UNO_QUERY_THROW );
1597 [ # # ]: 0 : }
1598 : : }
1599 [ # # ]: 0 : catch( Exception& )
1600 : : {
1601 : : OSL_FAIL("sd::findCommandNode(), exception caught!" );
1602 : : }
1603 : :
1604 : 0 : return xCommand;
1605 : : }
1606 : :
1607 : 0 : void CustomAnimationEffect::removeAudio()
1608 : : {
1609 : : try
1610 : : {
1611 : 0 : Reference< XAnimationNode > xChild;
1612 : :
1613 [ # # ]: 0 : if( mxAudio.is() )
1614 : : {
1615 [ # # ]: 0 : xChild.set( mxAudio, UNO_QUERY );
1616 : 0 : mxAudio.clear();
1617 : : }
1618 [ # # ]: 0 : else if( mnCommand == EffectCommands::STOPAUDIO )
1619 : : {
1620 [ # # ][ # # ]: 0 : xChild.set( findCommandNode( mxNode ), UNO_QUERY );
1621 : 0 : mnCommand = 0;
1622 : : }
1623 : :
1624 [ # # ]: 0 : if( xChild.is() )
1625 : : {
1626 [ # # ]: 0 : Reference< XTimeContainer > xContainer( mxNode, UNO_QUERY );
1627 [ # # ]: 0 : if( xContainer.is() )
1628 [ # # ][ # # ]: 0 : xContainer->removeChild( xChild );
1629 [ # # ]: 0 : }
1630 : : }
1631 : 0 : catch( Exception& )
1632 : : {
1633 : : OSL_FAIL("sd::CustomAnimationEffect::removeAudio(), exception caught!" );
1634 : : }
1635 : :
1636 : 0 : }
1637 : :
1638 : : // --------------------------------------------------------------------
1639 : :
1640 : 0 : void CustomAnimationEffect::setAudio( const Reference< ::com::sun::star::animations::XAudio >& xAudio )
1641 : : {
1642 [ # # ]: 0 : if( mxAudio != xAudio ) try
1643 : : {
1644 [ # # ]: 0 : removeAudio();
1645 [ # # ]: 0 : mxAudio = xAudio;
1646 [ # # ]: 0 : Reference< XTimeContainer > xContainer( mxNode, UNO_QUERY );
1647 [ # # ]: 0 : Reference< XAnimationNode > xChild( mxAudio, UNO_QUERY );
1648 [ # # ][ # # ]: 0 : if( xContainer.is() && xChild.is() )
[ # # ]
1649 [ # # ][ # # ]: 0 : xContainer->appendChild( xChild );
[ # # ]
1650 : : }
1651 : 0 : catch( Exception& )
1652 : : {
1653 : : OSL_FAIL("sd::CustomAnimationEffect::setAudio(), exception caught!" );
1654 : : }
1655 : 0 : }
1656 : :
1657 : : // --------------------------------------------------------------------
1658 : :
1659 : 0 : void CustomAnimationEffect::setStopAudio()
1660 : : {
1661 [ # # ]: 0 : if( mnCommand != EffectCommands::STOPAUDIO ) try
1662 : : {
1663 [ # # ]: 0 : if( mxAudio.is() )
1664 [ # # ]: 0 : removeAudio();
1665 : :
1666 [ # # ]: 0 : Reference< XMultiServiceFactory > xMsf( ::comphelper::getProcessServiceFactory() );
1667 [ # # ][ # # ]: 0 : Reference< XCommand > xCommand( xMsf->createInstance( "com.sun.star.animations.Command" ), UNO_QUERY_THROW );
[ # # ]
1668 : :
1669 [ # # ][ # # ]: 0 : xCommand->setCommand( EffectCommands::STOPAUDIO );
1670 : :
1671 [ # # ]: 0 : Reference< XTimeContainer > xContainer( mxNode, UNO_QUERY_THROW );
1672 [ # # ]: 0 : Reference< XAnimationNode > xChild( xCommand, UNO_QUERY_THROW );
1673 [ # # ][ # # ]: 0 : xContainer->appendChild( xChild );
1674 : :
1675 [ # # ]: 0 : mnCommand = EffectCommands::STOPAUDIO;
1676 : : }
1677 : 0 : catch( Exception& )
1678 : : {
1679 : : OSL_FAIL("sd::CustomAnimationEffect::setStopAudio(), exception caught!" );
1680 : : }
1681 : 0 : }
1682 : :
1683 : : // --------------------------------------------------------------------
1684 : :
1685 : 0 : bool CustomAnimationEffect::getStopAudio() const
1686 : : {
1687 : 0 : return mnCommand == EffectCommands::STOPAUDIO;
1688 : : }
1689 : :
1690 : : // --------------------------------------------------------------------
1691 : :
1692 : 0 : SdrPathObj* CustomAnimationEffect::createSdrPathObjFromPath()
1693 : : {
1694 [ # # ]: 0 : SdrPathObj * pPathObj = new SdrPathObj( OBJ_PATHLINE );
1695 : 0 : updateSdrPathObjFromPath( *pPathObj );
1696 : 0 : return pPathObj;
1697 : : }
1698 : :
1699 : : // --------------------------------------------------------------------
1700 : :
1701 : 0 : void CustomAnimationEffect::updateSdrPathObjFromPath( SdrPathObj& rPathObj )
1702 : : {
1703 [ # # ]: 0 : ::basegfx::B2DPolyPolygon xPolyPoly;
1704 [ # # ][ # # ]: 0 : if( ::basegfx::tools::importFromSvgD( xPolyPoly, getPath() ) )
[ # # ]
1705 : : {
1706 [ # # ]: 0 : SdrObject* pObj = GetSdrObjectFromXShape( getTargetShape() );
1707 [ # # ]: 0 : if( pObj )
1708 : : {
1709 [ # # ]: 0 : SdrPage* pPage = pObj->GetPage();
1710 [ # # ]: 0 : if( pPage )
1711 : : {
1712 [ # # ]: 0 : const Size aPageSize( pPage->GetSize() );
1713 [ # # ][ # # ]: 0 : xPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix((double)aPageSize.Width(), (double)aPageSize.Height()));
[ # # ]
1714 : : }
1715 : :
1716 [ # # ]: 0 : const Rectangle aBoundRect( pObj->GetCurrentBoundRect() );
1717 [ # # ]: 0 : const Point aCenter( aBoundRect.Center() );
1718 [ # # ][ # # ]: 0 : xPolyPoly.transform(basegfx::tools::createTranslateB2DHomMatrix(aCenter.X(), aCenter.Y()));
[ # # ]
1719 : : }
1720 : : }
1721 : :
1722 [ # # ][ # # ]: 0 : rPathObj.SetPathPoly( xPolyPoly );
1723 : 0 : }
1724 : :
1725 : : // --------------------------------------------------------------------
1726 : :
1727 : 0 : void CustomAnimationEffect::updatePathFromSdrPathObj( const SdrPathObj& rPathObj )
1728 : : {
1729 [ # # ]: 0 : ::basegfx::B2DPolyPolygon xPolyPoly( rPathObj.GetPathPoly() );
1730 : :
1731 [ # # ]: 0 : SdrObject* pObj = GetSdrObjectFromXShape( getTargetShape() );
1732 [ # # ]: 0 : if( pObj )
1733 : : {
1734 [ # # ]: 0 : Rectangle aBoundRect(0,0,0,0);
1735 : :
1736 [ # # ][ # # ]: 0 : const drawinglayer::primitive2d::Primitive2DSequence xPrimitives(pObj->GetViewContact().getViewIndependentPrimitive2DSequence());
1737 [ # # ]: 0 : const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
1738 [ # # ]: 0 : const basegfx::B2DRange aRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xPrimitives, aViewInformation2D));
1739 : :
1740 [ # # ][ # # ]: 0 : if(!aRange.isEmpty())
1741 : : {
1742 : : aBoundRect = Rectangle(
1743 [ # # ][ # # ]: 0 : (sal_Int32)floor(aRange.getMinX()), (sal_Int32)floor(aRange.getMinY()),
1744 [ # # ][ # # ]: 0 : (sal_Int32)ceil(aRange.getMaxX()), (sal_Int32)ceil(aRange.getMaxY()));
[ # # ]
1745 : : }
1746 : :
1747 [ # # ]: 0 : const Point aCenter( aBoundRect.Center() );
1748 : :
1749 [ # # ][ # # ]: 0 : xPolyPoly.transform(basegfx::tools::createTranslateB2DHomMatrix(-aCenter.X(), -aCenter.Y()));
[ # # ]
1750 : :
1751 [ # # ]: 0 : SdrPage* pPage = pObj->GetPage();
1752 [ # # ]: 0 : if( pPage )
1753 : : {
1754 [ # # ]: 0 : const Size aPageSize( pPage->GetSize() );
1755 : : xPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(
1756 [ # # ][ # # ]: 0 : 1.0 / (double)aPageSize.Width(), 1.0 / (double)aPageSize.Height()));
[ # # ]
1757 [ # # ][ # # ]: 0 : }
1758 : : }
1759 : :
1760 [ # # ][ # # ]: 0 : setPath( ::basegfx::tools::exportToSvgD( xPolyPoly ) );
[ # # ]
1761 : 0 : }
1762 : :
1763 : : // ====================================================================
1764 : :
1765 : 4 : EffectSequenceHelper::EffectSequenceHelper()
1766 [ + - ][ + - ]: 4 : : mnSequenceType( EffectNodeType::DEFAULT )
[ + - ]
1767 : : {
1768 : 4 : }
1769 : :
1770 : : // --------------------------------------------------------------------
1771 : :
1772 : 0 : EffectSequenceHelper::EffectSequenceHelper( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XTimeContainer >& xSequenceRoot )
1773 [ # # ][ # # ]: 0 : : mxSequenceRoot( xSequenceRoot ), mnSequenceType( EffectNodeType::DEFAULT )
[ # # ]
1774 : : {
1775 [ # # ]: 0 : Reference< XAnimationNode > xNode( mxSequenceRoot, UNO_QUERY_THROW );
1776 [ # # ]: 0 : create( xNode );
1777 : 0 : }
1778 : :
1779 : : // --------------------------------------------------------------------
1780 : :
1781 : 4 : EffectSequenceHelper::~EffectSequenceHelper()
1782 : : {
1783 [ + - ]: 4 : reset();
1784 [ - + ]: 4 : }
1785 : :
1786 : : // --------------------------------------------------------------------
1787 : :
1788 : 8 : void EffectSequenceHelper::reset()
1789 : : {
1790 : 8 : EffectSequence::iterator aIter( maEffects.begin() );
1791 : 8 : EffectSequence::iterator aEnd( maEffects.end() );
1792 [ - + ]: 8 : if( aIter != aEnd )
1793 : : {
1794 [ # # ]: 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
1795 [ # # ]: 0 : pEffect->setEffectSequence(0);
1796 : : }
1797 : 8 : maEffects.clear();
1798 : 8 : }
1799 : :
1800 : 0 : Reference< XAnimationNode > EffectSequenceHelper::getRootNode()
1801 : : {
1802 : 0 : Reference< XAnimationNode > xRoot( mxSequenceRoot, UNO_QUERY );
1803 : 0 : return xRoot;
1804 : : }
1805 : :
1806 : : // --------------------------------------------------------------------
1807 : :
1808 : 0 : void EffectSequenceHelper::append( const CustomAnimationEffectPtr& pEffect )
1809 : : {
1810 : 0 : pEffect->setEffectSequence( this );
1811 : 0 : maEffects.push_back(pEffect);
1812 : 0 : rebuild();
1813 : 0 : }
1814 : :
1815 : : // --------------------------------------------------------------------
1816 : :
1817 : 0 : CustomAnimationEffectPtr EffectSequenceHelper::append( const CustomAnimationPresetPtr& pPreset, const Any& rTarget, double fDuration /* = -1.0 */ )
1818 : : {
1819 : 0 : CustomAnimationEffectPtr pEffect;
1820 : :
1821 [ # # ]: 0 : if( pPreset.get() )
1822 : : {
1823 : 0 : OUString strEmpty;
1824 [ # # ]: 0 : Reference< XAnimationNode > xNode( pPreset->create( strEmpty ) );
1825 [ # # ]: 0 : if( xNode.is() )
1826 : : {
1827 : : // first, filter all only ui relevant user data
1828 [ # # ]: 0 : std::vector< NamedValue > aNewUserData;
1829 [ # # ][ # # ]: 0 : Sequence< NamedValue > aUserData( xNode->getUserData() );
1830 : 0 : sal_Int32 nLength = aUserData.getLength();
1831 : 0 : const NamedValue* p = aUserData.getConstArray();
1832 : 0 : bool bFilter = false;
1833 : :
1834 [ # # ]: 0 : while( nLength-- )
1835 : : {
1836 [ # # ][ # # ]: 0 : if( p->Name != "text-only" && p->Name != "preset-property" )
[ # # ]
1837 : : {
1838 [ # # ]: 0 : aNewUserData.push_back( *p );
1839 : 0 : bFilter = true;
1840 : : }
1841 : 0 : p++;
1842 : : }
1843 : :
1844 [ # # ]: 0 : if( bFilter )
1845 : : {
1846 [ # # ][ # # ]: 0 : aUserData = ::comphelper::containerToSequence< NamedValue, std::vector< NamedValue > >( aNewUserData );
[ # # ]
1847 [ # # ][ # # ]: 0 : xNode->setUserData( aUserData );
1848 : : }
1849 : :
1850 : : // check target, maybe we need to force it to text
1851 : 0 : Any aTarget( rTarget );
1852 : 0 : sal_Int16 nSubItem = ShapeAnimationSubType::AS_WHOLE;
1853 : :
1854 [ # # ][ # # ]: 0 : if( aTarget.getValueType() == ::getCppuType((const ParagraphTarget*)0) )
1855 : : {
1856 : 0 : nSubItem = ShapeAnimationSubType::ONLY_TEXT;
1857 : : }
1858 [ # # ]: 0 : else if( pPreset->isTextOnly() )
1859 : : {
1860 : 0 : Reference< XShape > xShape;
1861 [ # # ]: 0 : aTarget >>= xShape;
1862 [ # # ]: 0 : if( xShape.is() )
1863 : : {
1864 : : // thats bad, we target a shape here but the effect is only for text
1865 : : // so change subitem
1866 : 0 : nSubItem = ShapeAnimationSubType::ONLY_TEXT;
1867 : 0 : }
1868 : : }
1869 : :
1870 : : // now create effect from preset
1871 [ # # ][ # # ]: 0 : pEffect.reset( new CustomAnimationEffect( xNode ) );
[ # # ]
1872 : 0 : pEffect->setEffectSequence( this );
1873 [ # # ]: 0 : pEffect->setTarget( aTarget );
1874 [ # # ]: 0 : pEffect->setTargetSubItem( nSubItem );
1875 [ # # ]: 0 : if( fDuration != -1.0 )
1876 [ # # ]: 0 : pEffect->setDuration( fDuration );
1877 : :
1878 [ # # ]: 0 : maEffects.push_back(pEffect);
1879 : :
1880 [ # # ][ # # ]: 0 : rebuild();
1881 : 0 : }
1882 : : }
1883 : :
1884 : : DBG_ASSERT( pEffect.get(), "sd::EffectSequenceHelper::append(), failed!" );
1885 : 0 : return pEffect;
1886 : : }
1887 : :
1888 : : // --------------------------------------------------------------------
1889 : :
1890 : 0 : CustomAnimationEffectPtr EffectSequenceHelper::append( const SdrPathObj& rPathObj, const Any& rTarget, double fDuration /* = -1.0 */ )
1891 : : {
1892 : 0 : CustomAnimationEffectPtr pEffect;
1893 : :
1894 [ # # ]: 0 : if( fDuration <= 0.0 )
1895 : 0 : fDuration = 2.0;
1896 : :
1897 : : try
1898 : : {
1899 [ # # ]: 0 : Reference< XTimeContainer > xEffectContainer( createParallelTimeContainer() );
1900 : 0 : const OUString aServiceName( "com.sun.star.animations.AnimateMotion" );
1901 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xAnimateMotion( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY_THROW );
[ # # ][ # # ]
1902 : :
1903 [ # # ][ # # ]: 0 : xAnimateMotion->setDuration( Any( fDuration ) );
[ # # ]
1904 [ # # ][ # # ]: 0 : xAnimateMotion->setFill( AnimationFill::HOLD );
1905 [ # # ][ # # ]: 0 : xEffectContainer->appendChild( xAnimateMotion );
1906 : :
1907 : 0 : sal_Int16 nSubItem = ShapeAnimationSubType::AS_WHOLE;
1908 : :
1909 [ # # ][ # # ]: 0 : if( rTarget.getValueType() == ::getCppuType((const ParagraphTarget*)0) )
1910 : 0 : nSubItem = ShapeAnimationSubType::ONLY_TEXT;
1911 : :
1912 [ # # ]: 0 : Reference< XAnimationNode > xEffectNode( xEffectContainer, UNO_QUERY_THROW );
1913 [ # # ][ # # ]: 0 : pEffect.reset( new CustomAnimationEffect( xEffectNode ) );
[ # # ]
1914 : 0 : pEffect->setEffectSequence( this );
1915 [ # # ]: 0 : pEffect->setTarget( rTarget );
1916 [ # # ]: 0 : pEffect->setTargetSubItem( nSubItem );
1917 [ # # ]: 0 : pEffect->setNodeType( ::com::sun::star::presentation::EffectNodeType::ON_CLICK );
1918 [ # # ]: 0 : pEffect->setPresetClass( ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH );
1919 [ # # ]: 0 : pEffect->setAcceleration( 0.5 );
1920 [ # # ]: 0 : pEffect->setDecelerate( 0.5 );
1921 [ # # ]: 0 : pEffect->setFill( AnimationFill::HOLD );
1922 [ # # ]: 0 : pEffect->setBegin( 0.0 );
1923 [ # # ]: 0 : pEffect->updatePathFromSdrPathObj( rPathObj );
1924 [ # # ]: 0 : if( fDuration != -1.0 )
1925 [ # # ]: 0 : pEffect->setDuration( fDuration );
1926 : :
1927 [ # # ]: 0 : maEffects.push_back(pEffect);
1928 : :
1929 [ # # ][ # # ]: 0 : rebuild();
1930 : : }
1931 [ # # ]: 0 : catch( Exception& )
1932 : : {
1933 : : OSL_FAIL( "sd::EffectSequenceHelper::append(), exception cought!" );
1934 : : }
1935 : :
1936 : 0 : return pEffect;
1937 : : }
1938 : :
1939 : : // --------------------------------------------------------------------
1940 : :
1941 : 0 : void EffectSequenceHelper::replace( const CustomAnimationEffectPtr& pEffect, const CustomAnimationPresetPtr& pPreset, const OUString& rPresetSubType, double fDuration /* = -1.0 */ )
1942 : : {
1943 [ # # ][ # # ]: 0 : if( pEffect.get() && pPreset.get() ) try
[ # # ]
1944 : : {
1945 [ # # ]: 0 : Reference< XAnimationNode > xNewNode( pPreset->create( rPresetSubType ) );
1946 [ # # ]: 0 : if( xNewNode.is() )
1947 : : {
1948 [ # # ]: 0 : pEffect->replaceNode( xNewNode );
1949 [ # # ]: 0 : if( fDuration != -1.0 )
1950 [ # # ]: 0 : pEffect->setDuration( fDuration );
1951 : : }
1952 : :
1953 [ # # ][ # # ]: 0 : rebuild();
1954 : : }
1955 : 0 : catch( Exception& )
1956 : : {
1957 : : OSL_FAIL( "sd::EffectSequenceHelper::replace(), exception cought!" );
1958 : : }
1959 : 0 : }
1960 : :
1961 : : // --------------------------------------------------------------------
1962 : :
1963 : 0 : void EffectSequenceHelper::replace( const CustomAnimationEffectPtr& pEffect, const CustomAnimationPresetPtr& pPreset, double fDuration /* = -1.0 */ )
1964 : : {
1965 : 0 : OUString strEmpty;
1966 [ # # ]: 0 : replace( pEffect, pPreset, strEmpty, fDuration );
1967 : 0 : }
1968 : :
1969 : : // --------------------------------------------------------------------
1970 : :
1971 : 0 : void EffectSequenceHelper::remove( const CustomAnimationEffectPtr& pEffect )
1972 : : {
1973 [ # # ]: 0 : if( pEffect.get() )
1974 : : {
1975 : 0 : pEffect->setEffectSequence( 0 );
1976 : 0 : maEffects.remove( pEffect );
1977 : : }
1978 : :
1979 : 0 : rebuild();
1980 : 0 : }
1981 : :
1982 : : // --------------------------------------------------------------------
1983 : :
1984 : 0 : void EffectSequenceHelper::rebuild()
1985 : : {
1986 : 0 : implRebuild();
1987 : 0 : }
1988 : :
1989 : : // --------------------------------------------------------------------
1990 : :
1991 : 0 : void EffectSequenceHelper::implRebuild()
1992 : : {
1993 : : try
1994 : : {
1995 : : // first we delete all time containers on the first two levels
1996 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxSequenceRoot, UNO_QUERY_THROW );
1997 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
1998 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
1999 : : {
2000 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
[ # # ]
2001 [ # # ]: 0 : Reference< XTimeContainer > xChildContainer( xChildNode, UNO_QUERY_THROW );
2002 : :
2003 [ # # ]: 0 : Reference< XEnumerationAccess > xChildEnumerationAccess( xChildNode, UNO_QUERY_THROW );
2004 [ # # ][ # # ]: 0 : Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
2005 [ # # ][ # # ]: 0 : while( xChildEnumeration->hasMoreElements() )
[ # # ]
2006 : : {
2007 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW );
[ # # ]
2008 [ # # ][ # # ]: 0 : xChildContainer->removeChild( xNode );
2009 : 0 : }
2010 : :
2011 [ # # ][ # # ]: 0 : mxSequenceRoot->removeChild( xChildNode );
2012 : 0 : }
2013 : :
2014 : : // second, rebuild main sequence
2015 : 0 : EffectSequence::iterator aIter( maEffects.begin() );
2016 : 0 : EffectSequence::iterator aEnd( maEffects.end() );
2017 [ # # ]: 0 : if( aIter != aEnd )
2018 : : {
2019 [ # # ]: 0 : AfterEffectNodeList aAfterEffects;
2020 : :
2021 [ # # ]: 0 : CustomAnimationEffectPtr pEffect = (*aIter++);
2022 : :
2023 : 0 : bool bFirst = true;
2024 [ # # ]: 0 : do
2025 : : {
2026 : : // create a par container for the next click node and all following with and after effects
2027 [ # # ]: 0 : Reference< XTimeContainer > xOnClickContainer( createParallelTimeContainer() );
2028 : :
2029 : 0 : Event aEvent;
2030 [ # # ]: 0 : if( mxEventSource.is() )
2031 : : {
2032 [ # # ]: 0 : aEvent.Source <<= mxEventSource;
2033 : 0 : aEvent.Trigger = EventTrigger::ON_CLICK;
2034 : : }
2035 : : else
2036 : : {
2037 : 0 : aEvent.Trigger = EventTrigger::ON_NEXT;
2038 : : }
2039 : 0 : aEvent.Repeat = 0;
2040 : :
2041 [ # # ]: 0 : Any aBegin( makeAny( aEvent ) );
2042 [ # # ]: 0 : if( bFirst )
2043 : : {
2044 : : // if the first node is not a click action, this click container
2045 : : // must not have INDEFINITE begin but start at 0s
2046 : 0 : bFirst = false;
2047 [ # # ]: 0 : if( pEffect->getNodeType() != EffectNodeType::ON_CLICK )
2048 [ # # ]: 0 : aBegin <<= (double)0.0;
2049 : : }
2050 : :
2051 [ # # ][ # # ]: 0 : xOnClickContainer->setBegin( aBegin );
2052 : :
2053 [ # # ]: 0 : Reference< XAnimationNode > xOnClickContainerNode( xOnClickContainer, UNO_QUERY_THROW );
2054 [ # # ][ # # ]: 0 : mxSequenceRoot->appendChild( xOnClickContainerNode );
2055 : :
2056 : 0 : double fBegin = 0.0;
2057 : :
2058 [ # # ]: 0 : do
[ # # # # ]
2059 : : {
2060 : : // create a par container for the current click or after effect node and all following with effects
2061 [ # # ]: 0 : Reference< XTimeContainer > xWithContainer( createParallelTimeContainer() );
2062 [ # # ]: 0 : Reference< XAnimationNode > xWithContainerNode( xWithContainer, UNO_QUERY_THROW );
2063 [ # # ][ # # ]: 0 : xWithContainer->setBegin( makeAny( fBegin ) );
[ # # ]
2064 [ # # ][ # # ]: 0 : xOnClickContainer->appendChild( xWithContainerNode );
2065 : :
2066 : 0 : double fDuration = 0.0;
2067 [ # # ]: 0 : do
[ # # # # ]
2068 : : {
2069 : 0 : Reference< XAnimationNode > xEffectNode( pEffect->getNode() );
2070 [ # # ][ # # ]: 0 : xWithContainer->appendChild( xEffectNode );
2071 : :
2072 [ # # ]: 0 : if( pEffect->hasAfterEffect() )
2073 : : {
2074 [ # # ]: 0 : Reference< XAnimationNode > xAfterEffect( pEffect->createAfterEffectNode() );
2075 [ # # ]: 0 : AfterEffectNode a( xAfterEffect, xEffectNode, pEffect->IsAfterEffectOnNext() );
2076 [ # # ][ # # ]: 0 : aAfterEffects.push_back( a );
2077 : : }
2078 : :
2079 : 0 : double fTemp = pEffect->getBegin() + pEffect->getAbsoluteDuration();
2080 [ # # ]: 0 : if( fTemp > fDuration )
2081 : 0 : fDuration = fTemp;
2082 : :
2083 [ # # ]: 0 : if( aIter != aEnd )
2084 [ # # ]: 0 : pEffect = (*aIter++);
2085 : : else
2086 [ # # ]: 0 : pEffect.reset();
2087 : : }
2088 : 0 : while( pEffect.get() && (pEffect->getNodeType() == EffectNodeType::WITH_PREVIOUS) );
2089 : :
2090 : 0 : fBegin += fDuration;
2091 : : }
2092 : 0 : while( pEffect.get() && (pEffect->getNodeType() != EffectNodeType::ON_CLICK) );
2093 : : }
2094 : 0 : while( pEffect.get() );
2095 : :
2096 : : // process after effect nodes
2097 [ # # ]: 0 : std::for_each( aAfterEffects.begin(), aAfterEffects.end(), stl_process_after_effect_node_func );
2098 : :
2099 [ # # ]: 0 : updateTextGroups();
2100 : :
2101 : : // reset duration, might have been altered (see below)
2102 [ # # ][ # # ]: 0 : mxSequenceRoot->setDuration( Any() );
[ # # ]
2103 : : }
2104 : : else
2105 : : {
2106 : : // empty sequence, set duration to 0.0 explicitly
2107 : : // (otherwise, this sequence will never end)
2108 [ # # ][ # # ]: 0 : mxSequenceRoot->setDuration( makeAny((double)0.0) );
[ # # ]
2109 [ # # ]: 0 : }
2110 : : }
2111 : 0 : catch( Exception& )
2112 : : {
2113 : : OSL_FAIL( "sd::EffectSequenceHelper::rebuild(), exception cought!" );
2114 : : }
2115 : 0 : }
2116 : :
2117 : : // --------------------------------------------------------------------
2118 : :
2119 : 0 : Reference< XTimeContainer > EffectSequenceHelper::createParallelTimeContainer() const
2120 : : {
2121 : 0 : const OUString aServiceName( "com.sun.star.animations.ParallelTimeContainer" );
2122 [ # # ][ # # ]: 0 : return Reference< XTimeContainer >( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY );
[ # # ][ # # ]
2123 : : }
2124 : :
2125 : : // --------------------------------------------------------------------
2126 : :
2127 : 0 : stl_CustomAnimationEffect_search_node_predict::stl_CustomAnimationEffect_search_node_predict( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xSearchNode )
2128 : 0 : : mxSearchNode( xSearchNode )
2129 : : {
2130 : 0 : }
2131 : :
2132 : : // --------------------------------------------------------------------
2133 : :
2134 : 0 : bool stl_CustomAnimationEffect_search_node_predict::operator()( CustomAnimationEffectPtr pEffect ) const
2135 : : {
2136 : 0 : return pEffect->getNode() == mxSearchNode;
2137 : : }
2138 : :
2139 : : // --------------------------------------------------------------------
2140 : :
2141 : 0 : static bool implFindNextContainer( Reference< XTimeContainer >& xParent, Reference< XTimeContainer >& xCurrent, Reference< XTimeContainer >& xNext )
2142 : : throw(Exception)
2143 : : {
2144 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( xParent, UNO_QUERY_THROW );
2145 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration() );
2146 [ # # ]: 0 : if( xEnumeration.is() )
2147 : : {
2148 : 0 : Reference< XInterface > x;
2149 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() && !xNext.is() )
[ # # ][ # # ]
[ # # ]
2150 : : {
2151 [ # # ][ # # ]: 0 : if( (xEnumeration->nextElement() >>= x) && (x == xCurrent) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
2152 : : {
2153 [ # # ][ # # ]: 0 : if( xEnumeration->hasMoreElements() )
[ # # ]
2154 [ # # ][ # # ]: 0 : xEnumeration->nextElement() >>= xNext;
[ # # ]
2155 : : }
2156 : 0 : }
2157 : : }
2158 : 0 : return xNext.is();
2159 : : }
2160 : :
2161 : : // --------------------------------------------------------------------
2162 : :
2163 : 0 : void stl_process_after_effect_node_func(AfterEffectNode& rNode)
2164 : : {
2165 : : try
2166 : : {
2167 [ # # ][ # # ]: 0 : if( rNode.mxNode.is() && rNode.mxMaster.is() )
[ # # ]
2168 : : {
2169 : : // set master node
2170 [ # # ]: 0 : Reference< XAnimationNode > xMasterNode( rNode.mxMaster, UNO_QUERY_THROW );
2171 [ # # ][ # # ]: 0 : Sequence< NamedValue > aUserData( rNode.mxNode->getUserData() );
2172 : 0 : sal_Int32 nSize = aUserData.getLength();
2173 [ # # ]: 0 : aUserData.realloc(nSize+1);
2174 [ # # ]: 0 : aUserData[nSize].Name = "master-element";
2175 [ # # ][ # # ]: 0 : aUserData[nSize].Value <<= xMasterNode;
2176 [ # # ][ # # ]: 0 : rNode.mxNode->setUserData( aUserData );
2177 : :
2178 : : // insert after effect node into timeline
2179 [ # # ][ # # ]: 0 : Reference< XTimeContainer > xContainer( rNode.mxMaster->getParent(), UNO_QUERY_THROW );
[ # # ]
2180 : :
2181 [ # # ]: 0 : if( !rNode.mbOnNextEffect ) // sameClick
2182 : : {
2183 : : // insert the aftereffect after its effect is animated
2184 [ # # ][ # # ]: 0 : xContainer->insertAfter( rNode.mxNode, rNode.mxMaster );
2185 : : }
2186 : : else // nextClick
2187 : : {
2188 [ # # ]: 0 : Reference< XMultiServiceFactory > xMsf( ::comphelper::getProcessServiceFactory() );
2189 : : // insert the aftereffect in the next group
2190 : :
2191 [ # # ][ # # ]: 0 : Reference< XTimeContainer > xClickContainer( xContainer->getParent(), UNO_QUERY_THROW );
[ # # ]
2192 [ # # ][ # # ]: 0 : Reference< XTimeContainer > xSequenceContainer( xClickContainer->getParent(), UNO_QUERY_THROW );
[ # # ]
2193 : :
2194 : 0 : Reference< XTimeContainer > xNextContainer;
2195 : :
2196 : : // first try if we have an after effect container
2197 [ # # ][ # # ]: 0 : if( !implFindNextContainer( xClickContainer, xContainer, xNextContainer ) )
2198 : : {
2199 : 0 : Reference< XTimeContainer > xNextClickContainer;
2200 : : // if not, try to find the next click effect container
2201 [ # # ][ # # ]: 0 : if( implFindNextContainer( xSequenceContainer, xClickContainer, xNextClickContainer ) )
2202 : : {
2203 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( xNextClickContainer, UNO_QUERY_THROW );
2204 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
2205 [ # # ][ # # ]: 0 : if( xEnumeration->hasMoreElements() )
[ # # ]
2206 : : {
2207 : : // the next container is the first child container
2208 [ # # ][ # # ]: 0 : xEnumeration->nextElement() >>= xNextContainer;
[ # # ]
2209 : : }
2210 : : else
2211 : : {
2212 : : // this does not yet have a child container, create one
2213 : 0 : const OUString aServiceName( "com.sun.star.animations.ParallelTimeContainer" );
2214 [ # # ][ # # ]: 0 : xNextContainer = Reference< XTimeContainer >::query( xMsf->createInstance(aServiceName) );
[ # # ][ # # ]
2215 : :
2216 [ # # ]: 0 : if( xNextContainer.is() )
2217 : : {
2218 [ # # ]: 0 : Reference< XAnimationNode > xNode( xNextContainer, UNO_QUERY_THROW );
2219 [ # # ][ # # ]: 0 : xNode->setBegin( makeAny( (double)0.0 ) );
[ # # ]
2220 [ # # ][ # # ]: 0 : xNextClickContainer->appendChild( xNode );
2221 : 0 : }
2222 : : }
2223 : 0 : DBG_ASSERT( xNextContainer.is(), "ppt::stl_process_after_effect_node_func::operator(), could not find/create container!" );
2224 : 0 : }
2225 : : }
2226 : :
2227 : : // if we don't have a next container, we add one to the sequence container
2228 [ # # ]: 0 : if( !xNextContainer.is() )
2229 : : {
2230 : 0 : const OUString aServiceName( "com.sun.star.animations.ParallelTimeContainer" );
2231 [ # # ][ # # ]: 0 : Reference< XTimeContainer > xNewClickContainer( xMsf->createInstance(aServiceName), UNO_QUERY_THROW );
[ # # ]
2232 : :
2233 [ # # ]: 0 : Reference< XAnimationNode > xNewClickNode( xNewClickContainer, UNO_QUERY_THROW );
2234 : :
2235 : 0 : Event aEvent;
2236 : 0 : aEvent.Trigger = EventTrigger::ON_NEXT;
2237 : 0 : aEvent.Repeat = 0;
2238 [ # # ][ # # ]: 0 : xNewClickNode->setBegin( makeAny( aEvent ) );
[ # # ]
2239 : :
2240 [ # # ]: 0 : Reference< XAnimationNode > xRefNode( xClickContainer, UNO_QUERY_THROW );
2241 [ # # ][ # # ]: 0 : xSequenceContainer->insertAfter( xNewClickNode, xRefNode );
2242 : :
2243 [ # # ][ # # ]: 0 : xNextContainer = Reference< XTimeContainer >::query( xMsf->createInstance(aServiceName) );
[ # # ][ # # ]
2244 : :
2245 : : DBG_ASSERT( xNextContainer.is(), "ppt::stl_process_after_effect_node_func::operator(), could not create container!" );
2246 [ # # ]: 0 : if( xNextContainer.is() )
2247 : : {
2248 [ # # ]: 0 : Reference< XAnimationNode > xNode( xNextContainer, UNO_QUERY_THROW );
2249 [ # # ][ # # ]: 0 : xNode->setBegin( makeAny( (double)0.0 ) );
[ # # ]
2250 [ # # ][ # # ]: 0 : xNewClickContainer->appendChild( xNode );
2251 : 0 : }
2252 : : }
2253 : :
2254 [ # # ]: 0 : if( xNextContainer.is() )
2255 : : {
2256 : : // find begin time of first element
2257 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( xNextContainer, UNO_QUERY_THROW );
2258 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
2259 [ # # ][ # # ]: 0 : if( xEnumeration->hasMoreElements() )
[ # # ]
2260 : : {
2261 : 0 : Reference< XAnimationNode > xChild;
2262 : : // the next container is the first child container
2263 [ # # ][ # # ]: 0 : xEnumeration->nextElement() >>= xChild;
[ # # ]
2264 [ # # ]: 0 : if( xChild.is() )
2265 : : {
2266 [ # # ][ # # ]: 0 : Any aBegin( xChild->getBegin() );
2267 : 0 : double fBegin = 0.0;
2268 [ # # ][ # # ]: 0 : if( (aBegin >>= fBegin) && (fBegin >= 0.0))
[ # # ]
2269 [ # # ][ # # ]: 0 : rNode.mxNode->setBegin( aBegin );
2270 : 0 : }
2271 : : }
2272 : :
2273 [ # # ][ # # ]: 0 : xNextContainer->appendChild( rNode.mxNode );
2274 : 0 : }
2275 [ # # ][ # # ]: 0 : }
2276 : : }
2277 : : }
2278 : 0 : catch( Exception& )
2279 : : {
2280 : : OSL_FAIL( "ppt::stl_process_after_effect_node_func::operator(), exception cought!" );
2281 : : }
2282 : 0 : }
2283 : :
2284 : : // --------------------------------------------------------------------
2285 : :
2286 : 0 : EffectSequence::iterator EffectSequenceHelper::find( const CustomAnimationEffectPtr& pEffect )
2287 : : {
2288 : 0 : return std::find( maEffects.begin(), maEffects.end(), pEffect );
2289 : : }
2290 : :
2291 : : // --------------------------------------------------------------------
2292 : :
2293 : 0 : CustomAnimationEffectPtr EffectSequenceHelper::findEffect( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) const
2294 : : {
2295 [ # # ]: 0 : CustomAnimationEffectPtr pEffect;
2296 : :
2297 : 0 : EffectSequence::const_iterator aIter( maEffects.begin() );
2298 [ # # ]: 0 : for( ; aIter != maEffects.end(); ++aIter )
2299 : : {
2300 [ # # ][ # # ]: 0 : if( (*aIter)->getNode() == xNode )
2301 : : {
2302 [ # # ]: 0 : pEffect = (*aIter);
2303 : 0 : break;
2304 : : }
2305 : : }
2306 : :
2307 : 0 : return pEffect;
2308 : : }
2309 : :
2310 : : // --------------------------------------------------------------------
2311 : :
2312 : 0 : sal_Int32 EffectSequenceHelper::getOffsetFromEffect( const CustomAnimationEffectPtr& xEffect ) const
2313 : : {
2314 : 0 : sal_Int32 nOffset = 0;
2315 : :
2316 : 0 : EffectSequence::const_iterator aIter( maEffects.begin() );
2317 [ # # ]: 0 : for( ; aIter != maEffects.end(); ++aIter, nOffset++ )
2318 : : {
2319 [ # # ]: 0 : if( (*aIter) == xEffect )
2320 : 0 : return nOffset;
2321 : : }
2322 : :
2323 : 0 : return -1;
2324 : : }
2325 : :
2326 : : // --------------------------------------------------------------------
2327 : :
2328 : 0 : CustomAnimationEffectPtr EffectSequenceHelper::getEffectFromOffset( sal_Int32 nOffset ) const
2329 : : {
2330 : 0 : EffectSequence::const_iterator aIter( maEffects.begin() );
2331 [ # # ][ # # ]: 0 : while( nOffset-- && aIter != maEffects.end() )
[ # # ][ # # ]
2332 : 0 : ++aIter;
2333 : :
2334 [ # # ]: 0 : CustomAnimationEffectPtr pEffect;
2335 [ # # ]: 0 : if( aIter != maEffects.end() )
2336 [ # # ]: 0 : pEffect = (*aIter);
2337 : :
2338 : 0 : return pEffect;
2339 : : }
2340 : :
2341 : : // --------------------------------------------------------------------
2342 : :
2343 : 0 : bool EffectSequenceHelper::disposeShape( const Reference< XShape >& xShape )
2344 : : {
2345 : 0 : bool bChanges = false;
2346 : :
2347 : 0 : EffectSequence::iterator aIter( maEffects.begin() );
2348 [ # # ]: 0 : while( aIter != maEffects.end() )
2349 : : {
2350 [ # # ][ # # ]: 0 : if( (*aIter)->getTargetShape() == xShape )
[ # # ]
2351 : : {
2352 : 0 : (*aIter)->setEffectSequence( 0 );
2353 : 0 : bChanges = true;
2354 [ # # ]: 0 : aIter = maEffects.erase( aIter );
2355 : : }
2356 : : else
2357 : : {
2358 : 0 : ++aIter;
2359 : : }
2360 : : }
2361 : :
2362 : 0 : return bChanges;
2363 : : }
2364 : :
2365 : : // --------------------------------------------------------------------
2366 : :
2367 : 0 : bool EffectSequenceHelper::hasEffect( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape )
2368 : : {
2369 : 0 : EffectSequence::iterator aIter( maEffects.begin() );
2370 [ # # ]: 0 : while( aIter != maEffects.end() )
2371 : : {
2372 [ # # ][ # # ]: 0 : if( (*aIter)->getTargetShape() == xShape )
[ # # ]
2373 : 0 : return true;
2374 : 0 : ++aIter;
2375 : : }
2376 : :
2377 : 0 : return false;
2378 : : }
2379 : :
2380 : : // --------------------------------------------------------------------
2381 : :
2382 : 0 : void EffectSequenceHelper::insertTextRange( const com::sun::star::uno::Any& aTarget )
2383 : : {
2384 : 0 : bool bChanges = false;
2385 : :
2386 [ # # ]: 0 : ParagraphTarget aParaTarget;
2387 [ # # ][ # # ]: 0 : if( !(aTarget >>= aParaTarget ) )
2388 : 0 : return;
2389 : :
2390 : 0 : EffectSequence::iterator aIter( maEffects.begin() );
2391 [ # # ]: 0 : while( aIter != maEffects.end() )
2392 : : {
2393 [ # # ][ # # ]: 0 : if( (*aIter)->getTargetShape() == aParaTarget.Shape )
[ # # ]
2394 [ # # ]: 0 : bChanges |= (*aIter)->checkForText();
2395 : 0 : ++aIter;
2396 : : }
2397 : :
2398 [ # # ]: 0 : if( bChanges )
2399 [ # # ][ # # ]: 0 : rebuild();
[ # # ]
2400 : : }
2401 : :
2402 : : // --------------------------------------------------------------------
2403 : :
2404 : 0 : void EffectSequenceHelper::disposeTextRange( const com::sun::star::uno::Any& aTarget )
2405 : : {
2406 [ # # ]: 0 : ParagraphTarget aParaTarget;
2407 [ # # ][ # # ]: 0 : if( !(aTarget >>= aParaTarget ) )
2408 : 0 : return;
2409 : :
2410 : 0 : bool bChanges = false;
2411 : 0 : bool bErased = false;
2412 : :
2413 : 0 : EffectSequence::iterator aIter( maEffects.begin() );
2414 [ # # ]: 0 : while( aIter != maEffects.end() )
2415 : : {
2416 : 0 : Any aIterTarget( (*aIter)->getTarget() );
2417 [ # # ][ # # ]: 0 : if( aIterTarget.getValueType() == ::getCppuType((const ParagraphTarget*)0) )
2418 : : {
2419 [ # # ]: 0 : ParagraphTarget aIterParaTarget;
2420 [ # # ][ # # ]: 0 : if( (aIterTarget >>= aIterParaTarget) && (aIterParaTarget.Shape == aParaTarget.Shape) )
[ # # ][ # # ]
[ # # ]
2421 : : {
2422 [ # # ]: 0 : if( aIterParaTarget.Paragraph == aParaTarget.Paragraph )
2423 : : {
2424 : : // delete this effect if it targets the disposed paragraph directly
2425 : 0 : (*aIter)->setEffectSequence( 0 );
2426 [ # # ]: 0 : aIter = maEffects.erase( aIter );
2427 : 0 : bChanges = true;
2428 : 0 : bErased = true;
2429 : : }
2430 : : else
2431 : : {
2432 [ # # ]: 0 : if( aIterParaTarget.Paragraph > aParaTarget.Paragraph )
2433 : : {
2434 : : // shift all paragraphs after disposed paragraph
2435 : 0 : aIterParaTarget.Paragraph--;
2436 [ # # ][ # # ]: 0 : (*aIter)->setTarget( makeAny( aIterParaTarget ) );
2437 : : }
2438 : : }
2439 [ # # ]: 0 : }
2440 : : }
2441 [ # # ][ # # ]: 0 : else if( (*aIter)->getTargetShape() == aParaTarget.Shape )
[ # # ]
2442 : : {
2443 [ # # ]: 0 : bChanges |= (*aIter)->checkForText();
2444 : : }
2445 : :
2446 [ # # ]: 0 : if( bErased )
2447 : 0 : bErased = false;
2448 : : else
2449 : 0 : ++aIter;
2450 : 0 : }
2451 : :
2452 [ # # ]: 0 : if( bChanges )
2453 [ # # ][ # # ]: 0 : rebuild();
[ # # ]
2454 : : }
2455 : :
2456 : : // --------------------------------------------------------------------
2457 : :
2458 : 0 : CustomAnimationTextGroup::CustomAnimationTextGroup( const Reference< XShape >& rTarget, sal_Int32 nGroupId )
2459 : : : maTarget( rTarget ),
2460 : 0 : mnGroupId( nGroupId )
2461 : : {
2462 : 0 : reset();
2463 : 0 : }
2464 : :
2465 : : // --------------------------------------------------------------------
2466 : :
2467 : 0 : void CustomAnimationTextGroup::reset()
2468 : : {
2469 : 0 : mnTextGrouping = -1;
2470 : 0 : mbAnimateForm = false;
2471 : 0 : mbTextReverse = false;
2472 : 0 : mfGroupingAuto = -1.0;
2473 : 0 : mnLastPara = -1; // used to check for TextReverse
2474 : :
2475 [ # # ]: 0 : for (int i = 0; i < PARA_LEVELS; ++i)
2476 : : {
2477 : 0 : mnDepthFlags[i] = 0;
2478 : : }
2479 : :
2480 : 0 : maEffects.clear();
2481 : 0 : }
2482 : :
2483 : : // --------------------------------------------------------------------
2484 : :
2485 : 0 : void CustomAnimationTextGroup::addEffect( CustomAnimationEffectPtr& pEffect )
2486 : : {
2487 [ # # ]: 0 : maEffects.push_back( pEffect );
2488 : :
2489 : 0 : Any aTarget( pEffect->getTarget() );
2490 [ # # ][ # # ]: 0 : if( aTarget.getValueType() == ::getCppuType((const ParagraphTarget*)0) )
2491 : : {
2492 : : // now look at the paragraph
2493 [ # # ]: 0 : ParagraphTarget aParaTarget;
2494 [ # # ]: 0 : aTarget >>= aParaTarget;
2495 : :
2496 [ # # ]: 0 : if( mnLastPara != -1 )
2497 : 0 : mbTextReverse = mnLastPara > aParaTarget.Paragraph;
2498 : :
2499 : 0 : mnLastPara = aParaTarget.Paragraph;
2500 : :
2501 : 0 : const sal_Int32 nParaDepth = pEffect->getParaDepth();
2502 : :
2503 : : // only look at the first PARA_LEVELS levels
2504 [ # # ]: 0 : if( nParaDepth < PARA_LEVELS )
2505 : : {
2506 : : // our first paragraph with this level?
2507 [ # # ]: 0 : if( mnDepthFlags[nParaDepth] == 0 )
2508 : : {
2509 : : // so set it to the first found
2510 : 0 : mnDepthFlags[nParaDepth] = (sal_Int8)pEffect->getNodeType();
2511 : : }
2512 [ # # ]: 0 : else if( mnDepthFlags[nParaDepth] != pEffect->getNodeType() )
2513 : : {
2514 : 0 : mnDepthFlags[nParaDepth] = -1;
2515 : : }
2516 : :
2517 [ # # ]: 0 : if( pEffect->getNodeType() == EffectNodeType::AFTER_PREVIOUS )
2518 : 0 : mfGroupingAuto = pEffect->getBegin();
2519 : :
2520 : 0 : mnTextGrouping = PARA_LEVELS;
2521 [ # # ][ # # ]: 0 : while( (mnTextGrouping > 0)
[ # # ]
2522 : 0 : && (mnDepthFlags[mnTextGrouping - 1] <= 0) )
2523 : 0 : --mnTextGrouping;
2524 [ # # ]: 0 : }
2525 : : }
2526 : : else
2527 : : {
2528 : : // if we have an effect with the shape as a target, we animate the background
2529 : 0 : mbAnimateForm = pEffect->getTargetSubItem() != ShapeAnimationSubType::ONLY_TEXT;
2530 : 0 : }
2531 : 0 : }
2532 : :
2533 : : // --------------------------------------------------------------------
2534 : :
2535 : : class TextGroupMapImpl : public std::map< sal_Int32, CustomAnimationTextGroup* >
2536 : : {
2537 : : public:
2538 : : CustomAnimationTextGroup* findGroup( sal_Int32 nGroupId );
2539 : : };
2540 : :
2541 : : // --------------------------------------------------------------------
2542 : :
2543 : 0 : CustomAnimationTextGroupPtr EffectSequenceHelper::findGroup( sal_Int32 nGroupId )
2544 : : {
2545 [ # # ]: 0 : CustomAnimationTextGroupPtr aPtr;
2546 : :
2547 [ # # ]: 0 : CustomAnimationTextGroupMap::iterator aIter( maGroupMap.find( nGroupId ) );
2548 [ # # ]: 0 : if( aIter != maGroupMap.end() )
2549 [ # # ]: 0 : aPtr = (*aIter).second;
2550 : :
2551 : 0 : return aPtr;
2552 : : }
2553 : :
2554 : : // --------------------------------------------------------------------
2555 : :
2556 : 4 : void EffectSequenceHelper::updateTextGroups()
2557 : : {
2558 : 4 : maGroupMap.clear();
2559 : :
2560 : : // first create all the groups
2561 : 4 : EffectSequence::iterator aIter( maEffects.begin() );
2562 : 4 : const EffectSequence::iterator aEnd( maEffects.end() );
2563 [ - + ]: 4 : while( aIter != aEnd )
2564 : : {
2565 [ # # ]: 0 : CustomAnimationEffectPtr pEffect( (*aIter++) );
2566 : :
2567 : 0 : const sal_Int32 nGroupId = pEffect->getGroupId();
2568 : :
2569 [ # # ]: 0 : if( nGroupId == -1 )
2570 : 0 : continue; // trivial case, no group
2571 : :
2572 [ # # ]: 0 : CustomAnimationTextGroupPtr pGroup = findGroup( nGroupId );
2573 [ # # ]: 0 : if( !pGroup.get() )
2574 : : {
2575 [ # # ][ # # ]: 0 : pGroup.reset( new CustomAnimationTextGroup( pEffect->getTargetShape(), nGroupId ) );
[ # # ][ # # ]
2576 [ # # ][ # # ]: 0 : maGroupMap[nGroupId] = pGroup;
2577 : : }
2578 : :
2579 [ # # ]: 0 : pGroup->addEffect( pEffect );
2580 [ # # ][ # # ]: 0 : }
[ # # ]
2581 : 4 : }
2582 : :
2583 : : // --------------------------------------------------------------------
2584 : :
2585 : 0 : CustomAnimationTextGroupPtr EffectSequenceHelper::createTextGroup( CustomAnimationEffectPtr pEffect, sal_Int32 nTextGrouping, double fTextGroupingAuto, sal_Bool bAnimateForm, sal_Bool bTextReverse )
2586 : : {
2587 : : // first finde a free group-id
2588 : 0 : sal_Int32 nGroupId = 0;
2589 : :
2590 : 0 : CustomAnimationTextGroupMap::iterator aIter( maGroupMap.begin() );
2591 : 0 : const CustomAnimationTextGroupMap::iterator aEnd( maGroupMap.end() );
2592 [ # # ]: 0 : while( aIter != aEnd )
2593 : : {
2594 [ # # ]: 0 : if( (*aIter).first == nGroupId )
2595 : : {
2596 : 0 : nGroupId++;
2597 : 0 : aIter = maGroupMap.begin();
2598 : : }
2599 : : else
2600 : : {
2601 : 0 : ++aIter;
2602 : : }
2603 : : }
2604 : :
2605 [ # # ]: 0 : Reference< XShape > xTarget( pEffect->getTargetShape() );
2606 : :
2607 [ # # ][ # # ]: 0 : CustomAnimationTextGroupPtr pTextGroup( new CustomAnimationTextGroup( xTarget, nGroupId ) );
[ # # ]
2608 [ # # ][ # # ]: 0 : maGroupMap[nGroupId] = pTextGroup;
2609 : :
2610 : 0 : bool bUsed = false;
2611 : :
2612 : : // do we need to target the shape?
2613 [ # # ][ # # ]: 0 : if( (nTextGrouping == 0) || bAnimateForm )
2614 : : {
2615 : : sal_Int16 nSubItem;
2616 [ # # ]: 0 : if( nTextGrouping == 0)
2617 [ # # ]: 0 : nSubItem = bAnimateForm ? ShapeAnimationSubType::AS_WHOLE : ShapeAnimationSubType::ONLY_TEXT;
2618 : : else
2619 : 0 : nSubItem = ShapeAnimationSubType::ONLY_BACKGROUND;
2620 : :
2621 [ # # ][ # # ]: 0 : pEffect->setTarget( makeAny( xTarget ) );
2622 [ # # ]: 0 : pEffect->setTargetSubItem( nSubItem );
2623 : 0 : pEffect->setEffectSequence( this );
2624 [ # # ]: 0 : pEffect->setGroupId( nGroupId );
2625 : :
2626 [ # # ]: 0 : pTextGroup->addEffect( pEffect );
2627 : 0 : bUsed = true;
2628 : : }
2629 : :
2630 : 0 : pTextGroup->mnTextGrouping = nTextGrouping;
2631 : 0 : pTextGroup->mfGroupingAuto = fTextGroupingAuto;
2632 : 0 : pTextGroup->mbTextReverse = bTextReverse;
2633 : :
2634 : : // now add an effect for each paragraph
2635 [ # # ][ # # ]: 0 : createTextGroupParagraphEffects( pTextGroup, pEffect, bUsed );
[ # # ][ # # ]
[ # # ]
2636 : :
2637 [ # # ]: 0 : notify_listeners();
2638 : :
2639 : 0 : return pTextGroup;
2640 : : }
2641 : :
2642 : : // --------------------------------------------------------------------
2643 : :
2644 : 0 : void EffectSequenceHelper::createTextGroupParagraphEffects( CustomAnimationTextGroupPtr pTextGroup, CustomAnimationEffectPtr pEffect, bool bUsed )
2645 : : {
2646 : 0 : Reference< XShape > xTarget( pTextGroup->maTarget );
2647 : :
2648 : 0 : sal_Int32 nTextGrouping = pTextGroup->mnTextGrouping;
2649 : 0 : double fTextGroupingAuto = pTextGroup->mfGroupingAuto;
2650 : 0 : sal_Bool bTextReverse = pTextGroup->mbTextReverse;
2651 : :
2652 : : // now add an effect for each paragraph
2653 [ # # ]: 0 : if( nTextGrouping >= 0 ) try
2654 : : {
2655 [ # # ]: 0 : EffectSequence::iterator aInsertIter( find( pEffect ) );
2656 : :
2657 : 0 : const OUString strNumberingLevel( "NumberingLevel" );
2658 [ # # ]: 0 : Reference< XEnumerationAccess > xText( xTarget, UNO_QUERY_THROW );
2659 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xText->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
2660 : :
2661 [ # # ]: 0 : std::list< sal_Int16 > aParaList;
2662 : : sal_Int16 nPara;
2663 : :
2664 : : // fill the list with all valid paragraphs
2665 [ # # ][ # # ]: 0 : for( nPara = 0; xEnumeration->hasMoreElements(); nPara++ )
[ # # ]
2666 : : {
2667 [ # # ][ # # ]: 0 : Reference< XTextRange > xRange( xEnumeration->nextElement(), UNO_QUERY );
[ # # ]
2668 [ # # ][ # # ]: 0 : if( xRange.is() && !xRange->getString().isEmpty() )
[ # # ][ # # ]
[ # # # # ]
[ # # ]
2669 : : {
2670 [ # # ]: 0 : if( bTextReverse ) // sort them
2671 [ # # ]: 0 : aParaList.push_front( nPara );
2672 : : else
2673 [ # # ]: 0 : aParaList.push_back( nPara );
2674 : : }
2675 : 0 : }
2676 : :
2677 [ # # ]: 0 : ParagraphTarget aTarget;
2678 [ # # ]: 0 : aTarget.Shape = xTarget;
2679 : :
2680 : 0 : std::list< sal_Int16 >::iterator aIter( aParaList.begin() );
2681 : 0 : std::list< sal_Int16 >::iterator aEnd( aParaList.end() );
2682 [ # # ][ # # ]: 0 : while( aIter != aEnd )
2683 : : {
2684 [ # # ][ # # ]: 0 : aTarget.Paragraph = (*aIter++);
2685 : :
2686 [ # # ]: 0 : CustomAnimationEffectPtr pNewEffect;
2687 [ # # ]: 0 : if( bUsed )
2688 : : {
2689 : : // clone a new effect from first effect
2690 [ # # ][ # # ]: 0 : pNewEffect = pEffect->clone();
[ # # ]
2691 : 0 : ++aInsertIter;
2692 [ # # ]: 0 : aInsertIter = maEffects.insert( aInsertIter, pNewEffect );
2693 : : }
2694 : : else
2695 : : {
2696 : : // reuse first effect if its not yet used
2697 [ # # ]: 0 : pNewEffect = pEffect;
2698 : 0 : bUsed = true;
2699 [ # # ]: 0 : aInsertIter = find( pNewEffect );
2700 : : }
2701 : :
2702 : : // set target and group-id
2703 [ # # ][ # # ]: 0 : pNewEffect->setTarget( makeAny( aTarget ) );
2704 [ # # ]: 0 : pNewEffect->setTargetSubItem( ShapeAnimationSubType::ONLY_TEXT );
2705 [ # # ]: 0 : pNewEffect->setGroupId( pTextGroup->mnGroupId );
2706 : 0 : pNewEffect->setEffectSequence( this );
2707 : :
2708 : : // set correct node type
2709 [ # # ]: 0 : if( pNewEffect->getParaDepth() < nTextGrouping )
2710 : : {
2711 [ # # ]: 0 : if( fTextGroupingAuto == -1.0 )
2712 : : {
2713 [ # # ]: 0 : pNewEffect->setNodeType( EffectNodeType::ON_CLICK );
2714 [ # # ]: 0 : pNewEffect->setBegin( 0.0 );
2715 : : }
2716 : : else
2717 : : {
2718 [ # # ]: 0 : pNewEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
2719 [ # # ]: 0 : pNewEffect->setBegin( fTextGroupingAuto );
2720 : : }
2721 : : }
2722 : : else
2723 : : {
2724 [ # # ]: 0 : pNewEffect->setNodeType( EffectNodeType::WITH_PREVIOUS );
2725 [ # # ]: 0 : pNewEffect->setBegin( 0.0 );
2726 : : }
2727 : :
2728 [ # # ]: 0 : pTextGroup->addEffect( pNewEffect );
2729 [ # # ]: 0 : }
2730 [ # # ][ # # ]: 0 : notify_listeners();
[ # # ]
2731 : : }
2732 [ # # ]: 0 : catch( Exception& )
2733 : : {
2734 : : OSL_FAIL("sd::EffectSequenceHelper::createTextGroup(), exception cought!" );
2735 : 0 : }
2736 : 0 : }
2737 : :
2738 : : // --------------------------------------------------------------------
2739 : :
2740 : 0 : void EffectSequenceHelper::setTextGrouping( CustomAnimationTextGroupPtr pTextGroup, sal_Int32 nTextGrouping )
2741 : : {
2742 [ # # ]: 0 : if( pTextGroup->mnTextGrouping == nTextGrouping )
2743 : : {
2744 : : // first case, trivial case, do nothing
2745 : : }
2746 [ # # ][ # # ]: 0 : else if( (pTextGroup->mnTextGrouping == -1) && (nTextGrouping >= 0) )
[ # # ]
2747 : : {
2748 : : // second case, we need to add new effects for each paragraph
2749 : :
2750 [ # # ]: 0 : CustomAnimationEffectPtr pEffect( pTextGroup->maEffects.front() );
2751 : :
2752 : 0 : pTextGroup->mnTextGrouping = nTextGrouping;
2753 [ # # ][ # # ]: 0 : createTextGroupParagraphEffects( pTextGroup, pEffect, true );
[ # # ][ # # ]
[ # # ]
2754 [ # # ][ # # ]: 0 : notify_listeners();
2755 : : }
2756 [ # # ][ # # ]: 0 : else if( (pTextGroup->mnTextGrouping >= 0) && (nTextGrouping == -1 ) )
[ # # ]
2757 : : {
2758 : : // third case, we need to remove effects for each paragraph
2759 : :
2760 [ # # ]: 0 : EffectSequence aEffects( pTextGroup->maEffects );
2761 : 0 : pTextGroup->reset();
2762 : :
2763 : 0 : EffectSequence::iterator aIter( aEffects.begin() );
2764 : 0 : const EffectSequence::iterator aEnd( aEffects.end() );
2765 [ # # ]: 0 : while( aIter != aEnd )
2766 : : {
2767 [ # # ]: 0 : CustomAnimationEffectPtr pEffect( (*aIter++) );
2768 : :
2769 [ # # ][ # # ]: 0 : if( pEffect->getTarget().getValueType() == ::getCppuType((const ParagraphTarget*)0) )
2770 [ # # ]: 0 : remove( pEffect );
2771 : : else
2772 [ # # ]: 0 : pTextGroup->addEffect( pEffect );
2773 [ # # ]: 0 : }
2774 [ # # ]: 0 : notify_listeners();
2775 : : }
2776 : : else
2777 : : {
2778 : : // fourth case, we need to change the node types for the text nodes
2779 : 0 : double fTextGroupingAuto = pTextGroup->mfGroupingAuto;
2780 : :
2781 [ # # ]: 0 : EffectSequence aEffects( pTextGroup->maEffects );
2782 : 0 : pTextGroup->reset();
2783 : :
2784 : 0 : EffectSequence::iterator aIter( aEffects.begin() );
2785 : 0 : const EffectSequence::iterator aEnd( aEffects.end() );
2786 [ # # ]: 0 : while( aIter != aEnd )
2787 : : {
2788 [ # # ]: 0 : CustomAnimationEffectPtr pEffect( (*aIter++) );
2789 : :
2790 [ # # ][ # # ]: 0 : if( pEffect->getTarget().getValueType() == ::getCppuType((const ParagraphTarget*)0) )
2791 : : {
2792 : : // set correct node type
2793 [ # # ]: 0 : if( pEffect->getParaDepth() < nTextGrouping )
2794 : : {
2795 [ # # ]: 0 : if( fTextGroupingAuto == -1.0 )
2796 : : {
2797 [ # # ]: 0 : pEffect->setNodeType( EffectNodeType::ON_CLICK );
2798 [ # # ]: 0 : pEffect->setBegin( 0.0 );
2799 : : }
2800 : : else
2801 : : {
2802 [ # # ]: 0 : pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
2803 [ # # ]: 0 : pEffect->setBegin( fTextGroupingAuto );
2804 : : }
2805 : : }
2806 : : else
2807 : : {
2808 [ # # ]: 0 : pEffect->setNodeType( EffectNodeType::WITH_PREVIOUS );
2809 [ # # ]: 0 : pEffect->setBegin( 0.0 );
2810 : : }
2811 : : }
2812 : :
2813 [ # # ]: 0 : pTextGroup->addEffect( pEffect );
2814 : :
2815 [ # # ]: 0 : }
2816 [ # # ]: 0 : notify_listeners();
2817 : : }
2818 : 0 : }
2819 : :
2820 : : // --------------------------------------------------------------------
2821 : :
2822 : 0 : void EffectSequenceHelper::setAnimateForm( CustomAnimationTextGroupPtr pTextGroup, sal_Bool bAnimateForm )
2823 : : {
2824 [ # # ]: 0 : if( pTextGroup->mbAnimateForm == bAnimateForm )
2825 : : {
2826 : : // trivial case, do nothing
2827 : : }
2828 : : else
2829 : : {
2830 [ # # ]: 0 : EffectSequence aEffects( pTextGroup->maEffects );
2831 : 0 : pTextGroup->reset();
2832 : :
2833 : : SAL_WARN_IF(aEffects.empty(), "sd", "EffectSequenceHelper::setAnimateForm effects empty" );
2834 : :
2835 [ # # ]: 0 : if (aEffects.empty())
2836 : 0 : return;
2837 : :
2838 : 0 : EffectSequence::iterator aIter( aEffects.begin() );
2839 : 0 : const EffectSequence::iterator aEnd( aEffects.end() );
2840 : :
2841 : : // first insert if we have to
2842 [ # # ]: 0 : if( bAnimateForm )
2843 : : {
2844 [ # # ]: 0 : EffectSequence::iterator aInsertIter( find( (*aIter) ) );
2845 : :
2846 [ # # ]: 0 : CustomAnimationEffectPtr pEffect;
2847 [ # # ][ # # ]: 0 : if( (aEffects.size() == 1) && ((*aIter)->getTarget().getValueType() != ::getCppuType((const ParagraphTarget*)0) ) )
[ # # ][ # # ]
[ # # # # ]
2848 : : {
2849 : : // special case, only one effect and that targets whole text,
2850 : : // convert this to target whole shape
2851 [ # # ]: 0 : pEffect = (*aIter++);
2852 [ # # ]: 0 : pEffect->setTargetSubItem( ShapeAnimationSubType::AS_WHOLE );
2853 : : }
2854 : : else
2855 : : {
2856 [ # # ][ # # ]: 0 : pEffect = (*aIter)->clone();
[ # # ]
2857 [ # # ][ # # ]: 0 : pEffect->setTarget( makeAny( (*aIter)->getTargetShape() ) );
[ # # ]
2858 [ # # ]: 0 : pEffect->setTargetSubItem( ShapeAnimationSubType::ONLY_BACKGROUND );
2859 [ # # ]: 0 : maEffects.insert( aInsertIter, pEffect );
2860 : : }
2861 : :
2862 [ # # ][ # # ]: 0 : pTextGroup->addEffect( pEffect );
2863 : : }
2864 : :
2865 [ # # ][ # # ]: 0 : if( !bAnimateForm && (aEffects.size() == 1) )
[ # # ]
2866 : : {
2867 [ # # ]: 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
2868 [ # # ][ # # ]: 0 : pEffect->setTarget( makeAny( (*aIter)->getTargetShape() ) );
[ # # ]
2869 [ # # ]: 0 : pEffect->setTargetSubItem( ShapeAnimationSubType::ONLY_TEXT );
2870 [ # # ][ # # ]: 0 : pTextGroup->addEffect( pEffect );
2871 : : }
2872 : : else
2873 : : {
2874 : : // readd the rest to the group again
2875 [ # # ]: 0 : while( aIter != aEnd )
2876 : : {
2877 [ # # ]: 0 : CustomAnimationEffectPtr pEffect( (*aIter++) );
2878 : :
2879 [ # # ][ # # ]: 0 : if( pEffect->getTarget().getValueType() == ::getCppuType((const ParagraphTarget*)0) )
2880 : : {
2881 [ # # ]: 0 : pTextGroup->addEffect( pEffect );
2882 : : }
2883 : : else
2884 : : {
2885 : : DBG_ASSERT( !bAnimateForm, "sd::EffectSequenceHelper::setAnimateForm(), something is wrong here!" );
2886 [ # # ]: 0 : remove( pEffect );
2887 : : }
2888 [ # # ]: 0 : }
2889 : : }
2890 [ # # ][ # # ]: 0 : notify_listeners();
2891 : : }
2892 : : }
2893 : :
2894 : : // --------------------------------------------------------------------
2895 : :
2896 : 0 : void EffectSequenceHelper::setTextGroupingAuto( CustomAnimationTextGroupPtr pTextGroup, double fTextGroupingAuto )
2897 : : {
2898 : 0 : sal_Int32 nTextGrouping = pTextGroup->mnTextGrouping;
2899 : :
2900 [ # # ]: 0 : EffectSequence aEffects( pTextGroup->maEffects );
2901 : 0 : pTextGroup->reset();
2902 : :
2903 : 0 : EffectSequence::iterator aIter( aEffects.begin() );
2904 : 0 : const EffectSequence::iterator aEnd( aEffects.end() );
2905 [ # # ]: 0 : while( aIter != aEnd )
2906 : : {
2907 [ # # ]: 0 : CustomAnimationEffectPtr pEffect( (*aIter++) );
2908 : :
2909 [ # # ][ # # ]: 0 : if( pEffect->getTarget().getValueType() == ::getCppuType((const ParagraphTarget*)0) )
2910 : : {
2911 : : // set correct node type
2912 [ # # ]: 0 : if( pEffect->getParaDepth() < nTextGrouping )
2913 : : {
2914 [ # # ]: 0 : if( fTextGroupingAuto == -1.0 )
2915 : : {
2916 [ # # ]: 0 : pEffect->setNodeType( EffectNodeType::ON_CLICK );
2917 [ # # ]: 0 : pEffect->setBegin( 0.0 );
2918 : : }
2919 : : else
2920 : : {
2921 [ # # ]: 0 : pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
2922 [ # # ]: 0 : pEffect->setBegin( fTextGroupingAuto );
2923 : : }
2924 : : }
2925 : : else
2926 : : {
2927 [ # # ]: 0 : pEffect->setNodeType( EffectNodeType::WITH_PREVIOUS );
2928 [ # # ]: 0 : pEffect->setBegin( 0.0 );
2929 : : }
2930 : : }
2931 : :
2932 [ # # ]: 0 : pTextGroup->addEffect( pEffect );
2933 : :
2934 [ # # ]: 0 : }
2935 [ # # ]: 0 : notify_listeners();
2936 : 0 : }
2937 : :
2938 : : // --------------------------------------------------------------------
2939 : :
2940 : : struct ImplStlTextGroupSortHelper
2941 : : {
2942 : 0 : ImplStlTextGroupSortHelper( bool bReverse ) : mbReverse( bReverse ) {};
2943 : : bool operator()( const CustomAnimationEffectPtr& p1, const CustomAnimationEffectPtr& p2 );
2944 : : bool mbReverse;
2945 : : sal_Int32 getTargetParagraph( const CustomAnimationEffectPtr& p1 );
2946 : : };
2947 : :
2948 : : // --------------------------------------------------------------------
2949 : :
2950 : 0 : sal_Int32 ImplStlTextGroupSortHelper::getTargetParagraph( const CustomAnimationEffectPtr& p1 )
2951 : : {
2952 : 0 : const Any aTarget(p1->getTarget());
2953 [ # # ][ # # ]: 0 : if( aTarget.hasValue() && aTarget.getValueType() == ::getCppuType((const ParagraphTarget*)0) )
[ # # ][ # # ]
2954 : : {
2955 [ # # ]: 0 : ParagraphTarget aParaTarget;
2956 [ # # ]: 0 : aTarget >>= aParaTarget;
2957 [ # # ]: 0 : return aParaTarget.Paragraph;
2958 : : }
2959 : : else
2960 : : {
2961 [ # # ]: 0 : return mbReverse ? 0x7fffffff : -1;
2962 : 0 : }
2963 : : }
2964 : :
2965 : : // --------------------------------------------------------------------
2966 : :
2967 : 0 : bool ImplStlTextGroupSortHelper::operator()( const CustomAnimationEffectPtr& p1, const CustomAnimationEffectPtr& p2 )
2968 : : {
2969 [ # # ]: 0 : if( mbReverse )
2970 : : {
2971 : 0 : return getTargetParagraph( p2 ) < getTargetParagraph( p1 );
2972 : : }
2973 : : else
2974 : : {
2975 : 0 : return getTargetParagraph( p1 ) < getTargetParagraph( p2 );
2976 : : }
2977 : : }
2978 : :
2979 : : // --------------------------------------------------------------------
2980 : :
2981 : 0 : void EffectSequenceHelper::setTextReverse( CustomAnimationTextGroupPtr pTextGroup, sal_Bool bTextReverse )
2982 : : {
2983 [ # # ]: 0 : if( pTextGroup->mbTextReverse == bTextReverse )
2984 : : {
2985 : : // do nothing
2986 : : }
2987 : : else
2988 : : {
2989 [ # # ]: 0 : std::vector< CustomAnimationEffectPtr > aSortedVector(pTextGroup->maEffects.size());
2990 [ # # ]: 0 : std::copy( pTextGroup->maEffects.begin(), pTextGroup->maEffects.end(), aSortedVector.begin() );
2991 : 0 : ImplStlTextGroupSortHelper aSortHelper( bTextReverse );
2992 [ # # ]: 0 : std::sort( aSortedVector.begin(), aSortedVector.end(), aSortHelper );
2993 : :
2994 : 0 : pTextGroup->reset();
2995 : :
2996 : 0 : std::vector< CustomAnimationEffectPtr >::iterator aIter( aSortedVector.begin() );
2997 : 0 : const std::vector< CustomAnimationEffectPtr >::iterator aEnd( aSortedVector.end() );
2998 : :
2999 [ # # ][ # # ]: 0 : if( aIter != aEnd )
3000 : : {
3001 [ # # ]: 0 : pTextGroup->addEffect( (*aIter ) );
3002 [ # # ][ # # ]: 0 : EffectSequence::iterator aInsertIter( find( (*aIter++) ) );
3003 [ # # ][ # # ]: 0 : while( aIter != aEnd )
3004 : : {
3005 [ # # ][ # # ]: 0 : CustomAnimationEffectPtr pEffect( (*aIter++) );
3006 [ # # ][ # # ]: 0 : maEffects.erase( find( pEffect ) );
3007 [ # # ]: 0 : aInsertIter = maEffects.insert( ++aInsertIter, pEffect );
3008 [ # # ]: 0 : pTextGroup->addEffect( pEffect );
3009 [ # # ]: 0 : }
3010 : : }
3011 [ # # ]: 0 : notify_listeners();
3012 : : }
3013 : 0 : }
3014 : :
3015 : : // --------------------------------------------------------------------
3016 : :
3017 : 0 : void EffectSequenceHelper::addListener( ISequenceListener* pListener )
3018 : : {
3019 [ # # ][ # # ]: 0 : if( std::find( maListeners.begin(), maListeners.end(), pListener ) == maListeners.end() )
3020 : 0 : maListeners.push_back( pListener );
3021 : 0 : }
3022 : :
3023 : : // --------------------------------------------------------------------
3024 : :
3025 : 0 : void EffectSequenceHelper::removeListener( ISequenceListener* pListener )
3026 : : {
3027 : 0 : maListeners.remove( pListener );
3028 : 0 : }
3029 : :
3030 : : // --------------------------------------------------------------------
3031 : :
3032 : : struct stl_notify_listeners_func : public std::unary_function<ISequenceListener*, void>
3033 : : {
3034 : 4 : stl_notify_listeners_func() {}
3035 : 0 : void operator()(ISequenceListener* pListener) { pListener->notify_change(); }
3036 : : };
3037 : :
3038 : : // --------------------------------------------------------------------
3039 : :
3040 : 4 : void EffectSequenceHelper::notify_listeners()
3041 : : {
3042 : 4 : stl_notify_listeners_func aFunc;
3043 [ + - ]: 4 : std::for_each( maListeners.begin(), maListeners.end(), aFunc );
3044 : 4 : }
3045 : :
3046 : : // --------------------------------------------------------------------
3047 : :
3048 : 0 : void EffectSequenceHelper::create( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
3049 : : {
3050 : : DBG_ASSERT( xNode.is(), "sd::EffectSequenceHelper::create(), illegal argument" );
3051 : :
3052 [ # # ]: 0 : if( xNode.is() ) try
3053 : : {
3054 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
3055 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
3056 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
3057 : : {
3058 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
[ # # ]
3059 [ # # ]: 0 : createEffectsequence( xChildNode );
3060 [ # # ]: 0 : }
3061 : : }
3062 : 0 : catch( Exception& )
3063 : : {
3064 : : OSL_FAIL( "sd::EffectSequenceHelper::create(), exception cought!" );
3065 : : }
3066 : 0 : }
3067 : :
3068 : : // --------------------------------------------------------------------
3069 : :
3070 : 0 : void EffectSequenceHelper::createEffectsequence( const Reference< XAnimationNode >& xNode )
3071 : : {
3072 : : DBG_ASSERT( xNode.is(), "sd::EffectSequenceHelper::createEffectsequence(), illegal argument" );
3073 : :
3074 [ # # ]: 0 : if( xNode.is() ) try
3075 : : {
3076 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
3077 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
3078 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
3079 : : {
3080 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
[ # # ]
3081 : :
3082 [ # # ]: 0 : createEffects( xChildNode );
3083 [ # # ]: 0 : }
3084 : : }
3085 : 0 : catch( Exception& )
3086 : : {
3087 : : OSL_FAIL( "sd::EffectSequenceHelper::createEffectsequence(), exception cought!" );
3088 : : }
3089 : 0 : }
3090 : :
3091 : : // --------------------------------------------------------------------
3092 : :
3093 : 0 : void EffectSequenceHelper::createEffects( const Reference< XAnimationNode >& xNode )
3094 : : {
3095 : : DBG_ASSERT( xNode.is(), "sd::EffectSequenceHelper::createEffects(), illegal argument" );
3096 : :
3097 [ # # ]: 0 : if( xNode.is() ) try
3098 : : {
3099 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
3100 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
3101 [ # # ][ # # ]: 0 : while( xEnumeration->hasMoreElements() )
[ # # ]
3102 : : {
3103 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
[ # # ]
3104 : :
3105 [ # # ]: 0 : switch( xChildNode->getType() )
[ # # # ]
[ # # ]
3106 : : {
3107 : : // found an effect
3108 : : case AnimationNodeType::PAR:
3109 : : case AnimationNodeType::ITERATE:
3110 : : {
3111 [ # # ][ # # ]: 0 : CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xChildNode ) );
[ # # ]
3112 : :
3113 [ # # ]: 0 : if( pEffect->mnNodeType != -1 )
3114 : : {
3115 : 0 : pEffect->setEffectSequence( this );
3116 [ # # ]: 0 : maEffects.push_back(pEffect);
3117 [ # # ]: 0 : }
3118 : : }
3119 : 0 : break;
3120 : :
3121 : : // found an after effect
3122 : : case AnimationNodeType::SET:
3123 : : case AnimationNodeType::ANIMATECOLOR:
3124 : : {
3125 [ # # ]: 0 : processAfterEffect( xChildNode );
3126 : : }
3127 : 0 : break;
3128 : : }
3129 [ # # ]: 0 : }
3130 : : }
3131 : 0 : catch( Exception& )
3132 : : {
3133 : : OSL_FAIL( "sd::EffectSequenceHelper::createEffects(), exception cought!" );
3134 : : }
3135 : 0 : }
3136 : :
3137 : : // --------------------------------------------------------------------
3138 : :
3139 : 0 : void EffectSequenceHelper::processAfterEffect( const Reference< XAnimationNode >& xNode )
3140 : : {
3141 : : try
3142 : : {
3143 : 0 : Reference< XAnimationNode > xMaster;
3144 : :
3145 [ # # ][ # # ]: 0 : Sequence< NamedValue > aUserData( xNode->getUserData() );
3146 : 0 : sal_Int32 nLength = aUserData.getLength();
3147 : 0 : const NamedValue* p = aUserData.getConstArray();
3148 : :
3149 [ # # ]: 0 : while( nLength-- )
3150 : : {
3151 [ # # ]: 0 : if ( p->Name == "master-element" )
3152 : : {
3153 [ # # ]: 0 : p->Value >>= xMaster;
3154 : 0 : break;
3155 : : }
3156 : 0 : p++;
3157 : : }
3158 : :
3159 : : // only process if this is a valid after effect
3160 [ # # ]: 0 : if( xMaster.is() )
3161 : : {
3162 [ # # ]: 0 : CustomAnimationEffectPtr pMasterEffect;
3163 : :
3164 : : // find the master effect
3165 : 0 : stl_CustomAnimationEffect_search_node_predict aSearchPredict( xMaster );
3166 [ # # ]: 0 : EffectSequence::iterator aIter( std::find_if( maEffects.begin(), maEffects.end(), aSearchPredict ) );
3167 [ # # ]: 0 : if( aIter != maEffects.end() )
3168 [ # # ]: 0 : pMasterEffect = (*aIter );
3169 : :
3170 [ # # ]: 0 : if( pMasterEffect.get() )
3171 : : {
3172 : 0 : pMasterEffect->setHasAfterEffect( true );
3173 : :
3174 : : // find out what kind of after effect this is
3175 [ # # ][ # # ]: 0 : if( xNode->getType() == AnimationNodeType::ANIMATECOLOR )
[ # # ]
3176 : : {
3177 : : // its a dim
3178 [ # # ]: 0 : Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW );
3179 [ # # ][ # # ]: 0 : pMasterEffect->setDimColor( xAnimate->getTo() );
3180 : 0 : pMasterEffect->setAfterEffectOnNext( true );
3181 : : }
3182 : : else
3183 : : {
3184 : : // its a hide
3185 [ # # ]: 0 : Reference< XChild > xNodeChild( xNode, UNO_QUERY_THROW );
3186 [ # # ]: 0 : Reference< XChild > xMasterChild( xMaster, UNO_QUERY_THROW );
3187 [ # # ][ # # ]: 0 : pMasterEffect->setAfterEffectOnNext( xNodeChild->getParent() != xMasterChild->getParent() );
[ # # ][ # # ]
[ # # ]
3188 : : }
3189 [ # # ]: 0 : }
3190 [ # # ][ # # ]: 0 : }
3191 : : }
3192 : 0 : catch( Exception& )
3193 : : {
3194 : : OSL_FAIL( "sd::EffectSequenceHelper::processAfterEffect(), exception cought!" );
3195 : : }
3196 : 0 : }
3197 : :
3198 : : // ====================================================================
3199 : :
3200 [ - + ]: 8 : class AnimationChangeListener : public cppu::WeakImplHelper1< XChangesListener >
3201 : : {
3202 : : public:
3203 : 4 : AnimationChangeListener( MainSequence* pMainSequence ) : mpMainSequence( pMainSequence ) {}
3204 : :
3205 : : virtual void SAL_CALL changesOccurred( const ::com::sun::star::util::ChangesEvent& Event ) throw (RuntimeException);
3206 : : virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (RuntimeException);
3207 : : private:
3208 : : MainSequence* mpMainSequence;
3209 : : };
3210 : :
3211 : 0 : void SAL_CALL AnimationChangeListener::changesOccurred( const ::com::sun::star::util::ChangesEvent& ) throw (RuntimeException)
3212 : : {
3213 [ # # ]: 0 : if( mpMainSequence )
3214 : 0 : mpMainSequence->startRecreateTimer();
3215 : 0 : }
3216 : :
3217 : 0 : void SAL_CALL AnimationChangeListener::disposing( const ::com::sun::star::lang::EventObject& ) throw (RuntimeException)
3218 : : {
3219 : 0 : }
3220 : :
3221 : : // ====================================================================
3222 : :
3223 : 0 : MainSequence::MainSequence()
3224 [ # # ][ # # ]: 0 : : mxTimingRootNode( ::comphelper::getProcessServiceFactory()->createInstance("com.sun.star.animations.SequenceTimeContainer"), UNO_QUERY )
3225 : : , mbRebuilding( false )
3226 : : , mnRebuildLockGuard( 0 )
3227 [ # # ][ # # ]: 0 : , mbPendingRebuildRequest( false )
[ # # ][ # # ]
3228 : : {
3229 [ # # ]: 0 : if( mxTimingRootNode.is() )
3230 : : {
3231 [ # # ]: 0 : Sequence< ::com::sun::star::beans::NamedValue > aUserData( 1 );
3232 [ # # ]: 0 : aUserData[0].Name = "node-type";
3233 [ # # ][ # # ]: 0 : aUserData[0].Value <<= ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE;
3234 [ # # ][ # # ]: 0 : mxTimingRootNode->setUserData( aUserData );
[ # # ]
3235 : : }
3236 [ # # ]: 0 : init();
3237 : 0 : }
3238 : :
3239 : : // --------------------------------------------------------------------
3240 : :
3241 : 4 : MainSequence::MainSequence( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
3242 : : : mxTimingRootNode( xNode, UNO_QUERY )
3243 : : , mbRebuilding( false )
3244 : : , mnRebuildLockGuard( 0 )
3245 : : , mbPendingRebuildRequest( false )
3246 [ + - ][ + - ]: 4 : , mbIgnoreChanges( 0 )
[ + - ]
3247 : : {
3248 [ + - ]: 4 : init();
3249 : 4 : }
3250 : :
3251 : : // --------------------------------------------------------------------
3252 : :
3253 [ + - ]: 4 : MainSequence::~MainSequence()
3254 : : {
3255 [ + - ]: 4 : reset();
3256 [ - + ]: 8 : }
3257 : :
3258 : : // --------------------------------------------------------------------
3259 : :
3260 : 4 : void MainSequence::init()
3261 : : {
3262 : 4 : mnSequenceType = EffectNodeType::MAIN_SEQUENCE;
3263 : :
3264 : 4 : maTimer.SetTimeoutHdl( LINK(this, MainSequence, onTimerHdl) );
3265 : 4 : maTimer.SetTimeout(500);
3266 : :
3267 [ + - ][ + - ]: 4 : mxChangesListener.set( new AnimationChangeListener( this ) );
3268 : :
3269 : 4 : createMainSequence();
3270 : 4 : }
3271 : :
3272 : : // --------------------------------------------------------------------
3273 : :
3274 : 0 : void MainSequence::reset( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xTimingRootNode )
3275 : : {
3276 : 0 : reset();
3277 : :
3278 : 0 : mxTimingRootNode.set( xTimingRootNode, UNO_QUERY );
3279 : :
3280 : 0 : createMainSequence();
3281 : 0 : }
3282 : :
3283 : : // --------------------------------------------------------------------
3284 : :
3285 : 0 : Reference< ::com::sun::star::animations::XAnimationNode > MainSequence::getRootNode()
3286 : : {
3287 : : DBG_ASSERT( mnRebuildLockGuard == 0, "MainSequence::getRootNode(), rebuild is locked, ist this really what you want?" );
3288 : :
3289 [ # # ][ # # ]: 0 : if( maTimer.IsActive() && mbTimerMode )
[ # # ]
3290 : : {
3291 : : // force a rebuild NOW if one is pending
3292 : 0 : maTimer.Stop();
3293 : 0 : implRebuild();
3294 : : }
3295 : :
3296 : 0 : return EffectSequenceHelper::getRootNode();
3297 : : }
3298 : :
3299 : : // --------------------------------------------------------------------
3300 : :
3301 : 4 : void MainSequence::createMainSequence()
3302 : : {
3303 [ + - ]: 4 : if( mxTimingRootNode.is() ) try
3304 : : {
3305 [ + - ]: 4 : Reference< XEnumerationAccess > xEnumerationAccess( mxTimingRootNode, UNO_QUERY_THROW );
3306 [ + - ][ + - ]: 4 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ + - ]
3307 [ + - ][ + - ]: 4 : while( xEnumeration->hasMoreElements() )
[ - + ]
3308 : : {
3309 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
[ # # ]
3310 [ # # ]: 0 : sal_Int32 nNodeType = CustomAnimationEffect::get_node_type( xChildNode );
3311 [ # # ]: 0 : if( nNodeType == EffectNodeType::MAIN_SEQUENCE )
3312 : : {
3313 [ # # ]: 0 : mxSequenceRoot.set( xChildNode, UNO_QUERY );
3314 [ # # ]: 0 : EffectSequenceHelper::create( xChildNode );
3315 : : }
3316 [ # # ]: 0 : else if( nNodeType == EffectNodeType::INTERACTIVE_SEQUENCE )
3317 : : {
3318 [ # # ]: 0 : Reference< XTimeContainer > xInteractiveRoot( xChildNode, UNO_QUERY_THROW );
3319 [ # # ][ # # ]: 0 : InteractiveSequencePtr pIS( new InteractiveSequence( xInteractiveRoot, this ) );
[ # # ]
3320 [ # # ]: 0 : pIS->addListener( this );
3321 [ # # ][ # # ]: 0 : maInteractiveSequenceList.push_back( pIS );
3322 : : }
3323 : 0 : }
3324 : :
3325 : : // see if we have a mainsequence at all. if not, create one...
3326 [ + - ]: 4 : if( !mxSequenceRoot.is() )
3327 : : {
3328 [ + - ][ + - ]: 4 : mxSequenceRoot = Reference< XTimeContainer >::query(::comphelper::getProcessServiceFactory()->createInstance("com.sun.star.animations.SequenceTimeContainer"));
[ + - ][ + - ]
[ + - ]
3329 [ + - ]: 4 : if( mxSequenceRoot.is() )
3330 : : {
3331 [ + - ]: 4 : uno::Sequence< ::com::sun::star::beans::NamedValue > aUserData( 1 );
3332 [ + - ]: 4 : aUserData[0].Name = "node-type";
3333 [ + - ][ + - ]: 4 : aUserData[0].Value <<= ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE;
3334 [ + - ][ + - ]: 4 : mxSequenceRoot->setUserData( aUserData );
3335 : :
3336 : : // empty sequence until now, set duration to 0.0
3337 : : // explicitly (otherwise, this sequence will never
3338 : : // end)
3339 [ + - ][ + - ]: 4 : mxSequenceRoot->setDuration( makeAny((double)0.0) );
[ + - ]
3340 : :
3341 [ + - ]: 4 : Reference< XAnimationNode > xMainSequenceNode( mxSequenceRoot, UNO_QUERY_THROW );
3342 [ + - ][ + - ]: 4 : mxTimingRootNode->appendChild( xMainSequenceNode );
[ + - ]
3343 : : }
3344 : : }
3345 : :
3346 [ + - ]: 4 : updateTextGroups();
3347 : :
3348 [ + - ]: 4 : notify_listeners();
3349 : :
3350 [ + - ]: 4 : Reference< XChangesNotifier > xNotifier( mxTimingRootNode, UNO_QUERY );
3351 [ + - ]: 4 : if( xNotifier.is() )
3352 [ + - ][ + - ]: 4 : xNotifier->addChangesListener( mxChangesListener );
[ # # ]
3353 : : }
3354 : 0 : catch( Exception& )
3355 : : {
3356 : : OSL_FAIL( "sd::MainSequence::create(), exception cought!" );
3357 : 4 : return;
3358 : : }
3359 : :
3360 : : DBG_ASSERT( mxSequenceRoot.is(), "sd::MainSequence::create(), found no main sequence!" );
3361 : : }
3362 : :
3363 : : // --------------------------------------------------------------------
3364 : :
3365 : 4 : void MainSequence::reset()
3366 : : {
3367 [ + - ]: 4 : EffectSequenceHelper::reset();
3368 : :
3369 : 4 : InteractiveSequenceList::iterator aIter;
3370 [ - + ]: 4 : for( aIter = maInteractiveSequenceList.begin(); aIter != maInteractiveSequenceList.end(); ++aIter )
3371 [ # # ]: 0 : (*aIter)->reset();
3372 : 4 : maInteractiveSequenceList.clear();
3373 : :
3374 : : try
3375 : : {
3376 [ + - ]: 4 : Reference< XChangesNotifier > xNotifier( mxTimingRootNode, UNO_QUERY );
3377 [ + - ]: 4 : if( xNotifier.is() )
3378 [ + - ][ + - ]: 4 : xNotifier->removeChangesListener( mxChangesListener );
[ # # ]
3379 : : }
3380 [ # # ]: 0 : catch( Exception& )
3381 : : {
3382 : : // ...
3383 : : }
3384 : 4 : }
3385 : :
3386 : : // --------------------------------------------------------------------
3387 : :
3388 : 0 : InteractiveSequencePtr MainSequence::createInteractiveSequence( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape )
3389 : : {
3390 [ # # ]: 0 : InteractiveSequencePtr pIS;
3391 : :
3392 : : // create a new interactive sequence container
3393 [ # # ][ # # ]: 0 : Reference< XTimeContainer > xISRoot( ::comphelper::getProcessServiceFactory()->createInstance("com.sun.star.animations.SequenceTimeContainer"), UNO_QUERY );
[ # # ][ # # ]
3394 : : DBG_ASSERT( xISRoot.is(), "sd::MainSequence::createInteractiveSequence(), could not create \"com.sun.star.animations.SequenceTimeContainer\"!");
3395 [ # # ]: 0 : if( xISRoot.is() )
3396 : : {
3397 [ # # ]: 0 : uno::Sequence< ::com::sun::star::beans::NamedValue > aUserData( 1 );
3398 [ # # ]: 0 : aUserData[0].Name = "node-type";
3399 [ # # ][ # # ]: 0 : aUserData[0].Value <<= ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE ;
3400 [ # # ][ # # ]: 0 : xISRoot->setUserData( aUserData );
3401 : :
3402 [ # # ]: 0 : Reference< XChild > xChild( mxSequenceRoot, UNO_QUERY_THROW );
3403 [ # # ]: 0 : Reference< XAnimationNode > xISNode( xISRoot, UNO_QUERY_THROW );
3404 [ # # ][ # # ]: 0 : Reference< XTimeContainer > xParent( xChild->getParent(), UNO_QUERY_THROW );
[ # # ]
3405 [ # # ][ # # ]: 0 : xParent->appendChild( xISNode );
[ # # ]
3406 : : }
3407 [ # # ][ # # ]: 0 : pIS.reset( new InteractiveSequence( xISRoot, this) );
[ # # ]
3408 [ # # ]: 0 : pIS->setTriggerShape( xShape );
3409 [ # # ]: 0 : pIS->addListener( this );
3410 [ # # ]: 0 : maInteractiveSequenceList.push_back( pIS );
3411 : 0 : return pIS;
3412 : : }
3413 : :
3414 : : // --------------------------------------------------------------------
3415 : :
3416 : 0 : CustomAnimationEffectPtr MainSequence::findEffect( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) const
3417 : : {
3418 : 0 : CustomAnimationEffectPtr pEffect = EffectSequenceHelper::findEffect( xNode );
3419 : :
3420 [ # # ]: 0 : if( pEffect.get() == 0 )
3421 : : {
3422 : 0 : InteractiveSequenceList::const_iterator aIter;
3423 [ # # ][ # # ]: 0 : for( aIter = maInteractiveSequenceList.begin(); (aIter != maInteractiveSequenceList.end()) && (pEffect.get() == 0); ++aIter )
[ # # ][ # # ]
3424 : : {
3425 [ # # ][ # # ]: 0 : pEffect = (*aIter)->findEffect( xNode );
[ # # ]
3426 : : }
3427 : : }
3428 : 0 : return pEffect;
3429 : : }
3430 : :
3431 : : // --------------------------------------------------------------------
3432 : :
3433 : 0 : sal_Int32 MainSequence::getOffsetFromEffect( const CustomAnimationEffectPtr& pEffect ) const
3434 : : {
3435 [ # # ]: 0 : sal_Int32 nOffset = EffectSequenceHelper::getOffsetFromEffect( pEffect );
3436 : :
3437 [ # # ]: 0 : if( nOffset != -1 )
3438 : 0 : return nOffset;
3439 : :
3440 [ # # ]: 0 : nOffset = EffectSequenceHelper::getCount();
3441 : :
3442 : 0 : InteractiveSequenceList::const_iterator aIter;
3443 [ # # ]: 0 : for( aIter = maInteractiveSequenceList.begin(); aIter != maInteractiveSequenceList.end(); ++aIter )
3444 : : {
3445 [ # # ]: 0 : sal_Int32 nTemp = (*aIter)->getOffsetFromEffect( pEffect );
3446 [ # # ]: 0 : if( nTemp != -1 )
3447 : 0 : return nOffset + nTemp;
3448 : :
3449 [ # # ]: 0 : nOffset += (*aIter)->getCount();
3450 : : }
3451 : :
3452 : 0 : return -1;
3453 : : }
3454 : :
3455 : : // --------------------------------------------------------------------
3456 : :
3457 : 0 : CustomAnimationEffectPtr MainSequence::getEffectFromOffset( sal_Int32 nOffset ) const
3458 : : {
3459 [ # # ]: 0 : if( nOffset >= 0 )
3460 : : {
3461 [ # # ][ # # ]: 0 : if( nOffset < getCount() )
3462 [ # # ]: 0 : return EffectSequenceHelper::getEffectFromOffset( nOffset );
3463 : :
3464 [ # # ]: 0 : nOffset -= getCount();
3465 : :
3466 : 0 : InteractiveSequenceList::const_iterator aIter( maInteractiveSequenceList.begin() );
3467 : :
3468 [ # # ][ # # ]: 0 : while( (aIter != maInteractiveSequenceList.end()) && (nOffset > (*aIter)->getCount()) )
[ # # ][ # # ]
[ # # # # ]
3469 [ # # ]: 0 : nOffset -= (*aIter++)->getCount();
3470 : :
3471 [ # # ][ # # ]: 0 : if( (aIter != maInteractiveSequenceList.end()) && (nOffset >= 0) )
[ # # ][ # # ]
3472 [ # # ]: 0 : return (*aIter)->getEffectFromOffset( nOffset );
3473 : : }
3474 : :
3475 [ # # ]: 0 : CustomAnimationEffectPtr pEffect;
3476 [ # # ][ # # ]: 0 : return pEffect;
3477 : : }
3478 : :
3479 : : // --------------------------------------------------------------------
3480 : :
3481 : 0 : bool MainSequence::disposeShape( const Reference< XShape >& xShape )
3482 : : {
3483 [ # # ]: 0 : bool bChanges = EffectSequenceHelper::disposeShape( xShape );
3484 : :
3485 : 0 : InteractiveSequenceList::iterator aIter;
3486 [ # # ]: 0 : for( aIter = maInteractiveSequenceList.begin(); aIter != maInteractiveSequenceList.end(); )
3487 : : {
3488 [ # # ][ # # ]: 0 : if( (*aIter)->getTriggerShape() == xShape )
[ # # ]
3489 : : {
3490 [ # # ]: 0 : aIter = maInteractiveSequenceList.erase( aIter );
3491 : 0 : bChanges = true;
3492 : : }
3493 : : else
3494 : : {
3495 [ # # ]: 0 : bChanges |= (*aIter++)->disposeShape( xShape );
3496 : : }
3497 : : }
3498 : :
3499 [ # # ]: 0 : if( bChanges )
3500 [ # # ]: 0 : startRebuildTimer();
3501 : :
3502 : 0 : return bChanges;
3503 : : }
3504 : :
3505 : : // --------------------------------------------------------------------
3506 : :
3507 : 0 : bool MainSequence::hasEffect( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape )
3508 : : {
3509 [ # # ][ # # ]: 0 : if( EffectSequenceHelper::hasEffect( xShape ) )
3510 : 0 : return true;
3511 : :
3512 : 0 : InteractiveSequenceList::iterator aIter;
3513 [ # # ]: 0 : for( aIter = maInteractiveSequenceList.begin(); aIter != maInteractiveSequenceList.end(); )
3514 : : {
3515 [ # # ][ # # ]: 0 : if( (*aIter)->getTriggerShape() == xShape )
[ # # ]
3516 : 0 : return true;
3517 : :
3518 [ # # ][ # # ]: 0 : if( (*aIter++)->hasEffect( xShape ) )
3519 : 0 : return true;
3520 : : }
3521 : :
3522 : 0 : return false;
3523 : : }
3524 : :
3525 : : // --------------------------------------------------------------------
3526 : :
3527 : 0 : void MainSequence::insertTextRange( const com::sun::star::uno::Any& aTarget )
3528 : : {
3529 [ # # ]: 0 : EffectSequenceHelper::insertTextRange( aTarget );
3530 : :
3531 : 0 : InteractiveSequenceList::iterator aIter;
3532 [ # # ]: 0 : for( aIter = maInteractiveSequenceList.begin(); aIter != maInteractiveSequenceList.end(); ++aIter )
3533 : : {
3534 [ # # ]: 0 : (*aIter)->insertTextRange( aTarget );
3535 : : }
3536 : 0 : }
3537 : : // --------------------------------------------------------------------
3538 : :
3539 : 0 : void MainSequence::disposeTextRange( const com::sun::star::uno::Any& aTarget )
3540 : : {
3541 [ # # ]: 0 : EffectSequenceHelper::disposeTextRange( aTarget );
3542 : :
3543 : 0 : InteractiveSequenceList::iterator aIter;
3544 [ # # ]: 0 : for( aIter = maInteractiveSequenceList.begin(); aIter != maInteractiveSequenceList.end(); ++aIter )
3545 : : {
3546 [ # # ]: 0 : (*aIter)->disposeTextRange( aTarget );
3547 : : }
3548 : 0 : }
3549 : :
3550 : : // --------------------------------------------------------------------
3551 : :
3552 : : /** callback from the sd::View when an object just left text edit mode */
3553 : 0 : void MainSequence::onTextChanged( const Reference< XShape >& xShape )
3554 : : {
3555 [ # # ]: 0 : EffectSequenceHelper::onTextChanged( xShape );
3556 : :
3557 : 0 : InteractiveSequenceList::iterator aIter;
3558 [ # # ]: 0 : for( aIter = maInteractiveSequenceList.begin(); aIter != maInteractiveSequenceList.end(); ++aIter )
3559 : : {
3560 [ # # ]: 0 : (*aIter)->onTextChanged( xShape );
3561 : : }
3562 : 0 : }
3563 : :
3564 : : // --------------------------------------------------------------------
3565 : :
3566 : 0 : void EffectSequenceHelper::onTextChanged( const Reference< XShape >& xShape )
3567 : : {
3568 : 0 : bool bChanges = false;
3569 : :
3570 : 0 : EffectSequence::iterator aIter;
3571 [ # # ]: 0 : for( aIter = maEffects.begin(); aIter != maEffects.end(); ++aIter )
3572 : : {
3573 [ # # ][ # # ]: 0 : if( (*aIter)->getTargetShape() == xShape )
[ # # ]
3574 [ # # ]: 0 : bChanges |= (*aIter)->checkForText();
3575 : : }
3576 : :
3577 [ # # ]: 0 : if( bChanges )
3578 [ # # ]: 0 : EffectSequenceHelper::implRebuild();
3579 : 0 : }
3580 : :
3581 : : // --------------------------------------------------------------------
3582 : :
3583 : 0 : void MainSequence::rebuild()
3584 : : {
3585 : 0 : startRebuildTimer();
3586 : 0 : }
3587 : :
3588 : : // --------------------------------------------------------------------
3589 : :
3590 : 0 : void MainSequence::lockRebuilds()
3591 : : {
3592 : 0 : mnRebuildLockGuard++;
3593 : 0 : }
3594 : :
3595 : : // --------------------------------------------------------------------
3596 : :
3597 : 0 : void MainSequence::unlockRebuilds()
3598 : : {
3599 : : DBG_ASSERT( mnRebuildLockGuard, "sd::MainSequence::unlockRebuilds(), no corresponding lockRebuilds() call!" );
3600 [ # # ]: 0 : if( mnRebuildLockGuard )
3601 : 0 : mnRebuildLockGuard--;
3602 : :
3603 [ # # ][ # # ]: 0 : if( (mnRebuildLockGuard == 0) && mbPendingRebuildRequest )
3604 : : {
3605 : 0 : mbPendingRebuildRequest = false;
3606 : 0 : startRebuildTimer();
3607 : : }
3608 : 0 : }
3609 : :
3610 : : // --------------------------------------------------------------------
3611 : :
3612 : 0 : void MainSequence::implRebuild()
3613 : : {
3614 [ # # ]: 0 : if( mnRebuildLockGuard )
3615 : : {
3616 : 0 : mbPendingRebuildRequest = true;
3617 : 0 : return;
3618 : : }
3619 : :
3620 : 0 : mbRebuilding = true;
3621 : :
3622 [ # # ]: 0 : EffectSequenceHelper::implRebuild();
3623 : :
3624 : 0 : InteractiveSequenceList::iterator aIter( maInteractiveSequenceList.begin() );
3625 : 0 : const InteractiveSequenceList::iterator aEnd( maInteractiveSequenceList.end() );
3626 [ # # ]: 0 : while( aIter != aEnd )
3627 : : {
3628 [ # # ]: 0 : InteractiveSequencePtr pIS( (*aIter) );
3629 [ # # ]: 0 : if( pIS->maEffects.empty() )
3630 : : {
3631 : : // remove empty interactive sequences
3632 [ # # ]: 0 : aIter = maInteractiveSequenceList.erase( aIter );
3633 : :
3634 [ # # ]: 0 : Reference< XChild > xChild( mxSequenceRoot, UNO_QUERY_THROW );
3635 [ # # ][ # # ]: 0 : Reference< XTimeContainer > xParent( xChild->getParent(), UNO_QUERY_THROW );
[ # # ]
3636 [ # # ]: 0 : Reference< XAnimationNode > xISNode( pIS->mxSequenceRoot, UNO_QUERY_THROW );
3637 [ # # ][ # # ]: 0 : xParent->removeChild( xISNode );
3638 : : }
3639 : : else
3640 : : {
3641 [ # # ]: 0 : pIS->implRebuild();
3642 : 0 : ++aIter;
3643 : : }
3644 [ # # ]: 0 : }
3645 : :
3646 [ # # ]: 0 : notify_listeners();
3647 : 0 : mbRebuilding = false;
3648 : : }
3649 : :
3650 : : // --------------------------------------------------------------------
3651 : :
3652 : 0 : void MainSequence::notify_change()
3653 : : {
3654 : 0 : notify_listeners();
3655 : 0 : }
3656 : :
3657 : : // --------------------------------------------------------------------
3658 : :
3659 : 0 : bool MainSequence::setTrigger( const CustomAnimationEffectPtr& pEffect, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xTriggerShape )
3660 : : {
3661 : 0 : EffectSequenceHelper* pOldSequence = pEffect->getEffectSequence();
3662 : :
3663 : 0 : EffectSequenceHelper* pNewSequence = 0;
3664 [ # # ]: 0 : if( xTriggerShape.is() )
3665 : : {
3666 : 0 : InteractiveSequenceList::iterator aIter( maInteractiveSequenceList.begin() );
3667 : 0 : const InteractiveSequenceList::iterator aEnd( maInteractiveSequenceList.end() );
3668 [ # # ]: 0 : while( aIter != aEnd )
3669 : : {
3670 [ # # ]: 0 : InteractiveSequencePtr pIS( (*aIter++) );
3671 [ # # ][ # # ]: 0 : if( pIS->getTriggerShape() == xTriggerShape )
[ # # ]
3672 : : {
3673 : 0 : pNewSequence = pIS.get();
3674 : : break;
3675 : : }
3676 [ # # ][ # # ]: 0 : }
3677 : :
3678 [ # # ]: 0 : if( !pNewSequence )
3679 [ # # ][ # # ]: 0 : pNewSequence = createInteractiveSequence( xTriggerShape ).get();
3680 : : }
3681 : : else
3682 : : {
3683 : 0 : pNewSequence = this;
3684 : : }
3685 : :
3686 [ # # ]: 0 : if( pOldSequence != pNewSequence )
3687 : : {
3688 [ # # ]: 0 : if( pOldSequence )
3689 : 0 : pOldSequence->maEffects.remove( pEffect );
3690 [ # # ]: 0 : if( pNewSequence )
3691 : 0 : pNewSequence->maEffects.push_back( pEffect );
3692 : 0 : pEffect->setEffectSequence( pNewSequence );
3693 : 0 : return true;
3694 : : }
3695 : : else
3696 : : {
3697 : 0 : return false;
3698 : : }
3699 : :
3700 : : }
3701 : :
3702 : : // --------------------------------------------------------------------
3703 : :
3704 : 0 : IMPL_LINK_NOARG(MainSequence, onTimerHdl)
3705 : : {
3706 [ # # ]: 0 : if( mbTimerMode )
3707 : : {
3708 : 0 : implRebuild();
3709 : : }
3710 : : else
3711 : : {
3712 : 0 : reset();
3713 : 0 : createMainSequence();
3714 : : }
3715 : :
3716 : 0 : return 0;
3717 : : }
3718 : :
3719 : : // --------------------------------------------------------------------
3720 : :
3721 : : /** starts a timer that recreates the internal structure from the API core after 1 second */
3722 : 0 : void MainSequence::startRecreateTimer()
3723 : : {
3724 [ # # ][ # # ]: 0 : if( !mbRebuilding && (mbIgnoreChanges == 0) )
3725 : : {
3726 : 0 : mbTimerMode = false;
3727 : 0 : maTimer.Start();
3728 : : }
3729 : 0 : }
3730 : :
3731 : : // --------------------------------------------------------------------
3732 : :
3733 : : /** starts a timer that rebuilds the API core from the internal structure after 1 second */
3734 : 0 : void MainSequence::startRebuildTimer()
3735 : : {
3736 : 0 : mbTimerMode = true;
3737 : 0 : maTimer.Start();
3738 : 0 : }
3739 : :
3740 : : // ====================================================================
3741 : :
3742 : 0 : InteractiveSequence::InteractiveSequence( const Reference< XTimeContainer >& xSequenceRoot, MainSequence* pMainSequence )
3743 : 0 : : EffectSequenceHelper( xSequenceRoot ), mpMainSequence( pMainSequence )
3744 : : {
3745 : 0 : mnSequenceType = EffectNodeType::INTERACTIVE_SEQUENCE;
3746 : :
3747 : : try
3748 : : {
3749 [ # # ]: 0 : if( mxSequenceRoot.is() )
3750 : : {
3751 [ # # ]: 0 : Reference< XEnumerationAccess > xEnumerationAccess( mxSequenceRoot, UNO_QUERY_THROW );
3752 [ # # ][ # # ]: 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
[ # # ]
3753 [ # # ][ # # ]: 0 : while( !mxEventSource.is() && xEnumeration->hasMoreElements() )
[ # # ][ # # ]
[ # # ]
3754 : : {
3755 [ # # ][ # # ]: 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
[ # # ]
3756 : :
3757 : 0 : Event aEvent;
3758 [ # # ][ # # ]: 0 : if( (xChildNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::ON_CLICK) )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ]
3759 [ # # ]: 0 : aEvent.Source >>= mxEventSource;
3760 [ # # ]: 0 : }
3761 : : }
3762 : : }
3763 [ # # ]: 0 : catch( Exception& )
3764 : : {
3765 : : OSL_FAIL( "sd::InteractiveSequence::InteractiveSequence(), exception cought!" );
3766 : 0 : return;
3767 : : }
3768 : : }
3769 : :
3770 : : // --------------------------------------------------------------------
3771 : :
3772 : 0 : void InteractiveSequence::rebuild()
3773 : : {
3774 : 0 : mpMainSequence->rebuild();
3775 : 0 : }
3776 : :
3777 : 0 : void InteractiveSequence::implRebuild()
3778 : : {
3779 : 0 : EffectSequenceHelper::implRebuild();
3780 : 0 : }
3781 : :
3782 : : // --------------------------------------------------------------------
3783 : :
3784 : 0 : MainSequenceRebuildGuard::MainSequenceRebuildGuard( const MainSequencePtr& pMainSequence )
3785 : 0 : : mpMainSequence( pMainSequence )
3786 : : {
3787 [ # # ]: 0 : if( mpMainSequence.get() )
3788 : 0 : mpMainSequence->lockRebuilds();
3789 : 0 : }
3790 : :
3791 : 0 : MainSequenceRebuildGuard::~MainSequenceRebuildGuard()
3792 : : {
3793 [ # # ]: 0 : if( mpMainSequence.get() )
3794 [ # # ]: 0 : mpMainSequence->unlockRebuilds();
3795 : 0 : }
3796 : :
3797 : :
3798 : : }
3799 : :
3800 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|