Qt 4.8
qstate.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qstate.h"
43 
44 #ifndef QT_NO_STATEMACHINE
45 
46 #include "qstate_p.h"
47 #include "qhistorystate.h"
48 #include "qhistorystate_p.h"
49 #include "qabstracttransition.h"
50 #include "qabstracttransition_p.h"
51 #include "qsignaltransition.h"
52 #include "qstatemachine.h"
53 #include "qstatemachine_p.h"
54 
56 
143  : QAbstractStatePrivate(StandardState),
144  errorState(0), initialState(0), childMode(QState::ExclusiveStates),
145  childStatesListNeedsRefresh(true), transitionsListNeedsRefresh(true)
146 {
147 }
148 
150 {
151 }
152 
154 {
155  Q_Q(QState);
156  emit q->finished();
157 }
158 
160 {
161  Q_Q(QState);
162  emit q->propertiesAssigned();
163 }
164 
169  : QAbstractState(*new QStatePrivate, parent)
170 {
171 }
172 
178  : QAbstractState(*new QStatePrivate, parent)
179 {
180  Q_D(QState);
181  d->childMode = childMode;
182 }
183 
188  : QAbstractState(dd, parent)
189 {
190 }
191 
196 {
197 }
198 
200 {
201  if (childStatesListNeedsRefresh) {
202  childStatesList.clear();
204  for (it = children.constBegin(); it != children.constEnd(); ++it) {
206  if (!s || qobject_cast<QHistoryState*>(s))
207  continue;
208  childStatesList.append(s);
209  }
210  childStatesListNeedsRefresh = false;
211  }
212  return childStatesList;
213 }
214 
216 {
217  QList<QHistoryState*> result;
219  for (it = children.constBegin(); it != children.constEnd(); ++it) {
221  if (h)
222  result.append(h);
223  }
224  return result;
225 }
226 
228 {
229  if (transitionsListNeedsRefresh) {
230  transitionsList.clear();
232  for (it = children.constBegin(); it != children.constEnd(); ++it) {
234  if (t)
235  transitionsList.append(t);
236  }
237  transitionsListNeedsRefresh = false;
238  }
239  return transitionsList;
240 }
241 
242 #ifndef QT_NO_PROPERTIES
243 
250 void QState::assignProperty(QObject *object, const char *name,
251  const QVariant &value)
252 {
253  Q_D(QState);
254  if (!object) {
255  qWarning("QState::assignProperty: cannot assign property '%s' of null object", name);
256  return;
257  }
258  for (int i = 0; i < d->propertyAssignments.size(); ++i) {
259  QPropertyAssignment &assn = d->propertyAssignments[i];
260  if ((assn.object == object) && (assn.propertyName == name)) {
261  assn.value = value;
262  return;
263  }
264  }
265  d->propertyAssignments.append(QPropertyAssignment(object, name, value));
266 }
267 
268 #endif // QT_NO_PROPERTIES
269 
276 {
277  Q_D(const QState);
278  return d->errorState;
279 }
280 
289 {
290  Q_D(QState);
291  if (state != 0 && qobject_cast<QStateMachine*>(state)) {
292  qWarning("QStateMachine::setErrorState: root state cannot be error state");
293  return;
294  }
295  if (state != 0 && (!state->machine() || ((state->machine() != machine()) && !qobject_cast<QStateMachine*>(this)))) {
296  qWarning("QState::setErrorState: error state cannot belong "
297  "to a different state machine");
298  return;
299  }
300 
301  d->errorState = state;
302 }
303 
309 {
310  Q_D(QState);
311  if (!transition) {
312  qWarning("QState::addTransition: cannot add null transition");
313  return ;
314  }
315 
316  transition->setParent(this);
318  for (int i = 0; i < targets.size(); ++i) {
319  QAbstractState *t = targets.at(i).data();
320  if (!t) {
321  qWarning("QState::addTransition: cannot add transition to null state");
322  return ;
323  }
324  if ((QAbstractStatePrivate::get(t)->machine() != d->machine())
325  && QAbstractStatePrivate::get(t)->machine() && d->machine()) {
326  qWarning("QState::addTransition: cannot add transition "
327  "to a state in a different state machine");
328  return ;
329  }
330  }
331  if (machine() != 0 && machine()->configuration().contains(this))
333 }
334 
341  QAbstractState *target)
342 {
343  if (!sender) {
344  qWarning("QState::addTransition: sender cannot be null");
345  return 0;
346  }
347  if (!signal) {
348  qWarning("QState::addTransition: signal cannot be null");
349  return 0;
350  }
351  if (!target) {
352  qWarning("QState::addTransition: cannot add transition to null state");
353  return 0;
354  }
355  int offset = (*signal == '0'+QSIGNAL_CODE) ? 1 : 0;
356  const QMetaObject *meta = sender->metaObject();
357  if (meta->indexOfSignal(signal+offset) == -1) {
358  if (meta->indexOfSignal(QMetaObject::normalizedSignature(signal+offset)) == -1) {
359  qWarning("QState::addTransition: no such signal %s::%s",
360  meta->className(), signal+offset);
361  return 0;
362  }
363  }
364  QSignalTransition *trans = new QSignalTransition(sender, signal);
365  trans->setTargetState(target);
366  addTransition(trans);
367  return trans;
368 }
369 
370 namespace {
371 
372 // ### Make public?
373 class UnconditionalTransition : public QAbstractTransition
374 {
375 public:
376  UnconditionalTransition(QAbstractState *target)
378  { setTargetState(target); }
379 protected:
380  void onTransition(QEvent *) {}
381  bool eventTest(QEvent *) { return true; }
382 };
383 
384 } // namespace
385 
391 {
392  if (!target) {
393  qWarning("QState::addTransition: cannot add transition to null state");
394  return 0;
395  }
396  UnconditionalTransition *trans = new UnconditionalTransition(target);
397  addTransition(trans);
398  return trans;
399 }
400 
408 {
409  Q_D(QState);
410  if (!transition) {
411  qWarning("QState::removeTransition: cannot remove null transition");
412  return;
413  }
414  if (transition->sourceState() != this) {
415  qWarning("QState::removeTransition: transition %p's source state (%p)"
416  " is different from this state (%p)",
417  transition, transition->sourceState(), this);
418  return;
419  }
421  if (mach)
422  mach->unregisterTransition(transition);
423  transition->setParent(0);
424 }
425 
438 {
439  Q_D(const QState);
440  return d->transitions();
441 }
442 
447 {
448  Q_UNUSED(event);
449 }
450 
455 {
456  Q_UNUSED(event);
457 }
458 
463 {
464  Q_D(const QState);
465  return d->initialState;
466 }
467 
473 {
474  Q_D(QState);
475  if (d->childMode == QState::ParallelStates) {
476  qWarning("QState::setInitialState: ignoring attempt to set initial state "
477  "of parallel state group %p", this);
478  return;
479  }
480  if (state && (state->parentState() != this)) {
481  qWarning("QState::setInitialState: state %p is not a child of this state (%p)",
482  state, this);
483  return;
484  }
485  d->initialState = state;
486 }
487 
492 {
493  Q_D(const QState);
494  return d->childMode;
495 }
496 
501 {
502  Q_D(QState);
503  d->childMode = mode;
504 }
505 
510 {
511  Q_D(QState);
512  if ((e->type() == QEvent::ChildAdded) || (e->type() == QEvent::ChildRemoved)) {
513  d->childStatesListNeedsRefresh = true;
514  d->transitionsListNeedsRefresh = true;
515  }
516  return QAbstractState::event(e);
517 }
518 
548 
549 #endif //QT_NO_STATEMACHINE
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
double d
Definition: qnumeric_p.h:62
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
void onEntry(QEvent *event)
Reimplemented Function
Definition: qstate.cpp:446
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QState * parentState() const
Returns this state&#39;s parent state, or 0 if the state has no parent state.
static QByteArray normalizedSignature(const char *method)
Normalizes the signature of the given method.
QStateMachine * machine() const
Returns the state machine that this state is part of, or 0 if the state is not part of a state machin...
The QAbstractTransition class is the base class of transitions between QAbstractState objects...
void setInitialState(QAbstractState *state)
Sets this state&#39;s initial state to be the given state.
Definition: qstate.cpp:472
#define it(className, varName)
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qlist.h:269
The QList::const_iterator class provides an STL-style const iterator for QList and QQueue...
Definition: qlist.h:228
QVariant value
Definition: qstate_p.h:74
QList< QAbstractTransition * > transitions() const
Returns this state&#39;s outgoing transitions (i.
Definition: qstate.cpp:437
T * qobject_cast(QObject *object)
Definition: qobject.h:375
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
QAbstractState * errorState() const
QObject * object
Definition: qstate_p.h:72
The QState class provides a general-purpose state for QStateMachine.
Definition: qstate.h:61
void registerTransitions(QAbstractState *state)
void setParent(QObject *)
Makes the object a child of parent.
Definition: qobject.cpp:1950
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition: qobject.cpp:2327
#define Q_Q(Class)
Definition: qglobal.h:2483
bool event(QEvent *e)
Reimplemented Function
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static QStateMachinePrivate * get(QStateMachine *q)
The QAbstractState class is the base class of states of a QStateMachine.
The QSignalTransition class provides a transition based on a Qt signal.
ChildMode childMode() const
static QAbstractTransitionPrivate * get(QAbstractTransition *q)
const char * name
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
#define emit
Definition: qobjectdefs.h:76
void setChildMode(ChildMode mode)
Sets the child mode of this state.
Definition: qstate.cpp:500
Q_CORE_EXPORT void qWarning(const char *,...)
QList< QAbstractTransition * > transitions() const
Definition: qstate.cpp:227
int indexOfSignal(const char *signal) const
Finds signal and returns its index; otherwise returns -1.
void onExit(QEvent *event)
Reimplemented Function
Definition: qstate.cpp:454
void clear()
Removes all items from the list.
Definition: qlist.h:764
void setTargetState(QAbstractState *target)
Sets the target state of this transition.
ChildMode
This enum specifies how a state&#39;s child states are treated.
Definition: qstate.h:69
QStateMachine * machine() const
static QAbstractStatePrivate * get(QAbstractState *q)
The QHistoryState class provides a means of returning to a previously active substate.
Definition: qhistorystate.h:56
QState * sourceState
the source state (parent) of this transition
#define QSIGNAL_CODE
Definition: qobjectdefs.h:244
QList< QHistoryState * > historyStates() const
Definition: qstate.cpp:215
void removeTransition(QAbstractTransition *transition)
Removes the given transition from this state.
Definition: qstate.cpp:407
void unregisterTransition(QAbstractTransition *transition)
QList< QWeakPointer< QAbstractState > > targetStates
QList< QAbstractState * > childStates() const
Definition: qstate.cpp:199
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
bool event(QEvent *e)
Reimplemented Function
Definition: qstate.cpp:509
QByteArray propertyName
Definition: qstate_p.h:73
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
const QObjectList & children() const
Returns a list of child objects.
Definition: qobject.h:197
QObject * parent
Definition: qobject.h:92
return(isPopup||isToolTip)
void emitPropertiesAssigned()
Definition: qstate.cpp:159
~QState()
Destroys this state.
Definition: qstate.cpp:195
void assignProperty(QObject *object, const char *name, const QVariant &value)
Instructs this state to set the property with the given name of the given object to the given value w...
Definition: qstate.cpp:250
QAbstractState * initialState() const
QState(QState *parent=0)
Constructs a new state with the given parent state.
Definition: qstate.cpp:168
void addTransition(QAbstractTransition *transition)
Adds the given transition.
Definition: qstate.cpp:308
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void emitFinished()
Definition: qstate.cpp:153
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
void setErrorState(QAbstractState *state)
Sets this state&#39;s error state to be the given state.
Definition: qstate.cpp:288
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:272