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