diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a7f7a4c..678e867 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,8 +1,8 @@ add_executable(pkpassviewer pkpassviewer.cpp pkpassviewer.qrc) target_link_libraries(pkpassviewer itinerary) add_executable(departurequery departurequery.cpp departurequery.qrc) -target_link_libraries(departurequery KPublicTransport Qt5::Quick) +target_link_libraries(departurequery KPublicTransport Qt5::Quick Qt5::Widgets) add_executable(journeyquery journeyquery.cpp journeyquery.qrc) -target_link_libraries(journeyquery KPublicTransport Qt5::Quick) +target_link_libraries(journeyquery KPublicTransport Qt5::Quick Qt5::Widgets) diff --git a/tests/departurequery.cpp b/tests/departurequery.cpp index 5bef610..918525f 100644 --- a/tests/departurequery.cpp +++ b/tests/departurequery.cpp @@ -1,116 +1,116 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include +#include #include #include -#include #include #include using namespace KPublicTransport; class QueryManager : public QObject { Q_OBJECT Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged) Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) public: QueryManager() { ptMgr.setNetworkAccessManager(&nam); } Q_INVOKABLE void queryDeparture(double fromLat, double fromLon, const QString &id) { engine->rootContext()->setContextProperty(QStringLiteral("_departures"), QVariantList()); m_loading = true; emit loadingChanged(); m_errorMsg.clear(); emit errorMessageChanged(); Location from; from.setCoordinate(fromLat, fromLon); from.setIdentifier(QLatin1String("hafasId"), id); // ### temporary, until we have other look-up methods auto reply = ptMgr.queryDeparture(DepartureRequest(from)); QObject::connect(reply, &DepartureReply::finished, [reply, this]{ m_loading = false; emit loadingChanged(); if (reply->error() == DepartureReply::NoError) { const auto res = reply->departures(); QVariantList l; l.reserve(res.size()); std::transform(res.begin(), res.end(), std::back_inserter(l), [](const auto &journey) { return QVariant::fromValue(journey); }); engine->rootContext()->setContextProperty(QStringLiteral("_departures"), l); for (const auto &departure : res) { qDebug() << departure.stopPoint().name() << departure.route().line().name() << departure.route().direction() << departure.scheduledTime(); } } else { m_errorMsg = reply->errorString(); emit errorMessageChanged(); } }); } bool loading() const { return m_loading; } QString errorMessage() const { return m_errorMsg; } QQmlEngine *engine = nullptr; signals: void loadingChanged(); void errorMessageChanged(); private: QNetworkAccessManager nam; Manager ptMgr; QString m_errorMsg; bool m_loading = false; }; int main(int argc, char **argv) { QCoreApplication::setApplicationName(QStringLiteral("departurequery")); QCoreApplication::setOrganizationName(QStringLiteral("KDE")); QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - QGuiApplication app(argc, argv); + QApplication app(argc, argv); qmlRegisterUncreatableType("org.kde.kpublictransport", 1, 0, "Line", {}); QueryManager mgr; QQmlApplicationEngine engine; mgr.engine = &engine; engine.rootContext()->setContextProperty(QStringLiteral("_queryMgr"), &mgr); engine.load(QStringLiteral("qrc:/departurequery.qml")); return app.exec(); } #include "departurequery.moc" diff --git a/tests/departurequery.qml b/tests/departurequery.qml index d255406..c225c6b 100644 --- a/tests/departurequery.qml +++ b/tests/departurequery.qml @@ -1,115 +1,116 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.5 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.1 as QQC2 import org.kde.kirigami 2.0 as Kirigami import org.kde.kpublictransport 1.0 Kirigami.ApplicationWindow { title: "Departure Query" reachableModeEnabled: false width: 480 height: 720 pageStack.initialPage: departureQueryPage ListModel { id: exampleModel ListElement { name: "CDG"; lat: 2.57110; lon: 49.00406; hafasId: "8700147" } // IBNR for DB: 8704997 ListElement { name: "Paris Gare de Lyon"; lat: 2.37708; lon: 48.84388; hafasId: "8768600" } ListElement { name: "ZRH"; lat: 8.56275; lon: 47.45050; hafasId: "8503016" } ListElement { name: "Randa"; lat: 7.78315; lon: 46.09901; hafasId: "8501687" } ListElement { name: "Brussels Gare de Midi"; lat: 4.33620; lon: 50.83588; hafasId: "8814001" } ListElement { name: "Fosdem"; lat: 4.38116; lon: 50.81360 } ListElement { name: "VIE"; lat: 16.56312; lon: 48.12083; hafasId: "008100353" } ListElement { name: "Akademy 2018 Accomodation"; lat: 16.37859; lon: 48.18282 } ListElement { name: "Akademy 2018 BBQ"; lat: 16.43191; lon: 48.21612 } ListElement { name: "LEI"; lat: -2.37251; lon: 36.84774; } ListElement { name: "Akademy 2017 Accomodation"; lat: -2.44788; lon: 36.83731 } ListElement { name: "Akademy 2017 Venue"; lat: -2.40377; lon: 36.82784 } ListElement { name: "TXL"; lat: 13.29281; lon: 52.55420; } ListElement { name: "Akademy 2016 Venue"; lat: 13.41644; lon: 52.52068 } ListElement { name: "SXF"; lat: 13.51870; lon: 52.38841; hafasId: "900260005" } ListElement { name: "Brno central station"; lat: 16.61287; lon: 49.19069 } ListElement { name: "Akademy 2014 venue"; lat: 16.57564; lon: 49.22462 } } Component { id: departureQueryPage Kirigami.Page { ColumnLayout { anchors.fill: parent QQC2.ComboBox { id: exampleSelector Layout.fillWidth: true model: exampleModel textRole: "name" onCurrentIndexChanged: { var obj = exampleModel.get(currentIndex); _queryMgr.queryDeparture(obj.lat, obj.lon, obj.hafasId); } } ListView { Layout.fillHeight: true Layout.fillWidth: true model: _departures + spacing: Kirigami.Units.smallSpacing delegate: Item { implicitHeight: delegateLayout.implicitHeight implicitWidth: delegateLayout.implicitWidth ColumnLayout { id: delegateLayout - Text { + QQC2.Label { text: "From: " + modelData.stopPoint.name } - Text { + QQC2.Label { text: "Line: " + modelData.route.line.modeString + " " + modelData.route.line.name + " to " + modelData.route.direction } - Text { + QQC2.Label { text: "Time: " + modelData.scheduledTime } } Rectangle { anchors.left: parent.left anchors.leftMargin: -8 height: parent.height width: 4 color: modelData.route.line.color } } QQC2.BusyIndicator { anchors.centerIn: parent running: _queryMgr.loading } QQC2.Label { anchors.centerIn: parent width: parent.width text: _queryMgr.errorMessage color: Kirigami.Theme.negativeTextColor wrapMode: Text.Wrap } } } } } } diff --git a/tests/journeyquery.cpp b/tests/journeyquery.cpp index 54ca75b..ab32b02 100644 --- a/tests/journeyquery.cpp +++ b/tests/journeyquery.cpp @@ -1,125 +1,125 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include +#include #include #include -#include #include #include using namespace KPublicTransport; class QueryManager : public QObject { Q_OBJECT Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged) Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) public: QueryManager() { ptMgr.setNetworkAccessManager(&nam); } Q_INVOKABLE void findJourney(double fromLat, double fromLon, double toLat, double toLon) { engine->rootContext()->setContextProperty(QStringLiteral("_journeys"), QVariantList()); m_loading = true; emit loadingChanged(); m_errorMsg.clear(); emit errorMessageChanged(); Location from; from.setCoordinate(fromLat, fromLon); Location to; to.setCoordinate(toLat, toLon); auto reply = ptMgr.queryJourney({from, to}); QObject::connect(reply, &JourneyReply::finished, [reply, this]{ m_loading = false; emit loadingChanged(); if (reply->error() == JourneyReply::NoError) { const auto res = reply->journeys(); QVariantList l; l.reserve(res.size()); std::transform(res.begin(), res.end(), std::back_inserter(l), [](const auto &journey) { return QVariant::fromValue(journey); }); engine->rootContext()->setContextProperty(QStringLiteral("_journeys"), l); for (const auto &journey : res) { qDebug() << journey.sections().size(); for (const auto §ion : journey.sections()) { qDebug() << " From" << section.from().name() << section.departureTime(); qDebug() << " Mode" << section.mode() << section.route().line().name() << section.route().direction() << section.route().line().modeString(); qDebug() << " To" << section.to().name() << section.arrivalTime(); } } } else { m_errorMsg = reply->errorString(); emit errorMessageChanged(); } }); } bool loading() const { return m_loading; } QString errorMessage() const { return m_errorMsg; } QQmlEngine *engine = nullptr; signals: void loadingChanged(); void errorMessageChanged(); private: QNetworkAccessManager nam; Manager ptMgr; QString m_errorMsg; bool m_loading = false; }; int main(int argc, char **argv) { QCoreApplication::setApplicationName(QStringLiteral("journeyquery")); QCoreApplication::setOrganizationName(QStringLiteral("KDE")); QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - QGuiApplication app(argc, argv); + QApplication app(argc, argv); qmlRegisterUncreatableType("org.kde.kpublictransport", 1, 0, "Line", {}); qmlRegisterUncreatableType("org.kde.kpublictransport", 1, 0, "JourneySection", {}); QueryManager mgr; QQmlApplicationEngine engine; mgr.engine = &engine; engine.rootContext()->setContextProperty(QStringLiteral("_queryMgr"), &mgr); engine.load(QStringLiteral("qrc:/journeyquery.qml")); return app.exec(); } #include "journeyquery.moc" diff --git a/tests/journeyquery.qml b/tests/journeyquery.qml index 84835ae..a1c2885 100644 --- a/tests/journeyquery.qml +++ b/tests/journeyquery.qml @@ -1,194 +1,194 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.5 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.1 as QQC2 import org.kde.kirigami 2.0 as Kirigami import org.kde.kpublictransport 1.0 Kirigami.ApplicationWindow { title: "Journey Query" reachableModeEnabled: false width: 480 height: 720 pageStack.initialPage: journyQueryPage ListModel { id: exampleModel ListElement { name: "CDG -> Gare de Lyon" fromLat: 2.57110 fromLon: 49.00406 toLat: 2.37708 toLon: 48.84388 } ListElement { name: "ZRH -> Randa" fromLat: 8.56275 fromLon: 47.45050 toLat: 7.78315 toLon: 46.09901 } ListElement { name: "Gare de Midi -> Fosdem" fromLat: 4.33620 fromLon: 50.83588 toLat: 4.38116 toLon: 50.81360 } ListElement { name: "VIE -> Akademy 2018 Accomodation" fromLat: 16.56312 fromLon: 48.12083 toLat: 16.37859 toLon: 48.18282 } ListElement { name: "Akademy 2018 BBQ -> Accomodation" fromLat: 16.43191 fromLon: 48.21612 toLat: 16.37859 toLon: 48.18282 } ListElement { name: "LEI -> Akademy 2017 Accomodation" fromLat: -2.37251 fromLon: 36.84774 toLat: -2.44788 toLon: 36.83731 } ListElement { name: "Akademy 2017 Venue -> Accomodation" fromLat: -2.40377 fromLon: 36.82784 toLat: -2.44788 toLon: 36.83731 } ListElement { name: "TXL -> Akademy 2016" fromLat: 13.29281 fromLon: 52.55420 toLat: 13.41644 toLon: 52.52068 } ListElement { name: "SXF -> Akademy 2016" fromLat: 13.51870 fromLon: 52.38841 toLat: 13.41644 toLon: 52.52068 } ListElement { name: "Brno central station -> Akademy 2014 venue" fromLat: 16.61287 fromLon: 49.19069 toLat: 16.57564 toLon: 49.22462 } } function displayDuration(dur) { if (dur < 60) return "<1min"; if (dur < 3600) return Math.floor(dur/60) + "min"; return Math.floor(dur/3600) + ":" + Math.floor((dur % 3600)/60) } Component { id: journyQueryPage Kirigami.Page { ColumnLayout { anchors.fill: parent QQC2.ComboBox { id: exampleSelector Layout.fillWidth: true model: exampleModel textRole: "name" onCurrentIndexChanged: { var obj = exampleModel.get(currentIndex); _queryMgr.findJourney(obj.fromLat, obj.fromLon, obj.toLat, obj.toLon); } } QQC2.ComboBox { id: journeySelector Layout.fillWidth: true model: _journeys } ListView { Layout.fillHeight: true Layout.fillWidth: true model: _journeys[journeySelector.currentIndex].sections delegate: Item { implicitHeight: delegateLayout.implicitHeight implicitWidth: delegateLayout.implicitWidth ColumnLayout { id: delegateLayout - Text { + QQC2.Label { text: "From: " + modelData.from.name visible: index == 0 } - Text { + QQC2.Label { text: { switch (modelData.mode) { case JourneySection.PublicTransport: return modelData.route.line.modeString + " " + modelData.route.line.name + " " + displayDuration(modelData.duration); case JourneySection.Walking: return "Walk " + displayDuration(modelData.duration) case JourneySection.Transfer: return "Transfer " + displayDuration(modelData.duration) case JourneySection.Waiting: return "Wait " + displayDuration(modelData.duration) return "???"; }} } - Text { + QQC2.Label { text: "To: " + modelData.to.name } } Rectangle { anchors.left: parent.left anchors.leftMargin: -8 height: parent.height width: 4 color: modelData.route.line.color } } QQC2.BusyIndicator { anchors.centerIn: parent running: _queryMgr.loading } QQC2.Label { anchors.centerIn: parent width: parent.width text: _queryMgr.errorMessage color: Kirigami.Theme.negativeTextColor wrapMode: Text.Wrap } } } } } }