diff options
author | Liang Qi <liang.qi@qt.io> | 2017-08-17 10:45:20 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-08-17 10:45:26 +0200 |
commit | 5671c31a5141fed64edbe53fece895b2fd7449d3 (patch) | |
tree | 97dd4aebb4f64ea9117cc149fbf64308a3d7b5a0 | |
parent | d186096dd9dd26ebbd0d0f8bb699eee8f331250f (diff) | |
parent | 5a4550879d30d1897e9b62e4fb73e7392c4182b8 (diff) |
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts:
.qmake.conf
Change-Id: I12855e70c1444b9170f7ab55740bb50448e3dfb0
-rw-r--r-- | dist/changes-5.9.1 | 27 | ||||
-rw-r--r-- | examples/scxml/calculator-widgets/mainwindow.h | 2 | ||||
-rw-r--r-- | examples/scxml/ftpclient/ftpcontrolchannel.h | 2 | ||||
-rw-r--r-- | examples/scxml/ftpclient/ftpdatachannel.h | 2 | ||||
-rw-r--r-- | examples/scxml/mediaplayer-common/mainwindow.h | 2 | ||||
-rw-r--r-- | examples/scxml/pinball/mainwindow.h | 2 | ||||
-rw-r--r-- | examples/scxml/sudoku/mainwindow.cpp | 2 | ||||
-rw-r--r-- | examples/scxml/sudoku/mainwindow.h | 2 | ||||
-rw-r--r-- | examples/scxml/trafficlight-common/trafficlight.cpp | 7 | ||||
-rw-r--r-- | examples/scxml/trafficlight-common/trafficlight.h | 16 | ||||
-rw-r--r-- | examples/scxml/trafficlight-qml-simple/TrafficLight.qml | 2 | ||||
-rw-r--r-- | src/scxml/doc/qtscxml-instantiating-state-machines.qdoc | 4 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine.cpp | 28 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine_p.h | 4 | ||||
-rw-r--r-- | tests/auto/statemachine/historystate.scxml | 13 | ||||
-rw-r--r-- | tests/auto/statemachine/multipleinvokableservices.scxml | 48 | ||||
-rw-r--r-- | tests/auto/statemachine/tst_statemachine.cpp | 38 | ||||
-rw-r--r-- | tests/auto/statemachine/tst_statemachine.qrc | 2 |
18 files changed, 179 insertions, 24 deletions
diff --git a/dist/changes-5.9.1 b/dist/changes-5.9.1 new file mode 100644 index 0000000..a683cf9 --- /dev/null +++ b/dist/changes-5.9.1 @@ -0,0 +1,27 @@ +Qt 5.9.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + + - [QTBUG-59559] Fixed bundling of the module in static builds. + - [QTBUG-60938] Fixed usage of old (internal) API. + - Updated screenshots for Calculator, Mediaplayer and Soduko examples. + - [QTBUG-59568] Fixed a crash when handling the expr attribute. diff --git a/examples/scxml/calculator-widgets/mainwindow.h b/examples/scxml/calculator-widgets/mainwindow.h index c8d77f3..fe34271 100644 --- a/examples/scxml/calculator-widgets/mainwindow.h +++ b/examples/scxml/calculator-widgets/mainwindow.h @@ -66,7 +66,7 @@ class MainWindow : public QWidget Q_OBJECT public: - explicit MainWindow(QScxmlStateMachine *machine, QWidget *parent = 0); + explicit MainWindow(QScxmlStateMachine *machine, QWidget *parent = nullptr); ~MainWindow(); private: diff --git a/examples/scxml/ftpclient/ftpcontrolchannel.h b/examples/scxml/ftpclient/ftpcontrolchannel.h index ce8ad72..78a2486 100644 --- a/examples/scxml/ftpclient/ftpcontrolchannel.h +++ b/examples/scxml/ftpclient/ftpcontrolchannel.h @@ -59,7 +59,7 @@ class FtpControlChannel : public QObject { Q_OBJECT public: - explicit FtpControlChannel(QObject *parent = 0); + explicit FtpControlChannel(QObject *parent = nullptr); // Connect to an FTP server void connectToServer(const QString &server); diff --git a/examples/scxml/ftpclient/ftpdatachannel.h b/examples/scxml/ftpclient/ftpdatachannel.h index 2ca211c..097e7e7 100644 --- a/examples/scxml/ftpclient/ftpdatachannel.h +++ b/examples/scxml/ftpclient/ftpdatachannel.h @@ -60,7 +60,7 @@ class FtpDataChannel : public QObject { Q_OBJECT public: - explicit FtpDataChannel(QObject *parent = 0); + explicit FtpDataChannel(QObject *parent = nullptr); // Listen on a local address. void listen(const QHostAddress &address = QHostAddress::Any); diff --git a/examples/scxml/mediaplayer-common/mainwindow.h b/examples/scxml/mediaplayer-common/mainwindow.h index c89c269..9f26433 100644 --- a/examples/scxml/mediaplayer-common/mainwindow.h +++ b/examples/scxml/mediaplayer-common/mainwindow.h @@ -68,7 +68,7 @@ class MainWindow : public QWidget Q_OBJECT public: - explicit MainWindow(QScxmlStateMachine *stateMachine, QWidget *parent = 0); + explicit MainWindow(QScxmlStateMachine *stateMachine, QWidget *parent = nullptr); ~MainWindow(); private slots: diff --git a/examples/scxml/pinball/mainwindow.h b/examples/scxml/pinball/mainwindow.h index 57dffe7..daceb6e 100644 --- a/examples/scxml/pinball/mainwindow.h +++ b/examples/scxml/pinball/mainwindow.h @@ -66,7 +66,7 @@ class MainWindow : public QWidget Q_OBJECT public: - explicit MainWindow(QScxmlStateMachine *machine, QWidget *parent = 0); + explicit MainWindow(QScxmlStateMachine *machine, QWidget *parent = nullptr); ~MainWindow(); private: diff --git a/examples/scxml/sudoku/mainwindow.cpp b/examples/scxml/sudoku/mainwindow.cpp index 3a13010..7f7d99e 100644 --- a/examples/scxml/sudoku/mainwindow.cpp +++ b/examples/scxml/sudoku/mainwindow.cpp @@ -174,7 +174,7 @@ MainWindow::MainWindow(QScxmlStateMachine *machine, QWidget *parent) : foreach (const QFileInfo &sudokuFile, sudokuFiles) m_chooser->addItem(sudokuFile.completeBaseName(), sudokuFile.absoluteFilePath()); - connect(m_chooser, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + connect(m_chooser, QOverload<int>::of(&QComboBox::currentIndexChanged), [this] (int index) { const QString sudokuFile = m_chooser->itemData(index).toString(); const QVariantMap initValues = readSudoku(sudokuFile); diff --git a/examples/scxml/sudoku/mainwindow.h b/examples/scxml/sudoku/mainwindow.h index 99a0f1b..b37279e 100644 --- a/examples/scxml/sudoku/mainwindow.h +++ b/examples/scxml/sudoku/mainwindow.h @@ -66,7 +66,7 @@ class MainWindow : public QWidget Q_OBJECT public: - explicit MainWindow(QScxmlStateMachine *machine, QWidget *parent = 0); + explicit MainWindow(QScxmlStateMachine *machine, QWidget *parent = nullptr); ~MainWindow(); private: diff --git a/examples/scxml/trafficlight-common/trafficlight.cpp b/examples/scxml/trafficlight-common/trafficlight.cpp index 66ed289..8792ae2 100644 --- a/examples/scxml/trafficlight-common/trafficlight.cpp +++ b/examples/scxml/trafficlight-common/trafficlight.cpp @@ -55,7 +55,7 @@ class TrafficLightWidget : public QWidget { public: - TrafficLightWidget(QWidget *parent = 0) + TrafficLightWidget(QWidget *parent = nullptr) : QWidget(parent), m_background(QLatin1String(":/background.png")) { QVBoxLayout *vbox = new QVBoxLayout(this); @@ -76,14 +76,14 @@ public: LightWidget *greenLight() const { return m_green; } - virtual void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE + virtual void paintEvent(QPaintEvent *) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.drawImage(0, 0, m_background); } - virtual QSize sizeHint() const Q_DECL_OVERRIDE + virtual QSize sizeHint() const override { return m_background.size(); } @@ -133,7 +133,6 @@ void TrafficLight::toggleWorking(bool pause) LightWidget::LightWidget(const QString &image, QWidget *parent) : QWidget(parent) , m_image(image) - , m_on(false) {} bool LightWidget::isOn() const diff --git a/examples/scxml/trafficlight-common/trafficlight.h b/examples/scxml/trafficlight-common/trafficlight.h index f64feda..2639cb7 100644 --- a/examples/scxml/trafficlight-common/trafficlight.h +++ b/examples/scxml/trafficlight-common/trafficlight.h @@ -61,7 +61,7 @@ class TrafficLight : public QWidget Q_OBJECT public: - TrafficLight(QScxmlStateMachine *machine, QWidget *parent = 0); + TrafficLight(QScxmlStateMachine *machine, QWidget *parent = nullptr); private slots: void toggleWorking(bool pause); @@ -76,7 +76,7 @@ class LightWidget: public QWidget Q_PROPERTY(bool on READ isOn WRITE setOn) public: - LightWidget(const QString &image, QWidget *parent = 0); + LightWidget(const QString &image, QWidget *parent = nullptr); bool isOn() const; void setOn(bool on); @@ -85,23 +85,23 @@ public slots: void switchLight(bool onoff); protected: - virtual void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; - virtual QSize sizeHint() const Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent *) override; + virtual QSize sizeHint() const override; private: QImage m_image; - bool m_on; + bool m_on = false; }; class ButtonWidget : public QAbstractButton { Q_OBJECT public: - ButtonWidget(QWidget *parent = 0); + ButtonWidget(QWidget *parent = nullptr); protected: - virtual void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; - virtual QSize sizeHint() const Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent *) override; + virtual QSize sizeHint() const override; private: QImage m_playIcon; diff --git a/examples/scxml/trafficlight-qml-simple/TrafficLight.qml b/examples/scxml/trafficlight-qml-simple/TrafficLight.qml index da51ded..d2f9948 100644 --- a/examples/scxml/trafficlight-qml-simple/TrafficLight.qml +++ b/examples/scxml/trafficlight-qml-simple/TrafficLight.qml @@ -70,6 +70,7 @@ Window { Light { anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter color: "red" visible: stateMachine.red || stateMachine.redGoingGreen } @@ -82,6 +83,7 @@ Window { Light { anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter color: "green" visible: stateMachine.green } diff --git a/src/scxml/doc/qtscxml-instantiating-state-machines.qdoc b/src/scxml/doc/qtscxml-instantiating-state-machines.qdoc index 0737dff..37cff10 100644 --- a/src/scxml/doc/qtscxml-instantiating-state-machines.qdoc +++ b/src/scxml/doc/qtscxml-instantiating-state-machines.qdoc @@ -146,8 +146,8 @@ \code stateMachine->submitEvent("tap", QVariantMap({ - std::make_pair("artist", "Fatboy Slim"), - std::make_pair("title", "The Rockafeller Skank") + { "artist", "Fatboy Slim" }, + { "title", "The Rockafeller Skank" } }); \endcode diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp index e57630f..cc190fb 100644 --- a/src/scxml/qscxmlstatemachine.cpp +++ b/src/scxml/qscxmlstatemachine.cpp @@ -731,7 +731,9 @@ void QScxmlStateMachinePrivate::emitStateActive(int stateIndex, bool active) { Q_Q(QScxmlStateMachine); void *args[] = { Q_NULLPTR, const_cast<void*>(reinterpret_cast<const void*>(&active)) }; - QMetaObject::activate(q, m_metaObject, stateIndex, args); + const int signalIndex = m_stateIndexToSignalIndex.value(stateIndex, -1); + if (signalIndex >= 0) + QMetaObject::activate(q, m_metaObject, signalIndex, args); } void QScxmlStateMachinePrivate::emitInvokedServicesChanged() @@ -755,6 +757,26 @@ void QScxmlStateMachinePrivate::attach(QScxmlStateMachineInfo *info) info, &QScxmlStateMachineInfo::transitionsTriggered); } +void QScxmlStateMachinePrivate::updateMetaCache() +{ + m_stateIndexToSignalIndex.clear(); + + if (!m_tableData) + return; + + if (!m_stateTable) + return; + + int signalIndex = 0; + for (int i = 0; i < m_stateTable->stateCount; ++i) { + const auto &s = m_stateTable->state(i); + if (!s.isHistoryState() && s.type != StateTable::State::Invalid) { + m_stateIndexToSignalIndex.insert(i, signalIndex); + ++signalIndex; + } + } +} + QStringList QScxmlStateMachinePrivate::stateNames(const std::vector<int> &stateIndexes) const { QStringList names; @@ -1767,6 +1789,8 @@ void QScxmlStateMachine::setTableData(QScxmlTableData *tableData) == QScxmlExecutableContent::StateTable::terminator); } + d->updateMetaCache(); + emit tableDataChanged(tableData); } @@ -2174,7 +2198,7 @@ bool QScxmlStateMachine::isDispatchableTarget(const QString &target) const if (target.startsWith(QStringLiteral("#_"))) { QStringRef targetId = target.midRef(2); for (auto invokedService : d->m_invokedServices) { - if (invokedService.service->id() == targetId) + if (invokedService.service && invokedService.service->id() == targetId) return true; } } diff --git a/src/scxml/qscxmlstatemachine_p.h b/src/scxml/qscxmlstatemachine_p.h index 129ef61..a2926a8 100644 --- a/src/scxml/qscxmlstatemachine_p.h +++ b/src/scxml/qscxmlstatemachine_p.h @@ -282,6 +282,8 @@ public: void attach(QScxmlStateMachineInfo *info); const OrderedSet &configuration() const { return m_configuration; } + void updateMetaCache(); + private: QStringList stateNames(const std::vector<int> &stateIndexes) const; std::vector<int> historyStates(int stateIdx) const; @@ -378,6 +380,8 @@ private: bool isPaused() const { return m_runningState == Paused; } QScxmlInternal::StateMachineInfoProxy *m_infoSignalProxy; + + QHash<int, int> m_stateIndexToSignalIndex; }; QT_END_NAMESPACE diff --git a/tests/auto/statemachine/historystate.scxml b/tests/auto/statemachine/historystate.scxml new file mode 100644 index 0000000..4b3a5e4 --- /dev/null +++ b/tests/auto/statemachine/historystate.scxml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="HistoryState"> + <state id="Working"> + <state id="State1"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + </state> + <history type="shallow" id="HistoryState"/> + <transition type="external" event="timeout" target="State2"/> + </state> + <state id="State2"/> +</scxml> diff --git a/tests/auto/statemachine/multipleinvokableservices.scxml b/tests/auto/statemachine/multipleinvokableservices.scxml new file mode 100644 index 0000000..8b20695 --- /dev/null +++ b/tests/auto/statemachine/multipleinvokableservices.scxml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="MultipleInvokableServices.scxml" datamodel="ecmascript" initial="TopState"> + <datamodel> + <data id="Var"/> + </datamodel> + <state id="TopState"> + <state id="State1"> + <invoke id="invoke1"> + <content> + <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="anywhere"> + <state id="foo"> + <onentry> + <send target="#_parent" event="running1"/> + </onentry> + <transition event="toChild"> + <send target="#_parent" event="received1"/> + </transition> + </state> + </scxml> + </content> + </invoke> + </state> + <state id="State2"> + <invoke id="invoke2"> + <content> + <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="anywhere"> + <state id="foo"> + <onentry> + <send target="#_parent" event="running2"/> + </onentry> + </state> + </scxml> + </content> + </invoke> + </state> + <transition event="running1"> + <send event="toChild" target="#_invoke1"/> + </transition> + <transition event="received1"> + <assign location="Var" expr="1"/> + <send event="toChild" target="#_invoke2"/> + </transition> + <transition event="error.communication" cond="Var == 1" target="success"/> + <transition event="*" target="failure"/> + </state> + <final id="success"/> + <final id="failure"/> +</scxml> diff --git a/tests/auto/statemachine/tst_statemachine.cpp b/tests/auto/statemachine/tst_statemachine.cpp index ed1f424..4575737 100644 --- a/tests/auto/statemachine/tst_statemachine.cpp +++ b/tests/auto/statemachine/tst_statemachine.cpp @@ -48,6 +48,7 @@ private Q_SLOTS: void activeStateNames_data(); void activeStateNames(); void connections(); + void historyState(); void onExit(); void eventOccurred(); @@ -55,6 +56,8 @@ private Q_SLOTS: void running(); void invokeStateMachine(); + + void multipleInvokableServices(); // QTBUG-61484 }; void tst_StateMachine::stateNames_data() @@ -251,6 +254,24 @@ void tst_StateMachine::connections() #endif } +void tst_StateMachine::historyState() +{ + QScopedPointer<QScxmlStateMachine> stateMachine( + QScxmlStateMachine::fromFile(QString(":/tst_statemachine/historystate.scxml"))); + QVERIFY(!stateMachine.isNull()); + + bool state2Reached = false; + QMetaObject::Connection state2Connection = stateMachine->connectToState("State2", + [&state2Reached](bool enabled) { + state2Reached = state2Reached || enabled; + }); + QVERIFY(state2Connection); + + stateMachine->start(); + + QTRY_VERIFY(state2Reached); +} + void tst_StateMachine::onExit() { #if defined(__cpp_return_type_deduction) && __cpp_return_type_deduction == 201304 @@ -365,7 +386,6 @@ void tst_StateMachine::doneDotStateEvent() finishedSpy.wait(5000); QCOMPARE(finishedSpy.count(), 1); QCOMPARE(stateMachine->activeStateNames(true).size(), 1); - qDebug() << stateMachine->activeStateNames(true); QVERIFY(stateMachine->activeStateNames(true).contains(QLatin1String("success"))); } @@ -409,6 +429,22 @@ void tst_StateMachine::invokeStateMachine() QTRY_VERIFY(subMachine->activeStateNames().contains("here")); } +void tst_StateMachine::multipleInvokableServices() +{ + QScopedPointer<QScxmlStateMachine> stateMachine( + QScxmlStateMachine::fromFile(QString(":/tst_statemachine/multipleinvokableservices.scxml"))); + QVERIFY(!stateMachine.isNull()); + + QSignalSpy finishedSpy(stateMachine.data(), SIGNAL(finished())); + stateMachine->start(); + QCOMPARE(stateMachine->isRunning(), true); + + finishedSpy.wait(5000); + QCOMPARE(finishedSpy.count(), 1); + QCOMPARE(stateMachine->activeStateNames(true).size(), 1); + QVERIFY(stateMachine->activeStateNames(true).contains(QLatin1String("success"))); +} + QTEST_MAIN(tst_StateMachine) #include "tst_statemachine.moc" diff --git a/tests/auto/statemachine/tst_statemachine.qrc b/tests/auto/statemachine/tst_statemachine.qrc index c31fe4c..0bd68ff 100644 --- a/tests/auto/statemachine/tst_statemachine.qrc +++ b/tests/auto/statemachine/tst_statemachine.qrc @@ -6,5 +6,7 @@ <file>ids1.scxml</file> <file>stateDotDoneEvent.scxml</file> <file>invoke.scxml</file> + <file>historystate.scxml</file> + <file>multipleinvokableservices.scxml</file> </qresource> </RCC> |