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