src/corelib/animation/qsequentialanimationgroup.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     \class QSequentialAnimationGroup
       
    44     \brief The QSequentialAnimationGroup class provides a sequential group of animations.
       
    45     \since 4.6
       
    46     \ingroup animation
       
    47 
       
    48     QSequentialAnimationGroup is a QAnimationGroup that runs its
       
    49     animations in sequence, i.e., it starts one animation after
       
    50     another has finished playing. The animations are played in the
       
    51     order they are added to the group (using
       
    52     \l{QAnimationGroup::}{addAnimation()} or
       
    53     \l{QAnimationGroup::}{insertAnimationAt()}). The animation group
       
    54     finishes when its last animation has finished.
       
    55 
       
    56     At each moment there is at most one animation that is active in
       
    57     the group; it is returned by currentAnimation(). An empty group
       
    58     has no current animation.
       
    59 
       
    60     A sequential animation group can be treated as any other
       
    61     animation, i.e., it can be started, stopped, and added to other
       
    62     groups. You can also call addPause() or insertPauseAt() to add a
       
    63     pause to a sequential animation group.
       
    64 
       
    65     \code
       
    66         QSequentialAnimationGroup group;
       
    67 
       
    68         group.addAnimation(anim1);
       
    69         group.addAnimation(anim2);
       
    70 
       
    71         group.start();
       
    72     \endcode
       
    73 
       
    74     In this example, \c anim1 and \c anim2 are two already set up
       
    75     \l{QPropertyAnimation}s.
       
    76 
       
    77     \sa QAnimationGroup, QAbstractAnimation, {The Animation Framework}
       
    78 */
       
    79 
       
    80 #include "qsequentialanimationgroup.h"
       
    81 #include "qsequentialanimationgroup_p.h"
       
    82 
       
    83 #include "qpauseanimation.h"
       
    84 
       
    85 #include <QtCore/qdebug.h>
       
    86 
       
    87 #ifndef QT_NO_ANIMATION
       
    88 
       
    89 QT_BEGIN_NAMESPACE
       
    90 
       
    91 bool QSequentialAnimationGroupPrivate::atEnd() const
       
    92 {
       
    93     // we try to detect if we're at the end of the group
       
    94     //this is true if the following conditions are true:
       
    95     // 1. we're in the last loop
       
    96     // 2. the direction is forward
       
    97     // 3. the current animation is the last one
       
    98     // 4. the current animation has reached its end
       
    99     const int animTotalCurrentTime = QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime;
       
   100     return (currentLoop == loopCount - 1
       
   101         && direction == QAbstractAnimation::Forward
       
   102         && currentAnimation == animations.last()
       
   103         && animTotalCurrentTime == animationActualTotalDuration(currentAnimationIndex));
       
   104 }
       
   105 
       
   106 int QSequentialAnimationGroupPrivate::animationActualTotalDuration(int index) const
       
   107 {
       
   108     QAbstractAnimation *anim = animations.at(index);
       
   109     int ret = anim->totalDuration();
       
   110     if (ret == -1 && actualDuration.size() > index)
       
   111         ret = actualDuration.at(index); //we can try the actual duration there
       
   112     return ret;
       
   113 }
       
   114 
       
   115 QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivate::indexForCurrentTime() const
       
   116 {
       
   117     Q_ASSERT(!animations.isEmpty());
       
   118 
       
   119     AnimationIndex ret;
       
   120     int duration = 0;
       
   121 
       
   122     for (int i = 0; i < animations.size(); ++i) {
       
   123         duration = animationActualTotalDuration(i);
       
   124 
       
   125         // 'animation' is the current animation if one of these reasons is true:
       
   126         // 1. it's duration is undefined
       
   127         // 2. it ends after msecs
       
   128         // 3. it is the last animation (this can happen in case there is at least 1 uncontrolled animation)
       
   129         // 4. it ends exactly in msecs and the direction is backwards
       
   130         if (duration == -1 || currentTime < (ret.timeOffset + duration)
       
   131             || (currentTime == (ret.timeOffset + duration) && direction == QAbstractAnimation::Backward)) {
       
   132             ret.index = i;
       
   133             return ret;
       
   134         }
       
   135 
       
   136         // 'animation' has a non-null defined duration and is not the one at time 'msecs'.
       
   137         ret.timeOffset += duration;
       
   138     }
       
   139 
       
   140     // this can only happen when one of those conditions is true:
       
   141     // 1. the duration of the group is undefined and we passed its actual duration
       
   142     // 2. there are only 0-duration animations in the group
       
   143     ret.timeOffset -= duration;
       
   144     ret.index = animations.size() - 1;
       
   145     return ret;
       
   146 }
       
   147 
       
   148 void QSequentialAnimationGroupPrivate::restart()
       
   149 {
       
   150     // restarting the group by making the first/last animation the current one
       
   151     if (direction == QAbstractAnimation::Forward) {
       
   152         lastLoop = 0;
       
   153         if (currentAnimationIndex == 0)
       
   154             activateCurrentAnimation();
       
   155         else
       
   156             setCurrentAnimation(0);
       
   157     } else { // direction == QAbstractAnimation::Backward
       
   158         lastLoop = loopCount - 1;
       
   159         int index = animations.size() - 1;
       
   160         if (currentAnimationIndex == index)
       
   161             activateCurrentAnimation();
       
   162         else
       
   163             setCurrentAnimation(index);
       
   164     }
       
   165 }
       
   166 
       
   167 /*!
       
   168     \internal
       
   169     This manages advancing the execution of a group running forwards (time has gone forward),
       
   170     which is the same behaviour for rewinding the execution of a group running backwards
       
   171     (time has gone backward).
       
   172 */
       
   173 void QSequentialAnimationGroupPrivate::advanceForwards(const AnimationIndex &newAnimationIndex)
       
   174 {
       
   175     if (lastLoop < currentLoop) {
       
   176         // we need to fast forward to the end
       
   177         for (int i = currentAnimationIndex; i < animations.size(); ++i) {
       
   178             QAbstractAnimation *anim = animations.at(i);
       
   179             setCurrentAnimation(i, true);
       
   180             anim->setCurrentTime(animationActualTotalDuration(i));
       
   181         }
       
   182         // this will make sure the current animation is reset to the beginning
       
   183         if (animations.size() == 1)
       
   184             // we need to force activation because setCurrentAnimation will have no effect
       
   185             activateCurrentAnimation();
       
   186         else
       
   187             setCurrentAnimation(0, true);
       
   188     }
       
   189 
       
   190     // and now we need to fast forward from the current position to
       
   191     for (int i = currentAnimationIndex; i < newAnimationIndex.index; ++i) {     //### WRONG,
       
   192         QAbstractAnimation *anim = animations.at(i);
       
   193         setCurrentAnimation(i, true);
       
   194         anim->setCurrentTime(animationActualTotalDuration(i));
       
   195     }
       
   196     // setting the new current animation will happen later
       
   197 }
       
   198 
       
   199 /*!
       
   200     \internal
       
   201     This manages rewinding the execution of a group running forwards (time has gone forward),
       
   202     which is the same behaviour for advancing the execution of a group running backwards
       
   203     (time has gone backward).
       
   204 */
       
   205 void QSequentialAnimationGroupPrivate::rewindForwards(const AnimationIndex &newAnimationIndex)
       
   206 {
       
   207     if (lastLoop > currentLoop) {
       
   208         // we need to fast rewind to the beginning
       
   209         for (int i = currentAnimationIndex; i >= 0 ; --i) {
       
   210             QAbstractAnimation *anim = animations.at(i);
       
   211             setCurrentAnimation(i, true);
       
   212             anim->setCurrentTime(0);
       
   213         }
       
   214         // this will make sure the current animation is reset to the end
       
   215         if (animations.size() == 1)
       
   216             // we need to force activation because setCurrentAnimation will have no effect
       
   217             activateCurrentAnimation();
       
   218         else
       
   219             setCurrentAnimation(animations.count() - 1, true);
       
   220     }
       
   221 
       
   222     // and now we need to fast rewind from the current position to
       
   223     for (int i = currentAnimationIndex; i > newAnimationIndex.index; --i) {
       
   224         QAbstractAnimation *anim = animations.at(i);
       
   225         setCurrentAnimation(i, true);
       
   226         anim->setCurrentTime(0);
       
   227     }
       
   228     // setting the new current animation will happen later
       
   229 }
       
   230 
       
   231 /*!
       
   232     \fn QSequentialAnimationGroup::currentAnimationChanged(QAbstractAnimation *current)
       
   233 
       
   234     QSequentialAnimationGroup emits this signal when currentAnimation
       
   235     has been changed. \a current is the current animation.
       
   236 
       
   237     \sa currentAnimation()
       
   238 */
       
   239 
       
   240 
       
   241 /*!
       
   242     Constructs a QSequentialAnimationGroup.
       
   243     \a parent is passed to QObject's constructor.
       
   244 */
       
   245 QSequentialAnimationGroup::QSequentialAnimationGroup(QObject *parent)
       
   246     : QAnimationGroup(*new QSequentialAnimationGroupPrivate, parent)
       
   247 {
       
   248 }
       
   249 
       
   250 /*!
       
   251     \internal
       
   252 */
       
   253 QSequentialAnimationGroup::QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd,
       
   254                                                      QObject *parent)
       
   255     : QAnimationGroup(dd, parent)
       
   256 {
       
   257 }
       
   258 
       
   259 /*!
       
   260     Destroys the animation group. It will also destroy all its animations.
       
   261 */
       
   262 QSequentialAnimationGroup::~QSequentialAnimationGroup()
       
   263 {
       
   264 }
       
   265 
       
   266 /*!
       
   267     Adds a pause of \a msecs to this animation group.
       
   268     The pause is considered as a special type of animation, thus 
       
   269     \l{QAnimationGroup::animationCount()}{animationCount} will be 
       
   270     increased by one.
       
   271 
       
   272     \sa insertPauseAt(), QAnimationGroup::addAnimation()
       
   273 */
       
   274 QPauseAnimation *QSequentialAnimationGroup::addPause(int msecs)
       
   275 {
       
   276     QPauseAnimation *pause = new QPauseAnimation(msecs);
       
   277     addAnimation(pause);
       
   278     return pause;
       
   279 }
       
   280 
       
   281 /*!
       
   282     Inserts a pause of \a msecs milliseconds at \a index in this animation
       
   283     group.
       
   284 
       
   285     \sa addPause(), QAnimationGroup::insertAnimationAt()
       
   286 */
       
   287 QPauseAnimation *QSequentialAnimationGroup::insertPauseAt(int index, int msecs)
       
   288 {
       
   289     Q_D(const QSequentialAnimationGroup);
       
   290 
       
   291     if (index < 0 || index > d->animations.size()) {
       
   292         qWarning("QSequentialAnimationGroup::insertPauseAt: index is out of bounds");
       
   293         return 0;
       
   294     }
       
   295 
       
   296     QPauseAnimation *pause = new QPauseAnimation(msecs);
       
   297     insertAnimationAt(index, pause);
       
   298     return pause;
       
   299 }
       
   300 
       
   301 
       
   302 /*!
       
   303     \property QSequentialAnimationGroup::currentAnimation
       
   304     Returns the animation in the current time.
       
   305 
       
   306     \sa currentAnimationChanged()
       
   307 */
       
   308 QAbstractAnimation *QSequentialAnimationGroup::currentAnimation() const
       
   309 {
       
   310     Q_D(const QSequentialAnimationGroup);
       
   311     return d->currentAnimation;
       
   312 }
       
   313 
       
   314 /*!
       
   315     \reimp
       
   316 */
       
   317 int QSequentialAnimationGroup::duration() const
       
   318 {
       
   319     Q_D(const QSequentialAnimationGroup);
       
   320     int ret = 0;
       
   321 
       
   322     for (int i = 0; i < d->animations.size(); ++i) {
       
   323         QAbstractAnimation *animation = d->animations.at(i);
       
   324         const int currentDuration = animation->totalDuration();
       
   325         if (currentDuration == -1)
       
   326             return -1; // Undetermined length
       
   327 
       
   328         ret += currentDuration;
       
   329     }
       
   330 
       
   331     return ret;
       
   332 }
       
   333 
       
   334 /*!
       
   335     \reimp
       
   336 */
       
   337 void QSequentialAnimationGroup::updateCurrentTime(int currentTime)
       
   338 {
       
   339     Q_D(QSequentialAnimationGroup);
       
   340     if (!d->currentAnimation)
       
   341         return;
       
   342 
       
   343     const QSequentialAnimationGroupPrivate::AnimationIndex newAnimationIndex = d->indexForCurrentTime();
       
   344 
       
   345     // remove unneeded animations from actualDuration list
       
   346     while (newAnimationIndex.index < d->actualDuration.size())
       
   347         d->actualDuration.removeLast();
       
   348 
       
   349     // newAnimationIndex.index is the new current animation
       
   350     if (d->lastLoop < d->currentLoop
       
   351         || (d->lastLoop == d->currentLoop && d->currentAnimationIndex < newAnimationIndex.index)) {
       
   352             // advancing with forward direction is the same as rewinding with backwards direction
       
   353             d->advanceForwards(newAnimationIndex);
       
   354     } else if (d->lastLoop > d->currentLoop
       
   355         || (d->lastLoop == d->currentLoop && d->currentAnimationIndex > newAnimationIndex.index)) {
       
   356             // rewinding with forward direction is the same as advancing with backwards direction
       
   357             d->rewindForwards(newAnimationIndex);
       
   358     }
       
   359 
       
   360     d->setCurrentAnimation(newAnimationIndex.index);
       
   361 
       
   362     const int newCurrentTime = currentTime - newAnimationIndex.timeOffset;
       
   363 
       
   364     if (d->currentAnimation) {
       
   365         d->currentAnimation->setCurrentTime(newCurrentTime);
       
   366         if (d->atEnd()) {
       
   367             //we make sure that we don't exceed the duration here
       
   368             d->currentTime += QAbstractAnimationPrivate::get(d->currentAnimation)->totalCurrentTime - newCurrentTime;
       
   369             stop();
       
   370         }
       
   371     } else {
       
   372         //the only case where currentAnimation could be null
       
   373         //is when all animations have been removed
       
   374         Q_ASSERT(d->animations.isEmpty());
       
   375         d->currentTime = 0;
       
   376         stop();
       
   377     }
       
   378 
       
   379     d->lastLoop = d->currentLoop;
       
   380 }
       
   381 
       
   382 /*!
       
   383     \reimp
       
   384 */
       
   385 void QSequentialAnimationGroup::updateState(QAbstractAnimation::State oldState,
       
   386                                             QAbstractAnimation::State newState)
       
   387 {
       
   388     Q_D(QSequentialAnimationGroup);
       
   389     QAnimationGroup::updateState(oldState, newState);
       
   390 
       
   391     if (!d->currentAnimation)
       
   392         return;
       
   393 
       
   394     switch (newState) {
       
   395     case Stopped:
       
   396         d->currentAnimation->stop();
       
   397         break;
       
   398     case Paused:
       
   399         if (oldState == d->currentAnimation->state()
       
   400             && oldState == QSequentialAnimationGroup::Running) {
       
   401                 d->currentAnimation->pause();
       
   402             }
       
   403         else
       
   404             d->restart();
       
   405         break;
       
   406     case Running:
       
   407         if (oldState == d->currentAnimation->state()
       
   408             && oldState == QSequentialAnimationGroup::Paused)
       
   409             d->currentAnimation->start();
       
   410         else
       
   411             d->restart();
       
   412         break;
       
   413     }
       
   414 }
       
   415 
       
   416 /*!
       
   417     \reimp
       
   418 */
       
   419 void QSequentialAnimationGroup::updateDirection(QAbstractAnimation::Direction direction)
       
   420 {
       
   421     Q_D(QSequentialAnimationGroup);
       
   422     // we need to update the direction of the current animation
       
   423     if (state() != Stopped && d->currentAnimation)
       
   424         d->currentAnimation->setDirection(direction);
       
   425 }
       
   426 
       
   427 /*!
       
   428     \reimp
       
   429 */
       
   430 bool QSequentialAnimationGroup::event(QEvent *event)
       
   431 {
       
   432     return QAnimationGroup::event(event);
       
   433 }
       
   434 
       
   435 void QSequentialAnimationGroupPrivate::setCurrentAnimation(int index, bool intermediate)
       
   436 {
       
   437     Q_Q(QSequentialAnimationGroup);
       
   438 
       
   439     index = qMin(index, animations.count() - 1);
       
   440 
       
   441     if (index == -1) {
       
   442         Q_ASSERT(animations.isEmpty());
       
   443         currentAnimationIndex = -1;
       
   444         currentAnimation = 0;
       
   445         return;
       
   446     }
       
   447 
       
   448     // need these two checks below because this func can be called after the current animation
       
   449     // has been removed
       
   450     if (index == currentAnimationIndex && animations.at(index) == currentAnimation)
       
   451         return;
       
   452 
       
   453     // stop the old current animation
       
   454     if (currentAnimation)
       
   455         currentAnimation->stop();
       
   456 
       
   457     currentAnimation = animations.at(index);
       
   458     currentAnimationIndex = index;
       
   459 
       
   460     emit q->currentAnimationChanged(currentAnimation);
       
   461 
       
   462     activateCurrentAnimation(intermediate);
       
   463 }
       
   464 
       
   465 void QSequentialAnimationGroupPrivate::activateCurrentAnimation(bool intermediate)
       
   466 {
       
   467     Q_Q(QSequentialAnimationGroup);
       
   468 
       
   469     if (!currentAnimation)
       
   470         return;
       
   471 
       
   472     if (state == QSequentialAnimationGroup::Stopped)
       
   473         return;
       
   474 
       
   475     currentAnimation->stop();
       
   476 
       
   477     // we ensure the direction is consistent with the group's direction
       
   478     currentAnimation->setDirection(direction);
       
   479 
       
   480     // connects to the finish signal of uncontrolled animations
       
   481     if (currentAnimation->totalDuration() == -1)
       
   482         QObject::connect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished()));
       
   483 
       
   484     currentAnimation->start();
       
   485     if (!intermediate && state == QSequentialAnimationGroup::Paused)
       
   486         currentAnimation->pause();
       
   487 }
       
   488 
       
   489 void QSequentialAnimationGroupPrivate::_q_uncontrolledAnimationFinished()
       
   490 {
       
   491     Q_Q(QSequentialAnimationGroup);
       
   492     Q_ASSERT(qobject_cast<QAbstractAnimation *>(q->sender()) == currentAnimation);
       
   493 
       
   494     // we trust the duration returned by the animation
       
   495     while (actualDuration.size() < (currentAnimationIndex + 1))
       
   496         actualDuration.append(-1);
       
   497     actualDuration[currentAnimationIndex] = currentAnimation->currentTime();
       
   498 
       
   499     QObject::disconnect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished()));
       
   500 
       
   501     if ((direction == QAbstractAnimation::Forward && currentAnimation == animations.last())
       
   502         || (direction == QAbstractAnimation::Backward && currentAnimationIndex == 0)) {
       
   503         // we don't handle looping of a group with undefined duration
       
   504         q->stop();
       
   505     } else if (direction == QAbstractAnimation::Forward) {
       
   506         // set the current animation to be the next one
       
   507         setCurrentAnimation(currentAnimationIndex + 1);
       
   508     } else {
       
   509         // set the current animation to be the previous one
       
   510         setCurrentAnimation(currentAnimationIndex - 1);
       
   511     }
       
   512 }
       
   513 
       
   514 /*!
       
   515     \internal
       
   516     This method is called whenever an animation is added to
       
   517     the group at index \a index.
       
   518     Note: We only support insertion after the current animation
       
   519 */
       
   520 void QSequentialAnimationGroupPrivate::animationInsertedAt(int index)
       
   521 {
       
   522     if (currentAnimation == 0)
       
   523         setCurrentAnimation(0); // initialize the current animation
       
   524 
       
   525     if (currentAnimationIndex == index
       
   526         && currentAnimation->currentTime() == 0 && currentAnimation->currentLoop() == 0) {
       
   527             //in this case we simply insert an animation before the current one has actually started
       
   528             setCurrentAnimation(index);
       
   529     }
       
   530 
       
   531     //we update currentAnimationIndex in case it has changed (the animation pointer is still valid)
       
   532     currentAnimationIndex = animations.indexOf(currentAnimation);
       
   533 
       
   534     if (index < currentAnimationIndex || currentLoop != 0) {
       
   535         qWarning("QSequentialGroup::insertAnimationAt only supports to add animations after the current one.");
       
   536         return; //we're not affected because it is added after the current one
       
   537     }
       
   538 }
       
   539 
       
   540 /*!
       
   541     \internal
       
   542     This method is called whenever an animation is removed from
       
   543     the group at index \a index. The animation is no more listed when this
       
   544     method is called.
       
   545 */
       
   546 void QSequentialAnimationGroupPrivate::animationRemovedAt(int index)
       
   547 {
       
   548     Q_Q(QSequentialAnimationGroup);
       
   549     QAnimationGroupPrivate::animationRemovedAt(index);
       
   550 
       
   551     Q_ASSERT(currentAnimation); // currentAnimation should always be set
       
   552 
       
   553     if (actualDuration.size() > index)
       
   554         actualDuration.removeAt(index);
       
   555 
       
   556     const int currentIndex = animations.indexOf(currentAnimation);
       
   557     if (currentIndex == -1) {
       
   558         //we're removing the current animation, let's update it to another one
       
   559         if (index < animations.count())
       
   560             setCurrentAnimation(index); //let's try to take the next one
       
   561         else if (index > 0)
       
   562             setCurrentAnimation(index - 1);
       
   563         else// case all animations were removed
       
   564             setCurrentAnimation(-1);
       
   565     } else if (currentAnimationIndex > index) {
       
   566         currentAnimationIndex--;
       
   567     }
       
   568 
       
   569     // duration of the previous animations up to the current animation
       
   570     currentTime = 0;
       
   571     for (int i = 0; i < currentAnimationIndex; ++i) {
       
   572         const int current = animationActualTotalDuration(i);
       
   573         currentTime += current;
       
   574     }
       
   575 
       
   576     if (currentIndex != -1) {
       
   577         //the current animation is not the one being removed
       
   578         //so we add its current time to the current time of this group
       
   579         currentTime += QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime;
       
   580     }
       
   581 
       
   582     //let's also update the total current time
       
   583     totalCurrentTime = currentTime + loopCount * q->duration();
       
   584 }
       
   585 
       
   586 QT_END_NAMESPACE
       
   587 
       
   588 #include "moc_qsequentialanimationgroup.cpp"
       
   589 
       
   590 #endif //QT_NO_ANIMATION