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 QtCore 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 "qeventtransition.h"
41 #include "qeventtransition_p.h"
42 #include "qstate.h"
43 #include "qstate_p.h"
44 #include "qstatemachine.h"
45 #include "qstatemachine_p.h"
46 #include <qdebug.h>
47
48 QT_BEGIN_NAMESPACE
49
50 /*!
51 \class QEventTransition
52 \inmodule QtCore
53
54 \brief The QEventTransition class provides a QObject-specific transition for Qt events.
55
56 \since 4.6
57 \ingroup statemachine
58
59 A QEventTransition object binds an event to a particular QObject.
60 QEventTransition is part of \l{The State Machine Framework}.
61
62 Example:
63
64 \code
65 QPushButton *button = ...;
66 QState *s1 = ...;
67 QState *s2 = ...;
68 // If in s1 and the button receives an Enter event, transition to s2
69 QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter);
70 enterTransition->setTargetState(s2);
71 s1->addTransition(enterTransition);
72 // If in s2 and the button receives an Exit event, transition back to s1
73 QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave);
74 leaveTransition->setTargetState(s1);
75 s2->addTransition(leaveTransition);
76 \endcode
77
78 \section1 Subclassing
79
80 When reimplementing the eventTest() function, you should first call the base
81 implementation to verify that the event is a QStateMachine::WrappedEvent for
82 the proper object and event type. You may then cast the event to a
83 QStateMachine::WrappedEvent and get the original event by calling
84 QStateMachine::WrappedEvent::event(), and perform additional checks on that
85 object.
86
87 \sa QState::addTransition()
88 */
89
90 /*!
91 \property QEventTransition::eventSource
92
93 \brief the event source that this event transition is associated with
94 */
95
96 /*!
97 \property QEventTransition::eventType
98
99 \brief the type of event that this event transition is associated with
100 */
QEventTransitionPrivate()101 QEventTransitionPrivate::QEventTransitionPrivate()
102 {
103 object = nullptr;
104 eventType = QEvent::None;
105 registered = false;
106 }
107
~QEventTransitionPrivate()108 QEventTransitionPrivate::~QEventTransitionPrivate()
109 {
110 }
111
unregister()112 void QEventTransitionPrivate::unregister()
113 {
114 Q_Q(QEventTransition);
115 if (!registered || !machine())
116 return;
117 QStateMachinePrivate::get(machine())->unregisterEventTransition(q);
118 }
119
maybeRegister()120 void QEventTransitionPrivate::maybeRegister()
121 {
122 Q_Q(QEventTransition);
123 if (QStateMachine *mach = machine())
124 QStateMachinePrivate::get(mach)->maybeRegisterEventTransition(q);
125 }
126
127 /*!
128 Constructs a new QEventTransition object with the given \a sourceState.
129 */
QEventTransition(QState * sourceState)130 QEventTransition::QEventTransition(QState *sourceState)
131 : QAbstractTransition(*new QEventTransitionPrivate, sourceState)
132 {
133 }
134
135 /*!
136 Constructs a new QEventTransition object associated with events of the given
137 \a type for the given \a object, and with the given \a sourceState.
138 */
QEventTransition(QObject * object,QEvent::Type type,QState * sourceState)139 QEventTransition::QEventTransition(QObject *object, QEvent::Type type,
140 QState *sourceState)
141 : QAbstractTransition(*new QEventTransitionPrivate, sourceState)
142 {
143 Q_D(QEventTransition);
144 d->registered = false;
145 d->object = object;
146 d->eventType = type;
147 d->maybeRegister();
148 }
149
150 /*!
151 \internal
152 */
QEventTransition(QEventTransitionPrivate & dd,QState * parent)153 QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QState *parent)
154 : QAbstractTransition(dd, parent)
155 {
156 }
157
158 /*!
159 \internal
160 */
QEventTransition(QEventTransitionPrivate & dd,QObject * object,QEvent::Type type,QState * parent)161 QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object,
162 QEvent::Type type, QState *parent)
163 : QAbstractTransition(dd, parent)
164 {
165 Q_D(QEventTransition);
166 d->registered = false;
167 d->object = object;
168 d->eventType = type;
169 d->maybeRegister();
170 }
171
172 /*!
173 Destroys this QObject event transition.
174 */
~QEventTransition()175 QEventTransition::~QEventTransition()
176 {
177 }
178
179 /*!
180 Returns the event type that this event transition is associated with.
181 */
eventType() const182 QEvent::Type QEventTransition::eventType() const
183 {
184 Q_D(const QEventTransition);
185 return d->eventType;
186 }
187
188 /*!
189 Sets the event \a type that this event transition is associated with.
190 */
setEventType(QEvent::Type type)191 void QEventTransition::setEventType(QEvent::Type type)
192 {
193 Q_D(QEventTransition);
194 if (d->eventType == type)
195 return;
196 d->unregister();
197 d->eventType = type;
198 d->maybeRegister();
199 }
200
201 /*!
202 Returns the event source associated with this event transition.
203 */
eventSource() const204 QObject *QEventTransition::eventSource() const
205 {
206 Q_D(const QEventTransition);
207 return d->object;
208 }
209
210 /*!
211 Sets the event source associated with this event transition to be the given
212 \a object.
213 */
setEventSource(QObject * object)214 void QEventTransition::setEventSource(QObject *object)
215 {
216 Q_D(QEventTransition);
217 if (d->object == object)
218 return;
219 d->unregister();
220 d->object = object;
221 d->maybeRegister();
222 }
223
224 /*!
225 \reimp
226 */
eventTest(QEvent * event)227 bool QEventTransition::eventTest(QEvent *event)
228 {
229 Q_D(const QEventTransition);
230 if (event->type() == QEvent::StateMachineWrapped) {
231 QStateMachine::WrappedEvent *we = static_cast<QStateMachine::WrappedEvent*>(event);
232 return (we->object() == d->object)
233 && (we->event()->type() == d->eventType);
234 }
235 return false;
236 }
237
238 /*!
239 \reimp
240 */
onTransition(QEvent * event)241 void QEventTransition::onTransition(QEvent *event)
242 {
243 Q_UNUSED(event);
244 }
245
246 /*!
247 \reimp
248 */
event(QEvent * e)249 bool QEventTransition::event(QEvent *e)
250 {
251 return QAbstractTransition::event(e);
252 }
253
254 QT_END_NAMESPACE
255
256 #include "moc_qeventtransition.cpp"
257