summaryrefslogtreecommitdiffstats
path: root/src/statemachine/doc
diff options
context:
space:
mode:
Diffstat (limited to 'src/statemachine/doc')
-rw-r--r--src/statemachine/doc/images/animations-architecture.pngbin0 -> 27619 bytes
-rw-r--r--src/statemachine/doc/images/move-blocks-chart.pngbin0 -> 15740 bytes
-rw-r--r--src/statemachine/doc/images/rogue-statechart.pngbin0 -> 2490 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-button-history.pngbin0 -> 8493 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-button-nested.pngbin0 -> 7051 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-button.pngbin0 -> 4233 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-customevents.pngbin0 -> 2544 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-customevents2.pngbin0 -> 6713 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-examples.pngbin0 -> 3326 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-finished.pngbin0 -> 5518 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-nonparallel.pngbin0 -> 5350 bytes
-rw-r--r--src/statemachine/doc/images/statemachine-parallel.pngbin0 -> 8631 bytes
-rw-r--r--src/statemachine/doc/qstatemachine-qml-guide.qdoc293
-rw-r--r--src/statemachine/doc/qt6-changes.qdoc43
-rw-r--r--src/statemachine/doc/qtstatemachine-cpp-guide.qdoc511
-rw-r--r--src/statemachine/doc/qtstatemachine-examples.qdoc12
-rw-r--r--src/statemachine/doc/qtstatemachine-index.qdoc68
-rw-r--r--src/statemachine/doc/qtstatemachine-module-cpp.qdoc16
-rw-r--r--src/statemachine/doc/qtstatemachine-module-qml.qdoc18
-rw-r--r--src/statemachine/doc/qtstatemachine-module-use.qdocinc15
-rw-r--r--src/statemachine/doc/qtstatemachine-overview.qdoc42
-rw-r--r--src/statemachine/doc/qtstatemachine.qdocconf55
-rw-r--r--src/statemachine/doc/snippets/code/src_corelib_statemachine_qstatemachine.cpp18
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/Button.qml51
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/basicstate.qml18
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/finalstate.qml26
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/guardcondition.qml31
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/historystate.qml48
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/signaltransition.qml40
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/signaltransitionsignal.qml25
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/simplestatemachine.qml31
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/statemachine-button-history.qml112
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml97
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/statemachine-button-nested.qml89
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/statemachine-button.qml63
-rw-r--r--src/statemachine/doc/snippets/qml/statemachine/timeouttransition.qml32
-rw-r--r--src/statemachine/doc/snippets/statemachine/eventtest.cpp37
-rw-r--r--src/statemachine/doc/snippets/statemachine/main.cpp52
-rw-r--r--src/statemachine/doc/snippets/statemachine/main2.cpp57
-rw-r--r--src/statemachine/doc/snippets/statemachine/main3.cpp24
-rw-r--r--src/statemachine/doc/snippets/statemachine/main4.cpp75
-rw-r--r--src/statemachine/doc/snippets/statemachine/main5.cpp136
-rw-r--r--src/statemachine/doc/src/images/moveblocks-example.pngbin0 -> 4532 bytes
-rw-r--r--src/statemachine/doc/src/images/rogue-example.pngbin0 -> 10364 bytes
-rw-r--r--src/statemachine/doc/src/images/trafficlight-example.pngbin0 -> 5325 bytes
45 files changed, 2135 insertions, 0 deletions
diff --git a/src/statemachine/doc/images/animations-architecture.png b/src/statemachine/doc/images/animations-architecture.png
new file mode 100644
index 0000000..9b581af
--- /dev/null
+++ b/src/statemachine/doc/images/animations-architecture.png
Binary files differ
diff --git a/src/statemachine/doc/images/move-blocks-chart.png b/src/statemachine/doc/images/move-blocks-chart.png
new file mode 100644
index 0000000..fd0c165
--- /dev/null
+++ b/src/statemachine/doc/images/move-blocks-chart.png
Binary files differ
diff --git a/src/statemachine/doc/images/rogue-statechart.png b/src/statemachine/doc/images/rogue-statechart.png
new file mode 100644
index 0000000..c5f4048
--- /dev/null
+++ b/src/statemachine/doc/images/rogue-statechart.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-button-history.png b/src/statemachine/doc/images/statemachine-button-history.png
new file mode 100644
index 0000000..7f51cae
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-button-history.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-button-nested.png b/src/statemachine/doc/images/statemachine-button-nested.png
new file mode 100644
index 0000000..762ac14
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-button-nested.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-button.png b/src/statemachine/doc/images/statemachine-button.png
new file mode 100644
index 0000000..10102bd
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-button.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-customevents.png b/src/statemachine/doc/images/statemachine-customevents.png
new file mode 100644
index 0000000..62a4222
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-customevents.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-customevents2.png b/src/statemachine/doc/images/statemachine-customevents2.png
new file mode 100644
index 0000000..57b37ef
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-customevents2.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-examples.png b/src/statemachine/doc/images/statemachine-examples.png
new file mode 100644
index 0000000..b2ec66e
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-examples.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-finished.png b/src/statemachine/doc/images/statemachine-finished.png
new file mode 100644
index 0000000..0ac081d
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-finished.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-nonparallel.png b/src/statemachine/doc/images/statemachine-nonparallel.png
new file mode 100644
index 0000000..f9850a7
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-nonparallel.png
Binary files differ
diff --git a/src/statemachine/doc/images/statemachine-parallel.png b/src/statemachine/doc/images/statemachine-parallel.png
new file mode 100644
index 0000000..a65c297
--- /dev/null
+++ b/src/statemachine/doc/images/statemachine-parallel.png
Binary files differ
diff --git a/src/statemachine/doc/qstatemachine-qml-guide.qdoc b/src/statemachine/doc/qstatemachine-qml-guide.qdoc
new file mode 100644
index 0000000..deb9d94
--- /dev/null
+++ b/src/statemachine/doc/qstatemachine-qml-guide.qdoc
@@ -0,0 +1,293 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page qmlstatemachine-qml-guide.html
+ \title Qt State Machine QML Guide
+ \brief Overview of the Qt State Machine QML for constructing and executing state graphs.
+ \ingroup technology-apis
+ \ingroup explanation
+
+ \tableofcontents
+
+ Qt State Machine QML APIs provide types for creating and
+ executing state graphs in QML. It is similar to the C++ State Machine
+ framework based on Harel's
+ \l{Statecharts: A visual formalism for complex systems}, which
+ is also the basis for UML state diagrams. Like its
+ \l{Qt State Machine C++ Classes}{C++ counterpart}, the framework provides an
+ API and execution model based on \l{State Chart XML: State Machine Notation for
+ Control Abstraction}{State Chart XML (SCXML)}
+ to embed the elements and semantics of statecharts in QML applications.
+
+ For user interfaces with multiple visual states, independent of the
+ application's logical state, consider using QML States and Transitions.
+
+ For the full list of QML types provided by the framework to create event-driven
+ state machines, see: \l {Qt State Machine QML Types}
+
+ \section1 Using Both QtQuick and QtQml.StateMachine Imports
+
+ \warning If you're attempting to import both \l{QtQuick} and
+ \e{QtQml.StateMachine} in one single QML file, make sure to import
+ \e{QtQml.StateMachine} \e{last}. This way, the \e{State} type is provided
+ by the Declarative State Machine Framework and not by \l{QtQuick}:
+
+ \qml
+ import QtQuick
+ import QtQml.StateMachine
+
+ StateMachine {
+ State {
+ // okay, is of type QtQml.StateMachine.State
+ }
+ }
+ \endqml
+
+ Alternatively, you can import \e{QtQml.StateMachine} into a separate
+ namespace to avoid any ambiguity with QtQuick's \e{State} item:
+
+ \qml \QtMinorVersion
+ import QtQuick
+ import QtQml.StateMachine as DSM
+
+ DSM.StateMachine {
+ DSM.State {
+ // ...
+ }
+ }
+ \endqml
+
+ \section1 A Simple State Machine
+
+ To demonstrate the core functionality of the State Machine API, let's look
+ at an example: A state machine with three states, \c s1, \c s2 and \c
+ s3. The state machine is controlled by a single Button; when the button
+ is clicked, the machine transitions to another state. Initially, the state
+ machine is in state \c s1. The following is a state chart showing the
+ different states in our example.
+
+ \image statemachine-button.png
+
+ The following snippet shows the code needed to create such a state machine.
+
+ \snippet qml/statemachine/statemachine-button.qml 0
+
+ The state machine runs asynchronously to become part of your application's
+ event loop.
+
+ \section1 State Machines That Finish
+
+ The state machine defined in the previous section never finishes. In order
+ for a state machine to be able to finish, it needs to have a top-level \e
+ final state (FinalState object). When the state machine enters the top-level
+ final state, the machine emits the \l{State::finished}{finished}
+ signal and halts.
+
+ All you need to do to introduce a final state in the graph is create a
+ FinalState object and use it as the target of one or more transitions.
+
+ \section1 Sharing Transitions
+
+ Assume we wanted the user to be able to quit the application at any time by
+ clicking a Quit button. In order to achieve this, we need to create a final
+ state and make it the target of a transition associated with the Quit
+ button's \e clicked() signal. We could add a transition for each state;
+ however, this seems redundant and one would also have to
+ remember to add such a transition from every new state that is added in the
+ future.
+
+ We can achieve the same behavior (namely that clicking the Quit button quits
+ the state machine, regardless of which state the state machine is in) by
+ grouping states \c s1, \c s2 and \c s3. This is done by creating a new
+ top-level state and making the three original states children of the new
+ state. The following diagram shows the new state machine.
+
+ \image statemachine-button-nested.png
+
+ The three original states have been renamed \c s11, \c s12 and \c s13 to
+ reflect that they are now childrens of the new top-level state, \c s1. Child
+ states implicitly inherit the transitions of their parent state. This means
+ it is now sufficient to add a single transition from \c s1 to the final
+ state, \c s2. New states added to \c s1 will automatically inherit this
+ transition.
+
+ All that's needed to group states is to specify the proper parent when the
+ state is created. You also need to specify which of the child states is the
+ initial one (the child state the state machine should enter when the
+ parent state is the target of a transition).
+
+ \snippet qml/statemachine/statemachine-button-nested.qml 0
+
+ In this case we want the application to quit when the state machine is
+ finished, so the machine's \e finished() signal is connected to the
+ application's \e quit() slot.
+
+ A child state can override an inherited transition. For example, the
+ following code adds a transition that effectively causes the Quit button to
+ be ignored when the state machine is in state, \c s12.
+
+ \snippet qml/statemachine/statemachine-button-nested-ignore-quit.qml 0
+
+ A transition can have any state as its target irrespective of where the
+ target state is in the state hierarchy.
+
+ \section1 Using History States
+
+ Imagine that we wanted to add an "interrupt" mechanism to the example
+ discussed in the previous section; the user should be able to click a button
+ to have the state machine perform some non-related task, after which the
+ state machine should resume whatever it was doing before (i.e. return to the
+ old state, which is one of the three states in this case).
+
+ Such behavior can easily be modeled using \e{history states}. A history
+ state (HistoryState object) is a pseudo-state that represents the child
+ state that the parent state was in before it exited last.
+
+ A history state is created as a child of the state for which we wish to
+ record the current child state; when the state machine detects the presence
+ of such a state at runtime, it automatically records the current (real)
+ child state when the parent state exits. A transition to the history
+ state is in fact a transition to the child state that the state machine had
+ previously saved; the state machine automatically "forwards" the transition
+ to the real child state.
+
+ The following diagram shows the state machine after the interrupt mechanism
+ has been added.
+
+ \image statemachine-button-history.png
+
+ The following code shows how it can be implemented; in this example we
+ simply display a message box when \c s3 is entered, then immediately return
+ to the previous child state of \c s1 via the history state.
+
+ \snippet qml/statemachine/statemachine-button-history.qml 0
+
+ \section1 Using Parallel States
+
+ Assume that you wanted to model a set of mutually exclusive properties of a
+ car in a single state machine. Let's say the properties we are interested in
+ are Clean vs Dirty, and Moving vs Not moving. It would take four mutually
+ exclusive states and eight transitions to represent the states and freely
+ move between all possible combinations as shown in the following state chart.
+
+ \image statemachine-nonparallel.png
+
+ If we added a third property (say, Red vs Blue), the total number of states
+ would double, to eight; and if we added a fourth property (say, Enclosed vs
+ Convertible), the total number of states would double again, to 16.
+
+ This exponential increase can be reduced using parallel states, which enables
+ linear growth in the number of states and transitions as we add more
+ properties. Furthermore, states can be added to or removed from the parallel
+ state without affecting any of their sibling states. The following state
+ chart shows the different paralles states for the car example.
+
+ \image statemachine-parallel.png
+
+ To create a parallel state group, set childMode to QState.ParallelStates.
+
+ \qml
+ State {
+ id: s1
+ childMode: QState.ParallelStates
+ State {
+ id: s11
+ }
+ State {
+ id: s12
+ }
+ }
+ \endqml
+
+ When a parallel state group is entered, all its child states will be
+ simultaneously entered. Transitions within the individual child states
+ operate normally. However, any of the child states may take a transition
+ which exits the parent state. When this happens, the parent state and all of
+ its child states are exited.
+
+ The parallelism in the State Machine framework follows an interleaved
+ semantics. All parallel operations will be executed in a single, atomic step
+ of the event processing, so no event can interrupt the parallel operations.
+ However, events will still be processed sequentially, as the machine itself
+ is single threaded. For example, consider the situation where there are two
+ transitions that exit the same parallel state group, and their conditions
+ become true simultaneously. In this case, the event that is processed last
+ of the two will not have any effect.
+
+ \section1 Exiting a Composite State
+
+ A child state can be final (a FinalState object); when a final child state
+ is entered, the parent state emits the State::finished signal. The
+ following diagram shows a composite state \c s1 which does some processing
+ before entering a final state:
+
+ \image statemachine-finished.png
+
+ When \c s1 's final state is entered, \c s1 will automatically emit
+ \l{State::finished}{finished}. We use a signal transition to cause this event to
+ trigger a state change:
+
+ \qml
+ State {
+ id: s1
+ SignalTransition {
+ targetState: s2
+ signal: s1.finished
+ }
+ }
+ \endqml
+
+ Using final states in composite states is useful when you want to hide the
+ internal details of a composite state. The outside world should be able to
+ enter the state and get a notification when the state has completed its work,
+ without the need to know the internal details. This is a very powerful
+ abstraction and encapsulation mechanism when building complex (deeply nested)
+ state machines. (In the above example, you could of course create a transition
+ directly from \c s1 's \c done state rather than relying on \c s1 's
+ finished() signal, but with the consequence that implementation details of
+ \c s1 are exposed and depended on).
+
+ For parallel state groups, the State::finished signal is emitted when \e
+ all the child states have entered final states.
+
+ \section1 Targetless Transitions
+
+ A transition need not have a target state. A transition without a target can
+ be triggered the same way as any other transition; the difference is that
+ it doesn't cause any state changes. This allows you to react to a signal or
+ event when your machine is in a certain state, without having to leave that
+ state. For example:
+
+ \qml
+ Button {
+ id: button
+ text: "button"
+ StateMachine {
+ id: stateMachine
+ initialState: s1
+ running: true
+ State {
+ id: s1
+ SignalTransition {
+ signal: button.clicked
+ onTriggered: console.log("button pressed")
+ }
+ }
+ }
+ }
+ \endqml
+
+ The "button pressed" message will be displayed each time the button is clicked, but the
+ state machine will remain in its current state (s1). If the target state
+ were explicitly set to s1, s1 would be exited and re-entered each
+ time (the QAbstractState::entered and QAbstractState::exited
+ signals would be emitted).
+
+ \section1 Related Information
+
+ \list
+ \li \l{Qt State Machine QML Types}
+ \li \l{Qt State Machine Overview}
+ \endlist
+*/
diff --git a/src/statemachine/doc/qt6-changes.qdoc b/src/statemachine/doc/qt6-changes.qdoc
new file mode 100644
index 0000000..c7f6efe
--- /dev/null
+++ b/src/statemachine/doc/qt6-changes.qdoc
@@ -0,0 +1,43 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page qtstatemachine-changes-qt6.html
+ \title Changes to Qt State Machine
+ \ingroup changes-qt-5-to-6
+ \brief Migrate Qt State Machine to Qt 6.
+
+ Qt 6 is a result of the conscious effort to make the framework more
+ efficient and easy to use.
+
+ We try to maintain binary and source compatibility for all the public
+ APIs in each release. But some changes were inevitable in an effort to
+ make Qt a better framework.
+
+ In this topic we summarize those changes in Qt State Machine module, and provide
+ guidance to handle them.
+
+ \section1 Changes
+
+ The Qt StateMachine module is generally speaking source compatible with the Qt5
+ version and users of the library should be able to continue with no or
+ minor changes to their project.
+
+ \section2 QSignalTransition
+
+ The \l [CPP] QSignalTransition::senderObject() getter and the related
+ Q_PROPERTY now also use const QObject*. These are now better aligned
+ with the setter \l [CPP] QSignalTransition::setSenderObject(const QObject*) that takes a
+ const QObject* as a parameter.
+
+ \section1 Build system
+
+ As with Qt 6 in general, the Qt State Machine module has cmake support in addition
+ to qmake.
+
+ \section1 QML imports
+
+ The QML import versioning is optional unless one has a specific
+ reason for not using the latest. Generally speaking the versioned imports
+ work from version 5.8 to 6.x, where 'x' is the current minor release.
+*/
diff --git a/src/statemachine/doc/qtstatemachine-cpp-guide.qdoc b/src/statemachine/doc/qtstatemachine-cpp-guide.qdoc
new file mode 100644
index 0000000..a898ba4
--- /dev/null
+++ b/src/statemachine/doc/qtstatemachine-cpp-guide.qdoc
@@ -0,0 +1,511 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page qtstatemachine-cpp-guide.html
+ \title Qt State Machine C++ Guide
+ \brief An overview of the State Machine framework for constructing and
+ executing state graphs with the C++ API.
+ \ingroup technology-apis
+ \ingroup explanation
+
+ \tableofcontents
+
+ The State Machine framework provides classes for creating and executing
+ state graphs. This page illustrates the framework's key features in C++.
+
+ \sa {Qt State Machine Overview}
+ \sa {Qt State Machine QML Guide}
+
+ \section1 C++ Classes in the State Machine Framework
+
+ For the full list of C++ classes in the State Machine framework see
+ \l {Qt State Machine C++ Classes}
+
+ \section1 A Simple State Machine
+
+ To demonstrate the core functionality of the State Machine API, let's look
+ at a small example: A state machine with three states, \c s1, \c s2 and \c
+ s3. The state machine is controlled by a single QPushButton; when the button
+ is clicked, the machine transitions to another state. Initially, the state
+ machine is in state \c s1. The statechart for this machine is as follows:
+
+ \image statemachine-button.png
+
+ The following snippet shows the code needed to create such a state machine.
+ First, we create the state machine and states:
+
+ \snippet statemachine/main.cpp 0
+
+ Then, we create the transitions by using the QState::addTransition()
+ function:
+
+ \snippet statemachine/main.cpp 1
+
+ Next, we add the states to the machine and set the machine's initial state:
+
+ \snippet statemachine/main.cpp 2
+
+ Finally, we start the state machine:
+
+ \snippet statemachine/main.cpp 3
+
+ The state machine executes asynchronously, i.e. it becomes part of your
+ application's event loop.
+
+ \section1 Doing Useful Work on State Entry and Exit
+
+ The above state machine merely transitions from one state to another, it
+ doesn't perform any operations. The QState::assignProperty() function can be
+ used to have a state set a property of a QObject when the state is
+ entered. In the following snippet, the value that should be assigned to a
+ QLabel's text property is specified for each state:
+
+ \snippet statemachine/main.cpp 4
+
+ When any of the states is entered, the label's text will be changed
+ accordingly.
+
+ The QState::entered() signal is emitted when the state is entered, and the
+ QState::exited() signal is emitted when the state is exited. In the
+ following snippet, the button's \l {QPushButton::}{showMaximized()} slot
+ will be called when state \c s3 is entered, and the button's \l {QPushButton::}{showMinimized()}
+ slot will be called when \c s3 is exited:
+
+ \snippet statemachine/main.cpp 5
+
+ Custom states can reimplement QAbstractState::onEntry() and
+ QAbstractState::onExit().
+
+ \section1 State Machines That Finish
+
+ The state machine defined in the previous section never finishes. In order
+ for a state machine to be able to finish, it needs to have a top-level \e
+ final state (QFinalState object). When the state machine enters a top-level
+ final state, the machine will emit the QStateMachine::finished() signal and
+ halt.
+
+ All you need to do to introduce a final state in the graph is create a
+ QFinalState object and use it as the target of one or more transitions.
+
+ \section1 Sharing Transitions By Grouping States
+
+ Assume we wanted the user to be able to quit the application at any time by
+ clicking a Quit button. In order to achieve this, we need to create a final
+ state and make it the target of a transition associated with the Quit
+ button's \l{QPushButton::}{clicked()} signal. We could add a transition from each of \c s1, \c
+ s2 and \c s3; however, this seems redundant, and one would also have to
+ remember to add such a transition from every new state that is added in the
+ future.
+
+ We can achieve the same behavior (namely that clicking the Quit button quits
+ the state machine, regardless of which state the state machine is in) by
+ grouping states \c s1, \c s2 and \c s3. This is done by creating a new
+ top-level state and making the three original states children of the new
+ state. The following diagram shows the new state machine.
+
+ \image statemachine-button-nested.png
+
+ The three original states have been renamed \c s11, \c s12 and \c s13 to
+ reflect that they are now children of the new top-level state, \c s1. Child
+ states implicitly inherit the transitions of their parent state. This means
+ it is now sufficient to add a single transition from \c s1 to the final
+ state \c s2. New states added to \c s1 will also automatically inherit this
+ transition.
+
+ All that's needed to group states is to specify the proper parent when the
+ state is created. You also need to specify which of the child states is the
+ initial one (i.e. which child state the state machine should enter when the
+ parent state is the target of a transition).
+
+ \snippet statemachine/main2.cpp 0
+
+ \snippet statemachine/main2.cpp 1
+
+ In this case we want the application to quit when the state machine is
+ finished, so the machine's \l {QStateMachine::}{finished()} signal is connected to the
+ application's \l {QCoreApplication::}{quit()} slot.
+
+ A child state can override an inherited transition. For example, the
+ following code adds a transition that effectively causes the Quit button to
+ be ignored when the state machine is in state \c s12.
+
+ \snippet statemachine/main2.cpp 2
+
+ A transition can have any state as its target, i.e. the target state does
+ not have to be on the same level in the state hierarchy as the source state.
+
+ \section1 Using History States to Save and Restore the Current State
+
+ Imagine that we wanted to add an "interrupt" mechanism to the example
+ discussed in the previous section; the user should be able to click a button
+ to have the state machine perform some non-related task, after which the
+ state machine should resume whatever it was doing before (i.e. return to the
+ old state, which is one of \c s11, \c s12 and \c s13 in this case).
+
+ Such behavior can easily be modeled using \e{history states}. A history
+ state (QHistoryState object) is a pseudo-state that represents the child
+ state that the parent state was in the last time the parent state was
+ exited.
+
+ A history state is created as a child of the state for which we wish to
+ record the current child state; when the state machine detects the presence
+ of such a state at runtime, it automatically records the current (real)
+ child state when the parent state is exited. A transition to the history
+ state is in fact a transition to the child state that the state machine had
+ previously saved; the state machine automatically "forwards" the transition
+ to the real child state.
+
+ The following diagram shows the state machine after the interrupt mechanism
+ has been added.
+
+ \image statemachine-button-history.png
+
+ The following code shows how it can be implemented; in this example we
+ simply display a message box when \c s3 is entered, then immediately return
+ to the previous child state of \c s1 via the history state.
+
+ \snippet statemachine/main2.cpp 3
+
+ \section1 Using Parallel States to Avoid a Combinatorial Explosion of States
+
+ Assume that you wanted to model a set of mutually exclusive properties of a
+ car in a single state machine. Let's say the properties we are interested in
+ are Clean vs Dirty, and Moving vs Not moving. It would take four mutually
+ exclusive states and eight transitions to be able to represent and freely
+ move between all possible combinations.
+
+ \image statemachine-nonparallel.png
+
+ If we added a third property (say, Red vs Blue), the total number of states
+ would double, to eight; and if we added a fourth property (say, Enclosed vs
+ Convertible), the total number of states would double again, to 16.
+
+ Using parallel states, the total number of states and transitions grows
+ linearly as we add more properties, instead of exponentially. Furthermore,
+ states can be added to or removed from the parallel state without affecting
+ any of their sibling states.
+
+ \image statemachine-parallel.png
+
+ To create a parallel state group, pass QState::ParallelStates to the QState
+ constructor.
+
+ \snippet statemachine/main3.cpp 0
+
+ When a parallel state group is entered, all its child states will be
+ simultaneously entered. Transitions within the individual child states
+ operate normally. However, any of the child states may take a transition which exits the parent
+ state. When this happens, the parent state and all of its child states are exited.
+
+ The parallelism in the State Machine framework follows an interleaved semantics. All parallel
+ operations will be executed in a single, atomic step of the event processing, so no event can
+ interrupt the parallel operations. However, events will still be processed sequentially, since
+ the machine itself is single threaded. As an example: Consider the situation where there are two
+ transitions that exit the same parallel state group, and their conditions become true
+ simultaneously. In this case, the event that is processed last of the two will not have any
+ effect, since the first event will already have caused the machine to exit from the parallel
+ state.
+
+ \section1 Detecting that a Composite State has Finished
+
+ A child state can be final (a QFinalState object); when a final child state
+ is entered, the parent state emits the QState::finished() signal. The
+ following diagram shows a composite state \c s1 which does some processing
+ before entering a final state:
+
+ \image statemachine-finished.png
+
+ When \c s1 's final state is entered, \c s1 will automatically emit
+ \l {QState::}{finished()}. We use a signal transition to cause this event to trigger a
+ state change:
+
+ \snippet statemachine/main3.cpp 1
+
+ Using final states in composite states is useful when you want to hide the
+ internal details of a composite state; i.e. the only thing the outside world
+ should be able to do is enter the state, and get a notification when the
+ state has completed its work. This is a very powerful abstraction and
+ encapsulation mechanism when building complex (deeply nested) state
+ machines. (In the above example, you could of course create a transition
+ directly from \c s1 's \c done state rather than relying on \c s1 's
+ \l {QState::}{finished()} signal, but with the consequence that implementation details of
+ \c s1 are exposed and depended on).
+
+ For parallel state groups, the QState::finished() signal is emitted when \e
+ all the child states have entered final states.
+
+ \section1 Targetless Transitions
+
+ A transition need not have a target state. A transition without a target can
+ be triggered the same way as any other transition; the difference is that
+ when a targetless transition is triggered, it doesn't cause any state
+ changes. This allows you to react to a signal or event when your machine is
+ in a certain state, without having to leave that state. Example:
+
+ \code
+ QStateMachine machine;
+ QState *s1 = new QState(&machine);
+
+ QPushButton button;
+ QSignalTransition *trans = new QSignalTransition(&button, &QPushButton::clicked);
+ s1->addTransition(trans);
+
+ QMessageBox msgBox;
+ msgBox.setText("The button was clicked; carry on.");
+ QObject::connect(trans, QSignalTransition::triggered, &msgBox, &QMessageBox::exec);
+
+ machine.setInitialState(s1);
+ \endcode
+
+ The message box will be displayed each time the button is clicked, but the
+ state machine will remain in its current state (s1). If the target state
+ were explicitly set to s1, however, s1 would be exited and re-entered each
+ time (e.g. the QAbstractState::entered() and QAbstractState::exited()
+ signals would be emitted).
+
+ \section1 Events, Transitions and Guards
+
+ A QStateMachine runs its own event loop. For signal transitions
+ (QSignalTransition objects), QStateMachine automatically posts a
+ QStateMachine::SignalEvent to itself when it intercepts the corresponding
+ signal; similarly, for QObject event transitions (QEventTransition objects)
+ a QStateMachine::WrappedEvent is posted.
+
+ You can post your own events to the state machine using
+ QStateMachine::postEvent().
+
+ When posting a custom event to the state machine, you typically also have
+ one or more custom transitions that can be triggered from events of that
+ type. To create such a transition, you subclass QAbstractTransition and
+ reimplement \l [CPP] {QAbstractTransition::}{eventTest()}, where you check if an event
+ matches your event type (and optionally other criteria, e.g. attributes of
+ the event object).
+
+ Here we define our own custom event type, \c StringEvent, for posting
+ strings to the state machine:
+
+ \snippet statemachine/main4.cpp 0
+
+ Next, we define a transition that only triggers when the event's string
+ matches a particular string (a \e guarded transition):
+
+ \snippet statemachine/main4.cpp 1
+
+ In the \l [CPP] {QAbstractTransition::}{eventTest()} reimplementation, we first check if the event type is the
+ desired one; if so, we cast the event to a \c StringEvent and perform the
+ string comparison.
+
+ The following is a statechart that uses the custom event and transition:
+
+ \image statemachine-customevents.png
+
+ Here's what the implementation of the statechart looks like:
+
+ \snippet statemachine/main4.cpp 2
+
+ Once the machine is started, we can post events to it.
+
+ \snippet statemachine/main4.cpp 3
+
+ An event that is not handled by any relevant transition will be silently
+ consumed by the state machine. It can be useful to group states and provide
+ a default handling of such events; for example, as illustrated in the
+ following statechart:
+
+ \image statemachine-customevents2.png
+
+ For deeply nested statecharts, you can add such "fallback" transitions at
+ the level of granularity that's most appropriate.
+
+ \section1 Using Restore Policy To Automatically Restore Properties
+
+ In some state machines it can be useful to focus the attention on assigning properties in states,
+ not on restoring them when the state is no longer active. If you know that a property should
+ always be restored to its initial value when the machine enters a state that does not explicitly
+ give the property a value, you can set the global restore policy to
+ QStateMachine::RestoreProperties.
+
+ \code
+ QStateMachine machine;
+ machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties);
+ \endcode
+
+ When this restore policy is set, the machine will automatically restore all properties. If it
+ enters a state where a given property is not set, it will first search the hierarchy of ancestors
+ to see if the property is defined there. If it is, the property will be restored to the value
+ defined by the closest ancestor. If not, it will be restored to its initial value (i.e. the
+ value of the property before any property assignments in states were executed.)
+
+ Take the following code:
+
+ \snippet statemachine/main5.cpp 0
+
+ Lets say the property \c fooBar is 0.0 when the machine starts. When the machine is in state
+ \c s1, the property will be 1.0, since the state explicitly assigns this value to it. When the
+ machine is in state \c s2, no value is explicitly defined for the property, so it will implicitly
+ be restored to 0.0.
+
+ If we are using nested states, the parent defines a value for the property which is inherited by
+ all descendants that do not explicitly assign a value to the property.
+
+ \snippet statemachine/main5.cpp 2
+
+ Here \c s1 has two children: \c s2 and \c s3. When \c s2 is entered, the property \c fooBar
+ will have the value 2.0, since this is explicitly defined for the state. When the machine is in
+ state \c s3, no value is defined for the state, but \c s1 defines the property to be 1.0, so this
+ is the value that will be assigned to \c fooBar.
+
+ \section1 Animations and States Machines
+
+ The State Machine API connects with the \l {The Animation Framework} to allow automatically
+ animating properties as they are assigned in states.
+
+ The state machine provides a special state that can play an animation.
+ A QState can also set properties when the state is entered or exited, and
+ this special animation state will interpolate between these values when given a
+ QPropertyAnimation.
+
+ We can associate one or more animations to a transition between states
+ using a QSignalTransition or QEventTransition class. These classes
+ are both derived from QAbstractTransition, which defines the
+ convenience function \l [CPP] {QAbstractTransition::}{addAnimation()} that
+ enables the appending of one or more animations triggered when the
+ transition occurs.
+
+ We also have the possibility to associate properties with the
+ states rather than setting the start and end values ourselves.
+
+ Say we have the following code:
+
+ \snippet statemachine/main5.cpp 3
+
+ Here we define two states of a user interface. In \c s1 the \c button is small, and in \c s2
+ it is bigger. If we click the button to transition from \c s1 to \c s2, the geometry of the button
+ will be set immediately when a given state has been entered. If we want the transition to be
+ smooth, however, all we need to do is make a QPropertyAnimation and add this to the transition
+ object.
+
+ \snippet statemachine/main5.cpp 4
+
+ Adding an animation for the property in question means that the property assignment will no
+ longer take immediate effect when the state has been entered. Instead, the animation will start
+ playing when the state has been entered and smoothly animate the property assignment. Since we
+ do not set the start value or end value of the animation, these will be set implicitly. The
+ start value of the animation will be the property's current value when the animation starts, and
+ the end value will be set based on the property assignments defined for the state.
+
+ If the global restore policy of the state machine is set to QStateMachine::RestoreProperties,
+ it is possible to also add animations for the property restorations.
+
+ \section1 Detecting That All Properties Have Been Set In A State
+
+ When animations are used to assign properties, a state no longer defines the exact values that a
+ property will have when the machine is in the given state. While the animation is running, the
+ property can potentially have any value, depending on the animation.
+
+ In some cases, it can be useful to be able to detect when the property has actually been assigned
+ the value defined by a state.
+
+ Say we have the following code:
+
+ \snippet statemachine/main5.cpp 5
+
+ When \c button is clicked, the machine will transition into state \c s2, which will set the
+ geometry of the button, and then pop up a message box to alert the user that the geometry has
+ been changed.
+
+ In the normal case, where animations are not used, this will operate as expected. However, if
+ an animation for the \c geometry of \c button is set on the transition between \c s1 and \c s2,
+ the animation will be started when \c s2 is entered, but the \c geometry property will not
+ actually reach its defined value before the animation is finished running. In this case, the
+ message box will pop up before the geometry of the button has actually been set.
+
+ To ensure that the message box does not pop up until the geometry actually reaches its final
+ value, we can use the state's \l {QState::}{propertiesAssigned()} signal.
+ The \l {QState::}{propertiesAssigned()} signal will be emitted when the property is assigned
+ its final value, whether this is done immediately or after the animation has finished playing.
+
+ \snippet statemachine/main5.cpp 6
+
+ In this example, when \c button is clicked, the machine will enter \c s2. It will remain in state
+ \c s2 until the \c geometry property has been set to \c QRect(0, 0, 50, 50). Then it will
+ transition into \c s3. When \c s3 is entered, the message box will pop up. If the transition into
+ \c s2 has an animation for the \c geometry property, then the machine will stay in \c s2 until the
+ animation has finished playing. If there is no such animation, it will simply set the property and
+ immediately enter state \c s3.
+
+ Either way, when the machine is in state \c s3, you are guaranteed that the property \c geometry
+ has been assigned the defined value.
+
+ If the global restore policy is set to QStateMachine::RestoreProperties, the state will not emit
+ the \l {QState::}{propertiesAssigned()} signal until these have been executed as well.
+
+ \section1 What Happens If A State Is Exited Before The Animation Has Finished
+
+ If a state has property assignments, and the transition into the state has animations for the
+ properties, the state can potentially be exited before the properties have been assigned to the
+ values defines by the state. This is true in particular when there are transitions out from the
+ state that do not depend on the \l {QState::}{propertiesAssigned()} signal, as described in the previous section.
+
+ The State Machine API guarantees that a property assigned by the state machine either:
+ \list
+ \li Has a value explicitly assigned to the property.
+ \li Is currently being animated into a value explicitly assigned to the property.
+ \endlist
+
+ When a state is exited prior to the animation finishing, the behavior of the state machine depends
+ on the target state of the transition. If the target state explicitly assigns a value to the
+ property, no additional action will be taken. The property will be assigned the value defined by
+ the target state.
+
+ If the target state does not assign any value to the property, there are two
+ options: By default, the property will be assigned the value defined by the state it is leaving
+ (the value it would have been assigned if the animation had been permitted to finish playing). If
+ a global restore policy is set, however, this will take precedence, and the property will be
+ restored as usual.
+
+ \section1 Default Animations
+
+ As described earlier, you can add animations to transitions to make sure property assignments
+ in the target state are animated. If you want a specific animation to be used for a given property
+ regardless of which transition is taken, you can add it as a default animation to the state
+ machine. This is in particular useful when the properties assigned (or restored) by specific
+ states is not known when the machine is constructed.
+
+ \code
+ QState *s1 = new QState();
+ QState *s2 = new QState();
+
+ s2->assignProperty(object, "fooBar", 2.0);
+ s1->addTransition(s2);
+
+ QStateMachine machine;
+ machine.setInitialState(s1);
+ machine.addDefaultAnimation(new QPropertyAnimation(object, "fooBar"));
+ \endcode
+
+ When the machine is in state \c s2, the machine will play the default animation for the
+ property \c fooBar since this property is assigned by \c s2.
+
+ Note that animations explicitly set on transitions will take precedence over any default
+ animation for the given property.
+
+ \section1 Nesting State Machines
+
+ QStateMachine is a subclass of QState. This allows for a state machine to be a child state of
+ another machine. QStateMachine reimplements QState::onEntry() and calls QStateMachine::start(),
+ so that when the child state machine is entered, it will automatically start running.
+
+ The parent state machine treats the child machine as an \e atomic state in the state machine
+ algorithm. The child state machine is self-contained; it maintains its own event queue and
+ configuration. In particular, note that the \l{QStateMachine::}{configuration()}
+ of the child machine is not part of the parent machine's configuration (only the child machine
+ itself is).
+
+ States of the child state machine cannot be specified as targets of transitions in the parent
+ state machine; only the child state machine itself can. Conversely, states of the parent state
+ machine cannot be specified as targets of transitions in the child state machine. The child
+ state machine's \l{QState::}{finished}() signal can be used to trigger a transition
+ in the parent machine.
+*/
diff --git a/src/statemachine/doc/qtstatemachine-examples.qdoc b/src/statemachine/doc/qtstatemachine-examples.qdoc
new file mode 100644
index 0000000..7794b6e
--- /dev/null
+++ b/src/statemachine/doc/qtstatemachine-examples.qdoc
@@ -0,0 +1,12 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+\group examples-qtstatemachine
+\title Qt State Machine Examples
+\brief Examples for the Qt State Machine module.
+
+The Qt State Machine example applications demonstrate the functionality provided by the
+\l{Qt State Machine} module.
+
+*/
diff --git a/src/statemachine/doc/qtstatemachine-index.qdoc b/src/statemachine/doc/qtstatemachine-index.qdoc
new file mode 100644
index 0000000..0557efa
--- /dev/null
+++ b/src/statemachine/doc/qtstatemachine-index.qdoc
@@ -0,0 +1,68 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page qtstatemachine-index.html
+ \title Qt State Machine
+ \brief Provides functionality to create and execute state graphs.
+
+ The State Machine framework provides classes for creating and executing
+ state graphs.
+
+ \section1 Using the Module
+
+ \section2 QML API
+
+ \include {module-use.qdocinc} {using the qml api} {QtQml.StateMachine}
+
+ \section2 C++ API
+
+ \include {module-use.qdocinc} {using the c++ api}
+
+ \section3 Building with CMake
+
+ \include {module-use.qdocinc} {building with cmake} {StateMachine}
+
+ \section3 Building with qmake
+
+ \include {module-use.qdocinc} {building_with_qmake} {statemachine}
+
+ \section1 Articles and Guides
+
+ \list
+ \li \l {Qt State Machine Overview}
+ \li \l {Qt State Machine C++ Guide}
+ \li \l {Qt State Machine QML Guide}
+ \endlist
+
+ \section1 Examples
+
+ \list
+ \li \l {Qt State Machine Examples}
+ \endlist
+
+ \section1 Reference
+
+ \list
+ \li \l {Qt State Machine C++ Classes} {C++ Classes and Namespaces}
+ \li \l {Qt State Machine QML Types} {QML Types}
+ \endlist
+
+ \section1 Module Evolution
+ \l{Changes to Qt State Machine} lists important changes in the module API
+ and functionality that were done for the Qt 6 series of Qt.
+
+ \section1 Licenses and Trademarks
+
+ The Qt State Machine module is available under commercial licenses from
+ \l{The Qt Company}. In addition, it is available under free software licenses:
+ The \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
+ Furthermore, Qt State Machine in Qt \QtVersion may contain third party
+ modules under following permissive licenses:
+
+ \generatelist{groupsbymodule attributions-qtstatemachine}
+
+*/
diff --git a/src/statemachine/doc/qtstatemachine-module-cpp.qdoc b/src/statemachine/doc/qtstatemachine-module-cpp.qdoc
new file mode 100644
index 0000000..fc81267
--- /dev/null
+++ b/src/statemachine/doc/qtstatemachine-module-cpp.qdoc
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \module QtStateMachine
+ \title Qt State Machine C++ Classes
+ \ingroup modules
+ \ingroup technology-apis
+ \qtvariable statemachine
+ \qtcmakepackage StateMachine
+
+ \brief The Qt State Machine module provides classes for creating and executing state graphs.
+
+ The \l {Qt State Machine} page contains information about how to use the module.
+
+*/
diff --git a/src/statemachine/doc/qtstatemachine-module-qml.qdoc b/src/statemachine/doc/qtstatemachine-module-qml.qdoc
new file mode 100644
index 0000000..d9f84bf
--- /dev/null
+++ b/src/statemachine/doc/qtstatemachine-module-qml.qdoc
@@ -0,0 +1,18 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \qmlmodule QtQml.StateMachine 6.\QtMinorVersion
+ \title Qt State Machine QML Types
+ \ingroup qmlmodules
+ \brief Enables the use of State Machine with QML.
+
+ To import the QML types into your application, use the following import statement
+ in your .qml file:
+
+ \qml
+ import QtQml.StateMachine
+ \endqml
+
+ For more information, see \l {Qt State Machine QML Guide}.
+ */
diff --git a/src/statemachine/doc/qtstatemachine-module-use.qdocinc b/src/statemachine/doc/qtstatemachine-module-use.qdocinc
new file mode 100644
index 0000000..fb3101d
--- /dev/null
+++ b/src/statemachine/doc/qtstatemachine-module-use.qdocinc
@@ -0,0 +1,15 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+//! [cmakebuild]
+ \code
+ find_package(Qt6 REQUIRED COMPONENTS StateMachine)
+ target_link_libraries(mytarget PRIVATE Qt6::StateMachine)
+ \endcode
+//! [cmakebuild]
+
+//! [qmakebuild]
+ \code
+ QT += statemachine
+ \endcode
+//! [qmakebuild]
diff --git a/src/statemachine/doc/qtstatemachine-overview.qdoc b/src/statemachine/doc/qtstatemachine-overview.qdoc
new file mode 100644
index 0000000..3438d86
--- /dev/null
+++ b/src/statemachine/doc/qtstatemachine-overview.qdoc
@@ -0,0 +1,42 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page qtstatemachine-overview.html
+ \title Qt State Machine Overview
+ \brief An overview of the State Machine framework for constructing and executing state graphs.
+ \ingroup technology-apis
+ \ingroup explanation
+
+ \tableofcontents
+
+ The State Machine framework provides classes for creating and executing
+ state graphs. The concepts and notation are based on those from Harel's
+ \l{http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf}{Statecharts: A visual formalism for complex systems}, which
+ is also the basis of UML state diagrams. The semantics of state machine
+ execution are based on \l{State Chart XML: State Machine Notation for
+ Control Abstraction}{State Chart XML (SCXML)}.
+
+ Statecharts provide a graphical way of modeling how a system reacts to
+ stimuli. This is done by defining the possible \e states that the system can
+ be in, and how the system can move from one state to another (\e transitions
+ between states). A key characteristic of event-driven systems (such as Qt
+ applications) is that behavior often depends not only on the last or current
+ event, but also the events that preceded it. With statecharts, this
+ information is easy to express.
+
+ The State Machine framework provides an API and execution model that can be
+ used to effectively embed the elements and semantics of statecharts in Qt
+ applications. The framework integrates tightly with Qt's meta-object system;
+ for example, transitions between states can be triggered by signals, and
+ states can be configured to set properties and invoke methods on {QObject}s.
+ Qt's event system is used to drive the state machines.
+
+ The state graph in the State Machine framework is hierarchical. States can be nested inside of
+ other states, and the current configuration of the state machine consists of the set of states
+ which are currently active. All the states in a valid configuration of the state machine will
+ have a common ancestor.
+
+ \sa {Qt State Machine C++ Guide}, {Qt State Machine QML Guide}, {Qt SCXML Overview}
+
+ */
diff --git a/src/statemachine/doc/qtstatemachine.qdocconf b/src/statemachine/doc/qtstatemachine.qdocconf
new file mode 100644
index 0000000..7736501
--- /dev/null
+++ b/src/statemachine/doc/qtstatemachine.qdocconf
@@ -0,0 +1,55 @@
+include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtscxml.qdocconf)
+
+project = QtStateMachine
+description = Qt State Machine Reference Documentation
+version = $QT_VERSION
+
+imagedirs = images src/images
+
+# Install path for the examples
+examplesinstallpath = statemachine
+exampledirs = ../../../examples/statemachine \
+ snippets
+
+qhp.QtStateMachine.subprojects = classes qmltypes examples
+qhp.QtStateMachine.subprojects.classes.title = C++ Classes
+qhp.QtStateMachine.subprojects.classes.indexTitle = Qt State Machine C++ Classes
+qhp.QtStateMachine.subprojects.classes.selectors = class headerfile
+qhp.QtStateMachine.subprojects.classes.sortPages = true
+qhp.QtStateMachine.subprojects.qmltypes.title = QML Types
+qhp.QtStateMachine.subprojects.qmltypes.indexTitle = Qt State Machine QML Types
+qhp.QtStateMachine.subprojects.qmltypes.selectors = qmltype
+qhp.QtStateMachine.subprojects.qmltypes.sortPages = true
+qhp.QtStateMachine.subprojects.examples.title = Examples
+qhp.QtStateMachine.subprojects.examples.indexTitle = Qt State Machine Examples
+qhp.QtStateMachine.subprojects.examples.selectors = doc:example
+
+qhp.projects = QtStateMachine
+
+qhp.QtStateMachine.file = qtstatemachine.qhp
+qhp.QtStateMachine.namespace = org.qt-project.qtstatemachine.$QT_VERSION_TAG
+qhp.QtStateMachine.virtualFolder = qtstatemachine
+qhp.QtStateMachine.indexTitle = Qt StateMachine
+qhp.QtStateMachine.indexRoot =
+
+depends += qtcore qtdoc qmake qtquick qtwidgets qtgui qtqml qtscxml qtcmake
+
+headerdirs = .. \
+ ../gui \
+ ../../statemachineqml \
+ ../../../examples/statemachine
+
+sourcedirs += .. \
+ ../gui \
+ ../../statemachineqml \
+ ../../../examples/statemachine
+
+tagfile = qtstatemachine.tags
+
+navigation.landingpage = "Qt State Machine"
+navigation.cppclassespage = "Qt State Machine C++ Classes"
+navigation.qmltypespage = "Qt State Machine QML Types"
+
+# Highlighted examples in Data Processing & IO category
+manifestmeta.highlighted.names = "QtStateMachine/Traffic Light"
diff --git a/src/statemachine/doc/snippets/code/src_corelib_statemachine_qstatemachine.cpp b/src/statemachine/doc/snippets/code/src_corelib_statemachine_qstatemachine.cpp
new file mode 100644
index 0000000..4c9a0a5
--- /dev/null
+++ b/src/statemachine/doc/snippets/code/src_corelib_statemachine_qstatemachine.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [simple state machine]
+QPushButton button;
+
+QStateMachine machine;
+QState *s1 = new QState();
+s1->assignProperty(&button, "text", "Click me");
+
+QFinalState *s2 = new QFinalState();
+s1->addTransition(&button, &QPushButton::clicked, s2);
+
+machine.addState(s1);
+machine.addState(s2);
+machine.setInitialState(s1);
+machine.start();
+//! [simple state machine]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/Button.qml b/src/statemachine/doc/snippets/qml/statemachine/Button.qml
new file mode 100644
index 0000000..b968a18
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/Button.qml
@@ -0,0 +1,51 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Window
+
+Item {
+ id: container
+
+ property alias text: buttonLabel.text
+ property alias label: buttonLabel
+ signal clicked
+ property alias containsMouse: mouseArea.containsMouse
+ property alias pressed: mouseArea.pressed
+ implicitHeight: Math.max(Screen.pixelDensity * 7, buttonLabel.implicitHeight * 1.2)
+ implicitWidth: Math.max(Screen.pixelDensity * 11, buttonLabel.implicitWidth * 1.3)
+ height: implicitHeight
+ width: implicitWidth
+ property bool checkable: false
+ property bool checked: false
+
+ SystemPalette { id: palette }
+
+ Rectangle {
+ id: frame
+ anchors.fill: parent
+ color: palette.button
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: mouseArea.pressed ? Qt.darker(palette.button, 1.3) : palette.button }
+ GradientStop { position: 1.0; color: Qt.darker(palette.button, 1.3) }
+ }
+ antialiasing: true
+ radius: height / 6
+ border.color: Qt.darker(palette.button, 1.5)
+ border.width: 1
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: container.clicked()
+ hoverEnabled: true
+ }
+
+ Text {
+ id: buttonLabel
+ text: container.text
+ color: palette.buttonText
+ anchors.centerIn: parent
+ }
+}
diff --git a/src/statemachine/doc/snippets/qml/statemachine/basicstate.qml b/src/statemachine/doc/snippets/qml/statemachine/basicstate.qml
new file mode 100644
index 0000000..dac2914
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/basicstate.qml
@@ -0,0 +1,18 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine as DSM
+
+Rectangle {
+ DSM.StateMachine {
+ id: stateMachine
+ initialState: state
+ running: true
+ DSM.State {
+ id: state
+ }
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/finalstate.qml b/src/statemachine/doc/snippets/qml/statemachine/finalstate.qml
new file mode 100644
index 0000000..160419a
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/finalstate.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine as DSM
+
+Rectangle {
+ DSM.StateMachine {
+ id: stateMachine
+ initialState: state
+ running: true
+ DSM.State {
+ id: state
+ DSM.TimeoutTransition {
+ targetState: finalState
+ timeout: 200
+ }
+ }
+ DSM.FinalState {
+ id: finalState
+ }
+ onFinished: console.log("state finished")
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/guardcondition.qml b/src/statemachine/doc/snippets/qml/statemachine/guardcondition.qml
new file mode 100644
index 0000000..9bacea3
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/guardcondition.qml
@@ -0,0 +1,31 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine as DSM
+
+Rectangle {
+ Button {
+ anchors.fill: parent
+ id: button
+ DSM.StateMachine {
+ DSM.State {
+ DSM.SignalTransition {
+ targetState: finalState
+ signal: button.mysignal
+ // the guard condition uses the mystr string argument from mysignal
+ guard: mystr == "test"
+ }
+ }
+ DSM.FinalState {
+ id: finalState
+ }
+ }
+ // define the signal the SignalTransition is connected with
+ signal mysignal(mystr: string)
+ // on clicking the button emit the signal with a single string argument
+ onClicked: button.mysignal("test")
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/historystate.qml b/src/statemachine/doc/snippets/qml/statemachine/historystate.qml
new file mode 100644
index 0000000..e3e7a43
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/historystate.qml
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine as DSM
+
+Rectangle {
+ Button {
+ anchors.fill: parent
+ id: button
+ text: "Press me"
+ DSM.StateMachine {
+ id: stateMachine
+ initialState: parentState
+ running: true
+ DSM.State {
+ id: parentState
+ initialState: child2
+ onEntered: console.log("parentState entered")
+ onExited: console.log("parentState exited")
+ DSM.State {
+ id: child1
+ onEntered: console.log("child1 entered")
+ onExited: console.log("child1 exited")
+ }
+ DSM.State {
+ id: child2
+ onEntered: console.log("child2 entered")
+ onExited: console.log("child2 exited")
+ }
+ DSM.HistoryState {
+ id: historyState
+ defaultState: child1
+ }
+ DSM.SignalTransition {
+ targetState: historyState
+
+ // Clicking the button will cause the state machine to enter the child state
+ // that parentState was in the last time parentState was exited, or the history state's default
+ // state if parentState has never been entered.
+ signal: button.clicked
+ }
+ }
+ }
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/signaltransition.qml b/src/statemachine/doc/snippets/qml/statemachine/signaltransition.qml
new file mode 100644
index 0000000..3d7b4b0
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/signaltransition.qml
@@ -0,0 +1,40 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine as DSM
+
+Rectangle {
+ DSM.StateMachine {
+ id: stateMachine
+ initialState: state
+ running: true
+ DSM.State {
+ id: state
+ DSM.SignalTransition {
+ targetState: finalState
+ signal: button.clicked
+ guard: guardButton.checked
+ }
+ }
+ DSM.FinalState {
+ id: finalState
+ }
+ onFinished: Qt.quit()
+ }
+ Row {
+ spacing: 2
+ Button {
+ id: button
+ text: "Finish state"
+ }
+
+ Button {
+ id: guardButton
+ checkable: true
+ text: checked ? "Press to block the SignalTransition" : "Press to unblock the SignalTransition"
+ }
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/signaltransitionsignal.qml b/src/statemachine/doc/snippets/qml/statemachine/signaltransitionsignal.qml
new file mode 100644
index 0000000..2aeae2a
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/signaltransitionsignal.qml
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine as DSM
+
+Rectangle {
+ Button {
+ anchors.fill: parent
+ id: button
+ DSM.StateMachine {
+ DSM.State {
+ DSM.SignalTransition {
+ targetState: finalState
+ signal: button.clicked
+ }
+ }
+ DSM.FinalState {
+ id: finalState
+ }
+ }
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/simplestatemachine.qml b/src/statemachine/doc/snippets/qml/statemachine/simplestatemachine.qml
new file mode 100644
index 0000000..cd7e01e
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/simplestatemachine.qml
@@ -0,0 +1,31 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine as DSM
+
+Rectangle {
+ Button {
+ anchors.fill: parent
+ id: button
+ text: "Finish state"
+ DSM.StateMachine {
+ id: stateMachine
+ initialState: state
+ running: true
+ DSM.State {
+ id: state
+ DSM.SignalTransition {
+ targetState: finalState
+ signal: button.clicked
+ }
+ }
+ DSM.FinalState {
+ id: finalState
+ }
+ onFinished: Qt.quit()
+ }
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-history.qml b/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-history.qml
new file mode 100644
index 0000000..e5947ae
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-history.qml
@@ -0,0 +1,112 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine
+
+Rectangle {
+//![0]
+ Row {
+ anchors.fill: parent
+ spacing: 2
+ Button {
+ id: button
+ // change the button label to the active state id
+ text: s11.active ? "s11" : s12.active ? "s12" : s13.active ? "s13" : "s3"
+ }
+ Button {
+ id: interruptButton
+ text: s1.active ? "Interrupt" : "Resume"
+ }
+ Button {
+ id: quitButton
+ text: "quit"
+ }
+ }
+
+ StateMachine {
+ id: stateMachine
+ // set the initial state
+ initialState: s1
+
+ // start the state machine
+ running: true
+
+ State {
+ id: s1
+ // set the initial state
+ initialState: s11
+
+ // create a transition from s1 to s2 when the button is clicked
+ SignalTransition {
+ targetState: s2
+ signal: quitButton.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s1 entered")
+ onExited: console.log("s1 exited")
+ State {
+ id: s11
+ // create a transition from s1 to s2 when the button is clicked
+ SignalTransition {
+ targetState: s12
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s11 entered")
+ onExited: console.log("s11 exited")
+ }
+
+ State {
+ id: s12
+ // create a transition from s2 to s3 when the button is clicked
+ SignalTransition {
+ targetState: s13
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s12 entered")
+ onExited: console.log("s12 exited")
+ }
+ State {
+ id: s13
+ // create a transition from s3 to s1 when the button is clicked
+ SignalTransition {
+ targetState: s1
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s13 entered")
+ onExited: console.log("s13 exited")
+ }
+
+ // create a transition from s1 to s3 when the button is clicked
+ SignalTransition {
+ targetState: s3
+ signal: interruptButton.clicked
+ }
+ HistoryState {
+ id: s1h
+ }
+ }
+ FinalState {
+ id: s2
+ onEntered: console.log("s2 entered")
+ onExited: console.log("s2 exited")
+ }
+ State {
+ id: s3
+ SignalTransition {
+ targetState: s1h
+ signal: interruptButton.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s3 entered")
+ onExited: console.log("s3 exited")
+ }
+ onFinished: Qt.quit()
+ }
+//![0]
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml b/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml
new file mode 100644
index 0000000..db40f79
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml
@@ -0,0 +1,97 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine
+
+Rectangle {
+ Row {
+ anchors.fill: parent
+ spacing: 2
+ Button {
+ id: button
+ // change the button label to the active state id
+ text: s11.active ? "s11" : s12.active ? "s12" : "s13"
+ }
+ Button {
+ id: quitButton
+ text: "quit"
+ }
+ }
+
+ StateMachine {
+ id: stateMachine
+ // set the initial state
+ initialState: s1
+
+ // start the state machine
+ running: true
+
+ State {
+ id: s1
+ // set the initial state
+ initialState: s11
+
+ // create a transition from s1 to s2 when the button is clicked
+ SignalTransition {
+ targetState: s2
+ signal: quitButton.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s1 entered")
+ onExited: console.log("s1 exited")
+ State {
+ id: s11
+ // create a transition from s11 to s12 when the button is clicked
+ SignalTransition {
+ targetState: s12
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s11 entered")
+ onExited: console.log("s11 exited")
+ }
+
+//![0]
+ State {
+ id: s12
+ // create a transition from s12 to s13 when the button is clicked
+ SignalTransition {
+ targetState: s13
+ signal: button.clicked
+ }
+
+ // ignore Quit button when we are in state 12
+ SignalTransition {
+ targetState: s12
+ signal: quitButton.clicked
+ }
+
+ // do something when the state enters/exits
+ onEntered: console.log("s12 entered")
+ onExited: console.log("s12 exited")
+ }
+//![0]
+
+ State {
+ id: s13
+ // create a transition from s13 to s11 when the button is clicked
+ SignalTransition {
+ targetState: s11
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s13 entered")
+ onExited: console.log("s13 exited")
+ }
+ }
+ FinalState {
+ id: s2
+ onEntered: console.log("s2 entered")
+ onExited: console.log("s2 exited")
+ }
+ onFinished: Qt.quit()
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-nested.qml b/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-nested.qml
new file mode 100644
index 0000000..eae7427
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/statemachine-button-nested.qml
@@ -0,0 +1,89 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine
+
+Rectangle {
+//![0]
+ Row {
+ anchors.fill: parent
+ spacing: 2
+ Button {
+ id: button
+ // change the button label to the active state id
+ text: s11.active ? "s11" : s12.active ? "s12" : "s13"
+ }
+ Button {
+ id: quitButton
+ text: "quit"
+ }
+ }
+
+ StateMachine {
+ id: stateMachine
+ // set the initial state
+ initialState: s1
+
+ // start the state machine
+ running: true
+
+ State {
+ id: s1
+ // set the initial state
+ initialState: s11
+
+ // create a transition from s1 to s2 when the button is clicked
+ SignalTransition {
+ targetState: s2
+ signal: quitButton.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s1 entered")
+ onExited: console.log("s1 exited")
+ State {
+ id: s11
+ // create a transition from s11 to s12 when the button is clicked
+ SignalTransition {
+ targetState: s12
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s11 entered")
+ onExited: console.log("s11 exited")
+ }
+
+ State {
+ id: s12
+ // create a transition from s12 to s13 when the button is clicked
+ SignalTransition {
+ targetState: s13
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s12 entered")
+ onExited: console.log("s12 exited")
+ }
+ State {
+ id: s13
+ // create a transition from s13 to s11 when the button is clicked
+ SignalTransition {
+ targetState: s11
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s13 entered")
+ onExited: console.log("s13 exited")
+ }
+ }
+ FinalState {
+ id: s2
+ onEntered: console.log("s2 entered")
+ onExited: console.log("s2 exited")
+ }
+ onFinished: Qt.quit()
+ }
+//![0]
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/statemachine-button.qml b/src/statemachine/doc/snippets/qml/statemachine/statemachine-button.qml
new file mode 100644
index 0000000..8873117
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/statemachine-button.qml
@@ -0,0 +1,63 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine
+
+Rectangle {
+//![0]
+ Button {
+ anchors.fill: parent
+ id: button
+
+ // change the button label to the active state id
+ text: s1.active ? "s1" : s2.active ? "s2" : "s3"
+ }
+
+ StateMachine {
+ id: stateMachine
+ // set the initial state
+ initialState: s1
+
+ // start the state machine
+ running: true
+
+ State {
+ id: s1
+ // create a transition from s1 to s2 when the button is clicked
+ SignalTransition {
+ targetState: s2
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s1 entered")
+ onExited: console.log("s1 exited")
+ }
+
+ State {
+ id: s2
+ // create a transition from s2 to s3 when the button is clicked
+ SignalTransition {
+ targetState: s3
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s2 entered")
+ onExited: console.log("s2 exited")
+ }
+ State {
+ id: s3
+ // create a transition from s3 to s1 when the button is clicked
+ SignalTransition {
+ targetState: s1
+ signal: button.clicked
+ }
+ // do something when the state enters/exits
+ onEntered: console.log("s3 entered")
+ onExited: console.log("s3 exited")
+ }
+ }
+//![0]
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/qml/statemachine/timeouttransition.qml b/src/statemachine/doc/snippets/qml/statemachine/timeouttransition.qml
new file mode 100644
index 0000000..60bd420
--- /dev/null
+++ b/src/statemachine/doc/snippets/qml/statemachine/timeouttransition.qml
@@ -0,0 +1,32 @@
+// Copyright (C) 2014 Ford Motor Company
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [document]
+import QtQuick
+import QtQml.StateMachine as DSM
+
+Rectangle {
+ Button {
+ anchors.fill: parent
+ id: button
+ text: "Finish state"
+ enabled: !stateMachine.running
+ onClicked: stateMachine.running = true
+ DSM.StateMachine {
+ id: stateMachine
+ initialState: state
+ running: true
+ DSM.State {
+ id: state
+ DSM.TimeoutTransition {
+ targetState: finalState
+ timeout: 1000
+ }
+ }
+ DSM.FinalState {
+ id: finalState
+ }
+ }
+ }
+}
+//! [document]
diff --git a/src/statemachine/doc/snippets/statemachine/eventtest.cpp b/src/statemachine/doc/snippets/statemachine/eventtest.cpp
new file mode 100644
index 0000000..14cb48b
--- /dev/null
+++ b/src/statemachine/doc/snippets/statemachine/eventtest.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtGui>
+#include <QtStateMachine>
+
+class MyTransition : public QAbstractTransition
+{
+ Q_OBJECT
+public:
+ MyTransition() {}
+
+protected:
+//![0]
+ bool eventTest(QEvent *event) override
+ {
+ if (event->type() == QEvent::Wrapped) {
+ QEvent *wrappedEvent = static_cast<QStateMachine::WrappedEvent *>(event)->event();
+ if (wrappedEvent->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(wrappedEvent);
+ // Do your event test
+ }
+ }
+ return false;
+ }
+//![0]
+
+ void onTransition(QEvent *event) override
+ {
+
+ }
+};
+
+int main(int argv, char **args)
+{
+ return 0;
+}
diff --git a/src/statemachine/doc/snippets/statemachine/main.cpp b/src/statemachine/doc/snippets/statemachine/main.cpp
new file mode 100644
index 0000000..3cbeb5d
--- /dev/null
+++ b/src/statemachine/doc/snippets/statemachine/main.cpp
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtStateMachine>
+#include <QtWidgets>
+
+int main(int argv, char **args)
+{
+ QApplication app(argv, args);
+
+ QLabel *label = new QLabel;
+ QPushButton *button = new QPushButton;
+
+//![0]
+ QStateMachine machine;
+ QState *s1 = new QState();
+ QState *s2 = new QState();
+ QState *s3 = new QState();
+//![0]
+
+//![4]
+ s1->assignProperty(label, "text", "In state s1");
+ s2->assignProperty(label, "text", "In state s2");
+ s3->assignProperty(label, "text", "In state s3");
+//![4]
+
+//![5]
+ QObject::connect(s3, &QState::entered, button, &QPushButton:showMaximized);
+ QObject::connect(s3, &QState::exited, button, &QPushButton::showMinimized);
+//![5]
+
+//![1]
+ s1->addTransition(button, &QPushButton::clicked, s2);
+ s2->addTransition(button, &QPushButton::clicked, s3);
+ s3->addTransition(button, &QPushButton::clicked, s1);
+//![1]
+
+//![2]
+ machine.addState(s1);
+ machine.addState(s2);
+ machine.addState(s3);
+ machine.setInitialState(s1);
+//![2]
+
+//![3]
+ machine.start();
+//![3]
+
+ label->show();
+
+ return app.exec();
+}
diff --git a/src/statemachine/doc/snippets/statemachine/main2.cpp b/src/statemachine/doc/snippets/statemachine/main2.cpp
new file mode 100644
index 0000000..4fe4c19
--- /dev/null
+++ b/src/statemachine/doc/snippets/statemachine/main2.cpp
@@ -0,0 +1,57 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtStateMachine>
+#include <QtWidgets>
+
+int main(int argv, char **args)
+{
+ QApplication app(argv, args);
+
+ QStateMachine machine;
+
+//![0]
+ QState *s1 = new QState();
+ QState *s11 = new QState(s1);
+ QState *s12 = new QState(s1);
+ QState *s13 = new QState(s1);
+ s1->setInitialState(s11);
+ machine.addState(s1);
+//![0]
+
+//![2]
+ s12->addTransition(quitButton, &QPushButton::clicked, s12);
+//![2]
+
+//![1]
+ QFinalState *s2 = new QFinalState();
+ s1->addTransition(quitButton, &QPushButton::clicked, s2);
+ machine.addState(s2);
+ machine.setInitialState(s1);
+
+ QObject::connect(&machine, &QStateMachine::finished,
+ QCoreApplication::instance(), &QCoreApplication::quit);
+//![1]
+
+ QButton *interruptButton = new QPushButton("Interrupt Button");
+ QWidget *mainWindow = new QWidget();
+
+//![3]
+ QHistoryState *s1h = new QHistoryState(s1);
+
+ QState *s3 = new QState();
+ s3->assignProperty(label, "text", "In s3");
+ QMessageBox *mbox = new QMessageBox(mainWindow);
+ mbox->addButton(QMessageBox::Ok);
+ mbox->setText("Interrupted!");
+ mbox->setIcon(QMessageBox::Information);
+ QObject::connect(s3, &QState::entered, mbox, &QMessageBox::exec);
+ s3->addTransition(s1h);
+ machine.addState(s3);
+
+ s1->addTransition(interruptButton, &QPushButton::clicked, s3);
+//![3]
+
+ return app.exec();
+}
+
diff --git a/src/statemachine/doc/snippets/statemachine/main3.cpp b/src/statemachine/doc/snippets/statemachine/main3.cpp
new file mode 100644
index 0000000..7bae11f
--- /dev/null
+++ b/src/statemachine/doc/snippets/statemachine/main3.cpp
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtGui>
+#include <QtStateMachine>
+
+int main(int argv, char **args)
+{
+ QApplication app(argv, args);
+
+//![0]
+ QState *s1 = new QState(QState::ParallelStates);
+ // s11 and s12 will be entered in parallel
+ QState *s11 = new QState(s1);
+ QState *s12 = new QState(s1);
+//![0]
+
+//![1]
+ s1->addTransition(s1, &QState::finished, s2);
+//![1]
+
+ return app.exec();
+}
+
diff --git a/src/statemachine/doc/snippets/statemachine/main4.cpp b/src/statemachine/doc/snippets/statemachine/main4.cpp
new file mode 100644
index 0000000..bac255a
--- /dev/null
+++ b/src/statemachine/doc/snippets/statemachine/main4.cpp
@@ -0,0 +1,75 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtGui>
+#include <QtStateMachine>
+
+//![0]
+struct StringEvent : public QEvent
+{
+ StringEvent(const QString &val)
+ : QEvent(QEvent::Type(QEvent::User+1)),
+ value(val) {}
+
+ QString value;
+};
+//![0]
+
+//![1]
+class StringTransition : public QAbstractTransition
+{
+ Q_OBJECT
+
+public:
+ StringTransition(const QString &value)
+ : m_value(value) {}
+
+protected:
+ bool eventTest(QEvent *e) override
+ {
+ if (e->type() != QEvent::Type(QEvent::User+1)) // StringEvent
+ return false;
+ StringEvent *se = static_cast<StringEvent*>(e);
+ return (m_value == se->value);
+ }
+
+ void onTransition(QEvent *) override {}
+
+private:
+ QString m_value;
+};
+//![1]
+
+int main(int argv, char **args)
+{
+ QApplication app(argv, args);
+
+//![2]
+ QStateMachine machine;
+ QState *s1 = new QState();
+ QState *s2 = new QState();
+ QFinalState *done = new QFinalState();
+
+ StringTransition *t1 = new StringTransition("Hello");
+ t1->setTargetState(s2);
+ s1->addTransition(t1);
+ StringTransition *t2 = new StringTransition("world");
+ t2->setTargetState(done);
+ s2->addTransition(t2);
+
+ machine.addState(s1);
+ machine.addState(s2);
+ machine.addState(done);
+ machine.setInitialState(s1);
+//![2]
+
+//![3]
+ machine.postEvent(new StringEvent("Hello"));
+ machine.postEvent(new StringEvent("world"));
+//![3]
+
+ return app.exec();
+}
+
+#include "main4.moc"
+
diff --git a/src/statemachine/doc/snippets/statemachine/main5.cpp b/src/statemachine/doc/snippets/statemachine/main5.cpp
new file mode 100644
index 0000000..3b1b7e9
--- /dev/null
+++ b/src/statemachine/doc/snippets/statemachine/main5.cpp
@@ -0,0 +1,136 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtGui>
+#include <QtStateMachine>
+
+int main(int argv, char **args)
+{
+ QApplication app(argv, args);
+ QWidget *button;
+
+ {
+//![0]
+ QStateMachine machine;
+ machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties);
+
+ QState *s1 = new QState();
+ s1->assignProperty(object, "fooBar", 1.0);
+ machine.addState(s1);
+ machine.setInitialState(s1);
+
+ QState *s2 = new QState();
+ machine.addState(s2);
+//![0]
+ }
+
+ {
+
+//![2]
+ QStateMachine machine;
+ machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties);
+
+ QState *s1 = new QState();
+ s1->assignProperty(object, "fooBar", 1.0);
+ machine.addState(s1);
+ machine.setInitialState(s1);
+
+ QState *s2 = new QState(s1);
+ s2->assignProperty(object, "fooBar", 2.0);
+ s1->setInitialState(s2);
+
+ QState *s3 = new QState(s1);
+//![2]
+
+ }
+
+ {
+//![3]
+ QState *s1 = new QState();
+ QState *s2 = new QState();
+
+ s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50));
+ s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100));
+
+ s1->addTransition(button, &QPushButton::clicked, s2);
+//![3]
+
+ }
+
+ {
+//![4]
+ QState *s1 = new QState();
+ QState *s2 = new QState();
+
+ s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50));
+ s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100));
+
+ QSignalTransition *transition = s1->addTransition(button, &QPushButton::clicked, s2);
+ transition->addAnimation(new QPropertyAnimation(button, "geometry"));
+//![4]
+
+ }
+
+ {
+ QMainWindow *mainWindow = 0;
+
+//![5]
+ QMessageBox *messageBox = new QMessageBox(mainWindow);
+ messageBox->addButton(QMessageBox::Ok);
+ messageBox->setText("Button geometry has been set!");
+ messageBox->setIcon(QMessageBox::Information);
+
+ QState *s1 = new QState();
+
+ QState *s2 = new QState();
+ s2->assignProperty(button, "geometry", QRectF(0, 0, 50, 50));
+ connect(s2, &QState::entered, messageBox, SLOT(exec()));
+
+ s1->addTransition(button, &QPushButton::clicked, s2);
+//![5]
+ }
+
+ {
+ QMainWindow *mainWindow = 0;
+
+//![6]
+ QMessageBox *messageBox = new QMessageBox(mainWindow);
+ messageBox->addButton(QMessageBox::Ok);
+ messageBox->setText("Button geometry has been set!");
+ messageBox->setIcon(QMessageBox::Information);
+
+ QState *s1 = new QState();
+
+ QState *s2 = new QState();
+ s2->assignProperty(button, "geometry", QRectF(0, 0, 50, 50));
+
+ QState *s3 = new QState();
+ connect(s3, &QState::entered, messageBox, SLOT(exec()));
+
+ s1->addTransition(button, &QPushButton::clicked, s2);
+ s2->addTransition(s2, &QState::propertiesAssigned, s3);
+//![6]
+
+ }
+
+ {
+
+//![7]
+ QState *s1 = new QState();
+ QState *s2 = new QState();
+
+ s2->assignProperty(object, "fooBar", 2.0);
+ s1->addTransition(s2);
+
+ QStateMachine machine;
+ machine.setInitialState(s1);
+ machine.addDefaultAnimation(new QPropertyAnimation(object, "fooBar"));
+//![7]
+
+ }
+
+
+
+ return app.exec();
+}
+
diff --git a/src/statemachine/doc/src/images/moveblocks-example.png b/src/statemachine/doc/src/images/moveblocks-example.png
new file mode 100644
index 0000000..56353d1
--- /dev/null
+++ b/src/statemachine/doc/src/images/moveblocks-example.png
Binary files differ
diff --git a/src/statemachine/doc/src/images/rogue-example.png b/src/statemachine/doc/src/images/rogue-example.png
new file mode 100644
index 0000000..7aeb0e5
--- /dev/null
+++ b/src/statemachine/doc/src/images/rogue-example.png
Binary files differ
diff --git a/src/statemachine/doc/src/images/trafficlight-example.png b/src/statemachine/doc/src/images/trafficlight-example.png
new file mode 100644
index 0000000..3431542
--- /dev/null
+++ b/src/statemachine/doc/src/images/trafficlight-example.png
Binary files differ