/**************************************************************************** | |
** | |
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | |
** All rights reserved. | |
** Contact: Nokia Corporation (qt-info@nokia.com) | |
** | |
** This file is part of the QtCore module of the Qt Toolkit. | |
** | |
** $QT_BEGIN_LICENSE:LGPL$ | |
** GNU Lesser General Public License Usage | |
** This file may be used under the terms of the GNU Lesser General Public | |
** License version 2.1 as published by the Free Software Foundation and | |
** appearing in the file LICENSE.LGPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU Lesser | |
** General Public License version 2.1 requirements will be met: | |
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
** | |
** In addition, as a special exception, Nokia gives you certain additional | |
** rights. These rights are described in the Nokia Qt LGPL Exception | |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
** | |
** GNU General Public License Usage | |
** Alternatively, this file may be used under the terms of the GNU General | |
** Public License version 3.0 as published by the Free Software Foundation | |
** and appearing in the file LICENSE.GPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU General | |
** Public License version 3.0 requirements will be met: | |
** http://www.gnu.org/copyleft/gpl.html. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $QT_END_LICENSE$ | |
** | |
****************************************************************************/ | |
#include "qsignaltransition.h" | |
#ifndef QT_NO_STATEMACHINE | |
#include "qsignaltransition_p.h" | |
#include "qstate.h" | |
#include "qstate_p.h" | |
#include "qstatemachine.h" | |
#include "qstatemachine_p.h" | |
#include <qdebug.h> | |
QT_BEGIN_NAMESPACE | |
/*! | |
\class QSignalTransition | |
\brief The QSignalTransition class provides a transition based on a Qt signal. | |
\since 4.6 | |
\ingroup statemachine | |
Typically you would use the overload of QState::addTransition() that takes a | |
sender and signal as arguments, rather than creating QSignalTransition | |
objects directly. QSignalTransition is part of \l{The State Machine | |
Framework}. | |
You can subclass QSignalTransition and reimplement eventTest() to make a | |
signal transition conditional; the event object passed to eventTest() will | |
be a QStateMachine::SignalEvent object. Example: | |
\code | |
class CheckedTransition : public QSignalTransition | |
{ | |
public: | |
CheckedTransition(QCheckBox *check) | |
: QSignalTransition(check, SIGNAL(stateChanged(int))) {} | |
protected: | |
bool eventTest(QEvent *e) { | |
if (!QSignalTransition::eventTest(e)) | |
return false; | |
QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e); | |
return (se->arguments().at(0).toInt() == Qt::Checked); | |
} | |
}; | |
... | |
QCheckBox *check = new QCheckBox(); | |
check->setTristate(true); | |
QState *s1 = new QState(); | |
QState *s2 = new QState(); | |
CheckedTransition *t1 = new CheckedTransition(check); | |
t1->setTargetState(s2); | |
s1->addTransition(t1); | |
\endcode | |
*/ | |
/*! | |
\property QSignalTransition::senderObject | |
\brief the sender object that this signal transition is associated with | |
*/ | |
/*! | |
\property QSignalTransition::signal | |
\brief the signal that this signal transition is associated with | |
*/ | |
QSignalTransitionPrivate::QSignalTransitionPrivate() | |
{ | |
sender = 0; | |
signalIndex = -1; | |
} | |
QSignalTransitionPrivate *QSignalTransitionPrivate::get(QSignalTransition *q) | |
{ | |
return q->d_func(); | |
} | |
void QSignalTransitionPrivate::unregister() | |
{ | |
Q_Q(QSignalTransition); | |
if ((signalIndex == -1) || !machine()) | |
return; | |
QStateMachinePrivate::get(machine())->unregisterSignalTransition(q); | |
} | |
void QSignalTransitionPrivate::maybeRegister() | |
{ | |
Q_Q(QSignalTransition); | |
if (!machine() || !machine()->configuration().contains(sourceState())) | |
return; | |
QStateMachinePrivate::get(machine())->registerSignalTransition(q); | |
} | |
/*! | |
Constructs a new signal transition with the given \a sourceState. | |
*/ | |
QSignalTransition::QSignalTransition(QState *sourceState) | |
: QAbstractTransition(*new QSignalTransitionPrivate, sourceState) | |
{ | |
} | |
/*! | |
Constructs a new signal transition associated with the given \a signal of | |
the given \a sender, and with the given \a sourceState. | |
*/ | |
QSignalTransition::QSignalTransition(QObject *sender, const char *signal, | |
QState *sourceState) | |
: QAbstractTransition(*new QSignalTransitionPrivate, sourceState) | |
{ | |
Q_D(QSignalTransition); | |
d->sender = sender; | |
d->signal = signal; | |
} | |
/*! | |
Destroys this signal transition. | |
*/ | |
QSignalTransition::~QSignalTransition() | |
{ | |
} | |
/*! | |
Returns the sender object associated with this signal transition. | |
*/ | |
QObject *QSignalTransition::senderObject() const | |
{ | |
Q_D(const QSignalTransition); | |
return d->sender; | |
} | |
/*! | |
Sets the \a sender object associated with this signal transition. | |
*/ | |
void QSignalTransition::setSenderObject(QObject *sender) | |
{ | |
Q_D(QSignalTransition); | |
if (sender == d->sender) | |
return; | |
d->unregister(); | |
d->sender = sender; | |
d->maybeRegister(); | |
} | |
/*! | |
Returns the signal associated with this signal transition. | |
*/ | |
QByteArray QSignalTransition::signal() const | |
{ | |
Q_D(const QSignalTransition); | |
return d->signal; | |
} | |
/*! | |
Sets the \a signal associated with this signal transition. | |
*/ | |
void QSignalTransition::setSignal(const QByteArray &signal) | |
{ | |
Q_D(QSignalTransition); | |
if (signal == d->signal) | |
return; | |
d->unregister(); | |
d->signal = signal; | |
d->maybeRegister(); | |
} | |
/*! | |
\reimp | |
The default implementation returns true if the \a event is a | |
QStateMachine::SignalEvent object and the event's sender and signal index | |
match this transition, and returns false otherwise. | |
*/ | |
bool QSignalTransition::eventTest(QEvent *event) | |
{ | |
Q_D(const QSignalTransition); | |
if (event->type() == QEvent::StateMachineSignal) { | |
if (d->signalIndex == -1) | |
return false; | |
QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event); | |
return (se->sender() == d->sender) | |
&& (se->signalIndex() == d->signalIndex); | |
} | |
return false; | |
} | |
/*! | |
\reimp | |
*/ | |
void QSignalTransition::onTransition(QEvent *event) | |
{ | |
Q_UNUSED(event); | |
} | |
/*! | |
\reimp | |
*/ | |
bool QSignalTransition::event(QEvent *e) | |
{ | |
return QAbstractTransition::event(e); | |
} | |
void QSignalTransitionPrivate::callOnTransition(QEvent *e) | |
{ | |
Q_Q(QSignalTransition); | |
if (e->type() == QEvent::StateMachineSignal) { | |
QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent *>(e); | |
int savedSignalIndex = se->m_signalIndex; | |
se->m_signalIndex = originalSignalIndex; | |
q->onTransition(e); | |
se->m_signalIndex = savedSignalIndex; | |
} else { | |
q->onTransition(e); | |
} | |
} | |
QT_END_NAMESPACE | |
#endif //QT_NO_STATEMACHINE |