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