1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "private/qdeclarativestate_p_p.h"
43 #include "private/qdeclarativestate_p.h"
44
45 #include "private/qdeclarativetransition_p.h"
46 #include "private/qdeclarativestategroup_p.h"
47 #include "private/qdeclarativestateoperations_p.h"
48 #include "private/qdeclarativeanimation_p.h"
49 #include "private/qdeclarativeanimation_p_p.h"
50
51 #include <qdeclarativebinding_p.h>
52 #include <qdeclarativeglobal_p.h>
53
54 #include <QtCore/qdebug.h>
55
56 QT_BEGIN_NAMESPACE
57
58 DEFINE_BOOL_CONFIG_OPTION(stateChangeDebug, STATECHANGE_DEBUG);
59
QDeclarativeAction()60 QDeclarativeAction::QDeclarativeAction()
61 : restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), fromBinding(0), event(0),
62 specifiedObject(0)
63 {
64 }
65
QDeclarativeAction(QObject * target,const QString & propertyName,const QVariant & value)66 QDeclarativeAction::QDeclarativeAction(QObject *target, const QString &propertyName,
67 const QVariant &value)
68 : restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false),
69 property(target, propertyName, qmlEngine(target)), toValue(value),
70 fromBinding(0), event(0),
71 specifiedObject(target), specifiedProperty(propertyName)
72 {
73 if (property.isValid())
74 fromValue = property.read();
75 }
76
QDeclarativeAction(QObject * target,const QString & propertyName,QDeclarativeContext * context,const QVariant & value)77 QDeclarativeAction::QDeclarativeAction(QObject *target, const QString &propertyName,
78 QDeclarativeContext *context, const QVariant &value)
79 : restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false),
80 property(target, propertyName, context), toValue(value),
81 fromBinding(0), event(0),
82 specifiedObject(target), specifiedProperty(propertyName)
83 {
84 if (property.isValid())
85 fromValue = property.read();
86 }
87
88
~QDeclarativeActionEvent()89 QDeclarativeActionEvent::~QDeclarativeActionEvent()
90 {
91 }
92
typeName() const93 QString QDeclarativeActionEvent::typeName() const
94 {
95 return QString();
96 }
97
execute(Reason)98 void QDeclarativeActionEvent::execute(Reason)
99 {
100 }
101
isReversable()102 bool QDeclarativeActionEvent::isReversable()
103 {
104 return false;
105 }
106
reverse(Reason)107 void QDeclarativeActionEvent::reverse(Reason)
108 {
109 }
110
changesBindings()111 bool QDeclarativeActionEvent::changesBindings()
112 {
113 return false;
114 }
115
clearBindings()116 void QDeclarativeActionEvent::clearBindings()
117 {
118 }
119
override(QDeclarativeActionEvent * other)120 bool QDeclarativeActionEvent::override(QDeclarativeActionEvent *other)
121 {
122 Q_UNUSED(other);
123 return false;
124 }
125
QDeclarativeStateOperation(QObjectPrivate & dd,QObject * parent)126 QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObject *parent)
127 : QObject(dd, parent)
128 {
129 }
130
131 /*!
132 \qmlclass State QDeclarativeState
133 \ingroup qml-state-elements
134 \since 4.7
135 \brief The State element defines configurations of objects and properties.
136
137 A \e state is a set of batched changes from the default configuration.
138
139 All items have a default state that defines the default configuration of objects
140 and property values. New states can be defined by adding State items to the \l {Item::states}{states} property to
141 allow items to switch between different configurations. These configurations
142 can, for example, be used to apply different sets of property values or execute
143 different scripts.
144
145 The following example displays a single \l Rectangle. In the default state, the rectangle
146 is colored black. In the "clicked" state, a PropertyChanges element changes the
147 rectangle's color to red. Clicking within the MouseArea toggles the rectangle's state
148 between the default state and the "clicked" state, thus toggling the color of the
149 rectangle between black and red.
150
151 \snippet doc/src/snippets/declarative/state.qml 0
152
153 Notice the default state is referred to using an empty string ("").
154
155 States are commonly used together with \l{QML Animation and Transitions}{Transitions} to provide
156 animations when state changes occur.
157
158 \note Setting the state of an object from within another state of the same object is
159 not allowed.
160
161 \sa {declarative/animation/states}{states example}, {qmlstates}{States},
162 {QML Animation and Transitions}{Transitions}, QtDeclarative
163 */
QDeclarativeState(QObject * parent)164 QDeclarativeState::QDeclarativeState(QObject *parent)
165 : QObject(*(new QDeclarativeStatePrivate), parent)
166 {
167 Q_D(QDeclarativeState);
168 d->transitionManager.setState(this);
169 }
170
~QDeclarativeState()171 QDeclarativeState::~QDeclarativeState()
172 {
173 Q_D(QDeclarativeState);
174 if (d->group)
175 d->group->removeState(this);
176
177 /*
178 destroying an active state does not return us to the
179 base state, so we need to clean up our revert list to
180 prevent leaks. In the future we may want to redconsider
181 this overall architecture.
182 */
183 for (int i = 0; i < d->revertList.count(); ++i) {
184 if (d->revertList.at(i).binding()) {
185 d->revertList.at(i).binding()->destroy();
186 }
187 }
188 }
189
190 /*!
191 \qmlproperty string State::name
192 This property holds the name of the state.
193
194 Each state should have a unique name within its item.
195 */
name() const196 QString QDeclarativeState::name() const
197 {
198 Q_D(const QDeclarativeState);
199 return d->name;
200 }
201
setName(const QString & n)202 void QDeclarativeState::setName(const QString &n)
203 {
204 Q_D(QDeclarativeState);
205 d->name = n;
206 d->named = true;
207 }
208
isNamed() const209 bool QDeclarativeState::isNamed() const
210 {
211 Q_D(const QDeclarativeState);
212 return d->named;
213 }
214
isWhenKnown() const215 bool QDeclarativeState::isWhenKnown() const
216 {
217 Q_D(const QDeclarativeState);
218 return d->when != 0;
219 }
220
221 /*!
222 \qmlproperty bool State::when
223 This property holds when the state should be applied.
224
225 This should be set to an expression that evaluates to \c true when you want the state to
226 be applied. For example, the following \l Rectangle changes in and out of the "hidden"
227 state when the \l MouseArea is pressed:
228
229 \snippet doc/src/snippets/declarative/state-when.qml 0
230
231 If multiple states in a group have \c when clauses that evaluate to \c true
232 at the same time, the first matching state will be applied. For example, in
233 the following snippet \c state1 will always be selected rather than
234 \c state2 when sharedCondition becomes \c true.
235 \qml
236 Item {
237 states: [
238 State { name: "state1"; when: sharedCondition },
239 State { name: "state2"; when: sharedCondition }
240 ]
241 // ...
242 }
243 \endqml
244 */
when() const245 QDeclarativeBinding *QDeclarativeState::when() const
246 {
247 Q_D(const QDeclarativeState);
248 return d->when;
249 }
250
setWhen(QDeclarativeBinding * when)251 void QDeclarativeState::setWhen(QDeclarativeBinding *when)
252 {
253 Q_D(QDeclarativeState);
254 d->when = when;
255 if (d->group)
256 d->group->updateAutoState();
257 }
258
259 /*!
260 \qmlproperty string State::extend
261 This property holds the state that this state extends.
262
263 When a state extends another state, it inherits all the changes of that state.
264
265 The state being extended is treated as the base state in regards to
266 the changes specified by the extending state.
267 */
extends() const268 QString QDeclarativeState::extends() const
269 {
270 Q_D(const QDeclarativeState);
271 return d->extends;
272 }
273
setExtends(const QString & extends)274 void QDeclarativeState::setExtends(const QString &extends)
275 {
276 Q_D(QDeclarativeState);
277 d->extends = extends;
278 }
279
280 /*!
281 \qmlproperty list<Change> State::changes
282 This property holds the changes to apply for this state
283 \default
284
285 By default these changes are applied against the default state. If the state
286 extends another state, then the changes are applied against the state being
287 extended.
288 */
changes()289 QDeclarativeListProperty<QDeclarativeStateOperation> QDeclarativeState::changes()
290 {
291 Q_D(QDeclarativeState);
292 return QDeclarativeListProperty<QDeclarativeStateOperation>(this, &d->operations, QDeclarativeStatePrivate::operations_append,
293 QDeclarativeStatePrivate::operations_count, QDeclarativeStatePrivate::operations_at,
294 QDeclarativeStatePrivate::operations_clear);
295 }
296
operationCount() const297 int QDeclarativeState::operationCount() const
298 {
299 Q_D(const QDeclarativeState);
300 return d->operations.count();
301 }
302
operationAt(int index) const303 QDeclarativeStateOperation *QDeclarativeState::operationAt(int index) const
304 {
305 Q_D(const QDeclarativeState);
306 return d->operations.at(index);
307 }
308
operator <<(QDeclarativeStateOperation * op)309 QDeclarativeState &QDeclarativeState::operator<<(QDeclarativeStateOperation *op)
310 {
311 Q_D(QDeclarativeState);
312 d->operations.append(QDeclarativeStatePrivate::OperationGuard(op, &d->operations));
313 return *this;
314 }
315
complete()316 void QDeclarativeStatePrivate::complete()
317 {
318 Q_Q(QDeclarativeState);
319
320 for (int ii = 0; ii < reverting.count(); ++ii) {
321 for (int jj = 0; jj < revertList.count(); ++jj) {
322 if (revertList.at(jj).property() == reverting.at(ii)) {
323 revertList.removeAt(jj);
324 break;
325 }
326 }
327 }
328 reverting.clear();
329
330 emit q->completed();
331 }
332
333 // Generate a list of actions for this state. This includes coelescing state
334 // actions that this state "extends"
335 QDeclarativeStateOperation::ActionList
generateActionList(QDeclarativeStateGroup * group) const336 QDeclarativeStatePrivate::generateActionList(QDeclarativeStateGroup *group) const
337 {
338 QDeclarativeStateOperation::ActionList applyList;
339 if (inState)
340 return applyList;
341
342 // Prevent "extends" recursion
343 inState = true;
344
345 if (!extends.isEmpty()) {
346 QList<QDeclarativeState *> states = group->states();
347 for (int ii = 0; ii < states.count(); ++ii)
348 if (states.at(ii)->name() == extends) {
349 qmlExecuteDeferred(states.at(ii));
350 applyList = static_cast<QDeclarativeStatePrivate*>(states.at(ii)->d_func())->generateActionList(group);
351 }
352 }
353
354 foreach(QDeclarativeStateOperation *op, operations)
355 applyList << op->actions();
356
357 inState = false;
358 return applyList;
359 }
360
stateGroup() const361 QDeclarativeStateGroup *QDeclarativeState::stateGroup() const
362 {
363 Q_D(const QDeclarativeState);
364 return d->group;
365 }
366
setStateGroup(QDeclarativeStateGroup * group)367 void QDeclarativeState::setStateGroup(QDeclarativeStateGroup *group)
368 {
369 Q_D(QDeclarativeState);
370 d->group = group;
371 }
372
cancel()373 void QDeclarativeState::cancel()
374 {
375 Q_D(QDeclarativeState);
376 d->transitionManager.cancel();
377 }
378
deleteFromBinding()379 void QDeclarativeAction::deleteFromBinding()
380 {
381 if (fromBinding) {
382 QDeclarativePropertyPrivate::setBinding(property, 0);
383 fromBinding->destroy();
384 fromBinding = 0;
385 }
386 }
387
containsPropertyInRevertList(QObject * target,const QString & name) const388 bool QDeclarativeState::containsPropertyInRevertList(QObject *target, const QString &name) const
389 {
390 Q_D(const QDeclarativeState);
391
392 if (isStateActive()) {
393 QListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList);
394
395 while (revertListIterator.hasNext()) {
396 const QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
397 if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
398 return true;
399 }
400 }
401
402 return false;
403 }
404
changeValueInRevertList(QObject * target,const QString & name,const QVariant & revertValue)405 bool QDeclarativeState::changeValueInRevertList(QObject *target, const QString &name, const QVariant &revertValue)
406 {
407 Q_D(QDeclarativeState);
408
409 if (isStateActive()) {
410 QMutableListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList);
411
412 while (revertListIterator.hasNext()) {
413 QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
414 if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name) {
415 simpleAction.setValue(revertValue);
416 return true;
417 }
418 }
419 }
420
421 return false;
422 }
423
changeBindingInRevertList(QObject * target,const QString & name,QDeclarativeAbstractBinding * binding)424 bool QDeclarativeState::changeBindingInRevertList(QObject *target, const QString &name, QDeclarativeAbstractBinding *binding)
425 {
426 Q_D(QDeclarativeState);
427
428 if (isStateActive()) {
429 QMutableListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList);
430
431 while (revertListIterator.hasNext()) {
432 QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
433 if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name) {
434 if (simpleAction.binding())
435 simpleAction.binding()->destroy();
436
437 simpleAction.setBinding(binding);
438 return true;
439 }
440 }
441 }
442
443 return false;
444 }
445
removeEntryFromRevertList(QObject * target,const QString & name)446 bool QDeclarativeState::removeEntryFromRevertList(QObject *target, const QString &name)
447 {
448 Q_D(QDeclarativeState);
449
450 if (isStateActive()) {
451 QMutableListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList);
452
453 while (revertListIterator.hasNext()) {
454 QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
455 if (simpleAction.property().object() == target && simpleAction.property().name() == name) {
456 QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(simpleAction.property());
457 if (oldBinding) {
458 QDeclarativePropertyPrivate::setBinding(simpleAction.property(), 0);
459 oldBinding->destroy();
460 }
461
462 simpleAction.property().write(simpleAction.value());
463 if (simpleAction.binding())
464 QDeclarativePropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding());
465
466 revertListIterator.remove();
467 return true;
468 }
469 }
470 }
471
472 return false;
473 }
474
addEntryToRevertList(const QDeclarativeAction & action)475 void QDeclarativeState::addEntryToRevertList(const QDeclarativeAction &action)
476 {
477 Q_D(QDeclarativeState);
478
479 QDeclarativeSimpleAction simpleAction(action);
480
481 d->revertList.append(simpleAction);
482 }
483
removeAllEntriesFromRevertList(QObject * target)484 void QDeclarativeState::removeAllEntriesFromRevertList(QObject *target)
485 {
486 Q_D(QDeclarativeState);
487
488 if (isStateActive()) {
489 QMutableListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList);
490
491 while (revertListIterator.hasNext()) {
492 QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
493 if (simpleAction.property().object() == target) {
494 QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(simpleAction.property());
495 if (oldBinding) {
496 QDeclarativePropertyPrivate::setBinding(simpleAction.property(), 0);
497 oldBinding->destroy();
498 }
499
500 simpleAction.property().write(simpleAction.value());
501 if (simpleAction.binding())
502 QDeclarativePropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding());
503
504 revertListIterator.remove();
505 }
506 }
507 }
508 }
509
addEntriesToRevertList(const QList<QDeclarativeAction> & actionList)510 void QDeclarativeState::addEntriesToRevertList(const QList<QDeclarativeAction> &actionList)
511 {
512 Q_D(QDeclarativeState);
513 if (isStateActive()) {
514 QList<QDeclarativeSimpleAction> simpleActionList;
515
516 QListIterator<QDeclarativeAction> actionListIterator(actionList);
517 while(actionListIterator.hasNext()) {
518 const QDeclarativeAction &action = actionListIterator.next();
519 QDeclarativeSimpleAction simpleAction(action);
520 action.property.write(action.toValue);
521 if (!action.toBinding.isNull()) {
522 QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(simpleAction.property());
523 if (oldBinding)
524 QDeclarativePropertyPrivate::setBinding(simpleAction.property(), 0);
525 QDeclarativePropertyPrivate::setBinding(simpleAction.property(), action.toBinding.data(), QDeclarativePropertyPrivate::DontRemoveBinding);
526 }
527
528 simpleActionList.append(simpleAction);
529 }
530
531 d->revertList.append(simpleActionList);
532 }
533 }
534
valueInRevertList(QObject * target,const QString & name) const535 QVariant QDeclarativeState::valueInRevertList(QObject *target, const QString &name) const
536 {
537 Q_D(const QDeclarativeState);
538
539 if (isStateActive()) {
540 QListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList);
541
542 while (revertListIterator.hasNext()) {
543 const QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
544 if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
545 return simpleAction.value();
546 }
547 }
548
549 return QVariant();
550 }
551
bindingInRevertList(QObject * target,const QString & name) const552 QDeclarativeAbstractBinding *QDeclarativeState::bindingInRevertList(QObject *target, const QString &name) const
553 {
554 Q_D(const QDeclarativeState);
555
556 if (isStateActive()) {
557 QListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList);
558
559 while (revertListIterator.hasNext()) {
560 const QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
561 if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
562 return simpleAction.binding();
563 }
564 }
565
566 return 0;
567 }
568
isStateActive() const569 bool QDeclarativeState::isStateActive() const
570 {
571 return stateGroup() && stateGroup()->state() == name();
572 }
573
apply(QDeclarativeStateGroup * group,QDeclarativeTransition * trans,QDeclarativeState * revert)574 void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransition *trans, QDeclarativeState *revert)
575 {
576 Q_D(QDeclarativeState);
577
578 qmlExecuteDeferred(this);
579
580 cancel();
581 if (revert)
582 revert->cancel();
583 d->revertList.clear();
584 d->reverting.clear();
585
586 if (revert) {
587 QDeclarativeStatePrivate *revertPrivate =
588 static_cast<QDeclarativeStatePrivate*>(revert->d_func());
589 d->revertList = revertPrivate->revertList;
590 revertPrivate->revertList.clear();
591 }
592
593 // List of actions caused by this state
594 QDeclarativeStateOperation::ActionList applyList = d->generateActionList(group);
595
596 // List of actions that need to be reverted to roll back (just) this state
597 QDeclarativeStatePrivate::SimpleActionList additionalReverts;
598 // First add the reverse of all the applyList actions
599 for (int ii = 0; ii < applyList.count(); ++ii) {
600 QDeclarativeAction &action = applyList[ii];
601
602 if (action.event) {
603 if (!action.event->isReversable())
604 continue;
605 bool found = false;
606 for (int jj = 0; jj < d->revertList.count(); ++jj) {
607 QDeclarativeActionEvent *event = d->revertList.at(jj).event();
608 if (event && event->typeName() == action.event->typeName()) {
609 if (action.event->override(event)) {
610 found = true;
611
612 if (action.event != d->revertList.at(jj).event() && action.event->needsCopy()) {
613 action.event->copyOriginals(d->revertList.at(jj).event());
614
615 QDeclarativeSimpleAction r(action);
616 additionalReverts << r;
617 d->revertList.removeAt(jj);
618 --jj;
619 } else if (action.event->isRewindable()) //###why needed?
620 action.event->saveCurrentValues();
621
622 break;
623 }
624 }
625 }
626 if (!found) {
627 action.event->saveOriginals();
628 // Only need to revert the applyList action if the previous
629 // state doesn't have a higher priority revert already
630 QDeclarativeSimpleAction r(action);
631 additionalReverts << r;
632 }
633 } else {
634 bool found = false;
635 action.fromBinding = QDeclarativePropertyPrivate::binding(action.property);
636
637 for (int jj = 0; jj < d->revertList.count(); ++jj) {
638 if (d->revertList.at(jj).property() == action.property) {
639 found = true;
640 if (d->revertList.at(jj).binding() != action.fromBinding) {
641 action.deleteFromBinding();
642 }
643 break;
644 }
645 }
646
647 if (!found) {
648 if (!action.restore) {
649 action.deleteFromBinding();;
650 } else {
651 // Only need to revert the applyList action if the previous
652 // state doesn't have a higher priority revert already
653 QDeclarativeSimpleAction r(action);
654 additionalReverts << r;
655 }
656 }
657 }
658 }
659
660 // Any reverts from a previous state that aren't carried forth
661 // into this state need to be translated into apply actions
662 for (int ii = 0; ii < d->revertList.count(); ++ii) {
663 bool found = false;
664 if (d->revertList.at(ii).event()) {
665 QDeclarativeActionEvent *event = d->revertList.at(ii).event();
666 if (!event->isReversable())
667 continue;
668 for (int jj = 0; !found && jj < applyList.count(); ++jj) {
669 const QDeclarativeAction &action = applyList.at(jj);
670 if (action.event && action.event->typeName() == event->typeName()) {
671 if (action.event->override(event))
672 found = true;
673 }
674 }
675 } else {
676 for (int jj = 0; !found && jj < applyList.count(); ++jj) {
677 const QDeclarativeAction &action = applyList.at(jj);
678 if (action.property == d->revertList.at(ii).property())
679 found = true;
680 }
681 }
682 if (!found) {
683 QVariant cur = d->revertList.at(ii).property().read();
684 QDeclarativeAbstractBinding *delBinding =
685 QDeclarativePropertyPrivate::setBinding(d->revertList.at(ii).property(), 0);
686 if (delBinding)
687 delBinding->destroy();
688
689 QDeclarativeAction a;
690 a.property = d->revertList.at(ii).property();
691 a.fromValue = cur;
692 a.toValue = d->revertList.at(ii).value();
693 a.toBinding = QDeclarativeAbstractBinding::getPointer(d->revertList.at(ii).binding());
694 a.specifiedObject = d->revertList.at(ii).specifiedObject();
695 a.specifiedProperty = d->revertList.at(ii).specifiedProperty();
696 a.event = d->revertList.at(ii).event();
697 a.reverseEvent = d->revertList.at(ii).reverseEvent();
698 if (a.event && a.event->isRewindable())
699 a.event->saveCurrentValues();
700 applyList << a;
701 // Store these special reverts in the reverting list
702 d->reverting << d->revertList.at(ii).property();
703 }
704 }
705 // All the local reverts now become part of the ongoing revertList
706 d->revertList << additionalReverts;
707
708 #ifndef QT_NO_DEBUG_STREAM
709 // Output for debugging
710 if (stateChangeDebug()) {
711 foreach(const QDeclarativeAction &action, applyList) {
712 if (action.event)
713 qWarning() << " QDeclarativeAction event:" << action.event->typeName();
714 else
715 qWarning() << " QDeclarativeAction:" << action.property.object()
716 << action.property.name() << "From:" << action.fromValue
717 << "To:" << action.toValue;
718 }
719 }
720 #endif
721
722 d->transitionManager.transition(applyList, trans);
723 }
724
actions()725 QDeclarativeStateOperation::ActionList QDeclarativeStateOperation::actions()
726 {
727 return ActionList();
728 }
729
state() const730 QDeclarativeState *QDeclarativeStateOperation::state() const
731 {
732 Q_D(const QDeclarativeStateOperation);
733 return d->m_state;
734 }
735
setState(QDeclarativeState * state)736 void QDeclarativeStateOperation::setState(QDeclarativeState *state)
737 {
738 Q_D(QDeclarativeStateOperation);
739 d->m_state = state;
740 }
741
742 QT_END_NAMESPACE
743