src/corelib/statemachine/qsignaltransition.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qsignaltransition.h"
       
    43 
       
    44 #ifndef QT_NO_STATEMACHINE
       
    45 
       
    46 #include "qsignaltransition_p.h"
       
    47 #include "qstate.h"
       
    48 #include "qstate_p.h"
       
    49 #include "qstatemachine.h"
       
    50 #include "qstatemachine_p.h"
       
    51 #include <qdebug.h>
       
    52 
       
    53 QT_BEGIN_NAMESPACE
       
    54 
       
    55 /*!
       
    56   \class QSignalTransition
       
    57 
       
    58   \brief The QSignalTransition class provides a transition based on a Qt signal.
       
    59 
       
    60   \since 4.6
       
    61   \ingroup statemachine
       
    62 
       
    63   Typically you would use the overload of QState::addTransition() that takes a
       
    64   sender and signal as arguments, rather than creating QSignalTransition
       
    65   objects directly. QSignalTransition is part of \l{The State Machine
       
    66   Framework}.
       
    67 
       
    68   You can subclass QSignalTransition and reimplement eventTest() to make a
       
    69   signal transition conditional; the event object passed to eventTest() will
       
    70   be a QStateMachine::SignalEvent object. Example:
       
    71 
       
    72   \code
       
    73   class CheckedTransition : public QSignalTransition
       
    74   {
       
    75   public:
       
    76       CheckedTransition(QCheckBox *check)
       
    77           : QSignalTransition(check, SIGNAL(stateChanged(int))) {}
       
    78   protected:
       
    79       bool eventTest(QEvent *e) const {
       
    80           if (!QSignalTransition::eventTest(e))
       
    81               return false;
       
    82           QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e);
       
    83           return (se->arguments().at(0).toInt() == Qt::Checked);
       
    84       }
       
    85   };
       
    86 
       
    87   ...
       
    88 
       
    89   QCheckBox *check = new QCheckBox();
       
    90   check->setTristate(true);
       
    91 
       
    92   QState *s1 = new QState();
       
    93   QState *s2 = new QState();
       
    94   CheckedTransition *t1 = new CheckedTransition(check);
       
    95   t1->setTargetState(s2);
       
    96   s1->addTransition(t1);
       
    97   \endcode
       
    98 */
       
    99 
       
   100 /*!
       
   101     \property QSignalTransition::senderObject
       
   102 
       
   103     \brief the sender object that this signal transition is associated with
       
   104 */
       
   105 
       
   106 /*!
       
   107     \property QSignalTransition::signal
       
   108 
       
   109     \brief the signal that this signal transition is associated with
       
   110 */
       
   111 
       
   112 QSignalTransitionPrivate::QSignalTransitionPrivate()
       
   113 {
       
   114     sender = 0;
       
   115     signalIndex = -1;
       
   116 }
       
   117 
       
   118 QSignalTransitionPrivate *QSignalTransitionPrivate::get(QSignalTransition *q)
       
   119 {
       
   120     return q->d_func();
       
   121 }
       
   122 
       
   123 void QSignalTransitionPrivate::unregister()
       
   124 {
       
   125     Q_Q(QSignalTransition);
       
   126     if ((signalIndex == -1) || !machine())
       
   127         return;
       
   128     QStateMachinePrivate::get(machine())->unregisterSignalTransition(q);
       
   129 }
       
   130 
       
   131 void QSignalTransitionPrivate::maybeRegister()
       
   132 {
       
   133     Q_Q(QSignalTransition);
       
   134     if (!machine() || !machine()->configuration().contains(sourceState()))
       
   135         return;
       
   136     QStateMachinePrivate::get(machine())->registerSignalTransition(q);
       
   137 }
       
   138 
       
   139 /*!
       
   140   Constructs a new signal transition with the given \a sourceState.
       
   141 */
       
   142 QSignalTransition::QSignalTransition(QState *sourceState)
       
   143     : QAbstractTransition(*new QSignalTransitionPrivate, sourceState)
       
   144 {
       
   145 }
       
   146 
       
   147 /*!
       
   148   Constructs a new signal transition associated with the given \a signal of
       
   149   the given \a sender, and with the given \a sourceState.
       
   150 */
       
   151 QSignalTransition::QSignalTransition(QObject *sender, const char *signal,
       
   152                                      QState *sourceState)
       
   153     : QAbstractTransition(*new QSignalTransitionPrivate, sourceState)
       
   154 {
       
   155     Q_D(QSignalTransition);
       
   156     d->sender = sender;
       
   157     d->signal = signal;
       
   158 }
       
   159 
       
   160 /*!
       
   161   Destroys this signal transition.
       
   162 */
       
   163 QSignalTransition::~QSignalTransition()
       
   164 {
       
   165 }
       
   166 
       
   167 /*!
       
   168   Returns the sender object associated with this signal transition.
       
   169 */
       
   170 QObject *QSignalTransition::senderObject() const
       
   171 {
       
   172     Q_D(const QSignalTransition);
       
   173     return d->sender;
       
   174 }
       
   175 
       
   176 /*!
       
   177   Sets the \a sender object associated with this signal transition.
       
   178 */
       
   179 void QSignalTransition::setSenderObject(QObject *sender)
       
   180 {
       
   181     Q_D(QSignalTransition);
       
   182     if (sender == d->sender)
       
   183         return;
       
   184     d->unregister();
       
   185     d->sender = sender;
       
   186     d->maybeRegister();
       
   187 }
       
   188 
       
   189 /*!
       
   190   Returns the signal associated with this signal transition.
       
   191 */
       
   192 QByteArray QSignalTransition::signal() const
       
   193 {
       
   194     Q_D(const QSignalTransition);
       
   195     return d->signal;
       
   196 }
       
   197 
       
   198 /*!
       
   199   Sets the \a signal associated with this signal transition.
       
   200 */
       
   201 void QSignalTransition::setSignal(const QByteArray &signal)
       
   202 {
       
   203     Q_D(QSignalTransition);
       
   204     if (signal == d->signal)
       
   205         return;
       
   206     d->unregister();
       
   207     d->signal = signal;
       
   208     d->maybeRegister();
       
   209 }
       
   210 
       
   211 /*!
       
   212   \reimp
       
   213 
       
   214   The default implementation returns true if the \a event is a
       
   215   QStateMachine::SignalEvent object and the event's sender and signal index
       
   216   match this transition, and returns false otherwise.
       
   217 */
       
   218 bool QSignalTransition::eventTest(QEvent *event)
       
   219 {
       
   220     Q_D(const QSignalTransition);
       
   221     if (event->type() == QEvent::StateMachineSignal) {
       
   222         if (d->signalIndex == -1)
       
   223             return false;
       
   224         QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event);
       
   225         return (se->sender() == d->sender)
       
   226             && (se->signalIndex() == d->signalIndex);
       
   227     }
       
   228     return false;
       
   229 }
       
   230 
       
   231 /*!
       
   232   \reimp
       
   233 */
       
   234 void QSignalTransition::onTransition(QEvent *event)
       
   235 {
       
   236     Q_UNUSED(event);
       
   237 }
       
   238 
       
   239 /*!
       
   240   \reimp
       
   241 */
       
   242 bool QSignalTransition::event(QEvent *e)
       
   243 {
       
   244     return QAbstractTransition::event(e);
       
   245 }
       
   246 
       
   247 void QSignalTransitionPrivate::callOnTransition(QEvent *e)
       
   248 {
       
   249     Q_Q(QSignalTransition);
       
   250 
       
   251     if (e->type() == QEvent::StateMachineSignal) {
       
   252         QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent *>(e);
       
   253         int savedSignalIndex = se->m_signalIndex;
       
   254         se->m_signalIndex = originalSignalIndex;
       
   255         q->onTransition(e);
       
   256         se->m_signalIndex = savedSignalIndex;
       
   257     } else {
       
   258         q->onTransition(e);
       
   259     }
       
   260 }
       
   261 
       
   262 QT_END_NAMESPACE
       
   263 
       
   264 #endif //QT_NO_STATEMACHINE