From 992d624c1861e67ca482a47f13e99fd8c97e7379 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sat, 21 Sep 2019 23:33:15 +0200 Subject: [PATCH] Ref T731, moved AFV station model and client to BlackCore::Afv * the QML map can also be used in dialog * ATC station list also can be used in BlackCore --- samples/afvclient/afvclient.pro | 2 - samples/afvclient/afvmapreader.cpp | 91 -------------- samples/afvclient/afvmapreader.h | 39 ------ samples/afvclient/main.cpp | 10 +- samples/afvclient/models/atcstationmodel.cpp | 118 ----------------- samples/afvclient/models/atcstationmodel.h | 94 -------------- src/blackcore/afv/clients/afvclient.h | 1 - src/blackcore/afv/model/afvmapreader.cpp | 99 +++++++++++++++ src/blackcore/afv/model/afvmapreader.h | 49 ++++++++ src/blackcore/afv/model/atcstationmodel.cpp | 126 +++++++++++++++++++ src/blackcore/afv/model/atcstationmodel.h | 105 ++++++++++++++++ src/blackcore/blackcore.pro | 2 + src/blackgui/blackgui.pro | 2 +- src/blackgui/components/afvmapdialog.cpp | 14 +++ src/blackgui/components/afvmapdialog.h | 10 ++ src/swiftguistandard/swiftguistd.cpp | 1 + 16 files changed, 413 insertions(+), 350 deletions(-) delete mode 100644 samples/afvclient/afvmapreader.cpp delete mode 100644 samples/afvclient/afvmapreader.h delete mode 100644 samples/afvclient/models/atcstationmodel.cpp delete mode 100644 samples/afvclient/models/atcstationmodel.h create mode 100644 src/blackcore/afv/model/afvmapreader.cpp create mode 100644 src/blackcore/afv/model/afvmapreader.h create mode 100644 src/blackcore/afv/model/atcstationmodel.cpp create mode 100644 src/blackcore/afv/model/atcstationmodel.h diff --git a/samples/afvclient/afvclient.pro b/samples/afvclient/afvclient.pro index e098d75ed..09b81026d 100644 --- a/samples/afvclient/afvclient.pro +++ b/samples/afvclient/afvclient.pro @@ -24,9 +24,7 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 HEADERS += *.h -HEADERS += $$PWD/models/*.h SOURCES += *.cpp -SOURCES += $$PWD/models/*.cpp DEFINES += _USE_MATH_DEFINES RESOURCES += qml/qml.qrc diff --git a/samples/afvclient/afvmapreader.cpp b/samples/afvclient/afvmapreader.cpp deleted file mode 100644 index 5b8d501f8..000000000 --- a/samples/afvclient/afvmapreader.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "afvmapreader.h" -#include "blackcore/application.h" -#include "dto.h" -#include -#include -#include -#include -#include - -using namespace BlackCore::Afv; - -AFVMapReader::AFVMapReader(QObject *parent) : QObject(parent) -{ - m_model = new CSampleAtcStationModel(this); - m_timer = new QTimer(this); - connect(m_timer, &QTimer::timeout, this, &AFVMapReader::updateFromMap); - m_timer->start(3000); -} - -void AFVMapReader::updateFromMap() -{ - if (! sApp) { return; } - - QEventLoop loop; - connect(sApp->getNetworkAccessManager(), &QNetworkAccessManager::finished, &loop, &QEventLoop::quit); - QNetworkReply *reply = sApp->getNetworkAccessManager()->get(QNetworkRequest(QUrl("https://afv-map.vatsim.net/atis-map-data"))); - while (! reply->isFinished()) { loop.exec(); } - QByteArray jsonData = reply->readAll(); - reply->deleteLater(); - - if (jsonData.isEmpty()) { return; } - - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); - if (jsonDoc.isObject()) - { - QJsonObject rootObject = jsonDoc.object(); - QVector transceivers; - - if (rootObject.contains("controllers")) - { - QJsonObject otherObject = rootObject.value("controllers").toObject(); - for (auto it = otherObject.begin(); it != otherObject.end(); ++it) - { - QString callsign = it.key(); - if (it.value().isObject()) - { - QJsonObject stationObject = it.value().toObject(); - if (stationObject.contains("transceivers")) - { - QJsonArray txArray = stationObject.value("transceivers").toArray(); - for (auto jt = txArray.begin(); jt != txArray.end(); ++jt) - { - TransceiverDto transceiver = TransceiverDto::fromJson(jt->toObject()); - transceivers.push_back( { callsign, transceiver} ); - } - } - } - } - } - - if (rootObject.contains("other") && rootObject.value("other").isObject()) - { - QJsonObject otherObject = rootObject.value("other").toObject(); - for (auto it = otherObject.begin(); it != otherObject.end(); ++it) - { - QString callsign = it.key(); - if (it.value().isObject()) - { - QJsonObject stationObject = it.value().toObject(); - if (stationObject.contains("transceivers")) - { - QJsonArray txArray = stationObject.value("transceivers").toArray(); - for (auto jt = txArray.begin(); jt != txArray.end(); ++jt) - { - TransceiverDto transceiver = TransceiverDto::fromJson(jt->toObject()); - transceivers.push_back( { callsign, transceiver} ); - } - } - } - } - } - - if (transceivers.isEmpty()) { return; } - transceivers.erase(std::remove_if(transceivers.begin(), transceivers.end(), [this](const CSampleAtcStation &s) - { - return s.callsign() == m_callsign; - }), - transceivers.end()); - m_model->updateAtcStations(transceivers); - } -} diff --git a/samples/afvclient/afvmapreader.h b/samples/afvclient/afvmapreader.h deleted file mode 100644 index 457510dfc..000000000 --- a/samples/afvclient/afvmapreader.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2019 - * swift Project Community / Contributors - * - * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level - * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, - * or distributed except according to the terms contained in the LICENSE file. - */ - -#ifndef BLACKSAMPLE_AFVMAPREADER_H -#define BLACKSAMPLE_AFVMAPREADER_H - -#include "models/atcstationmodel.h" - -#include -#include - -//! Map reader -class AFVMapReader : public QObject -{ - Q_OBJECT - Q_PROPERTY(CSampleAtcStationModel* atcStationModel READ getAtcStationModel CONSTANT) - -public: - //! Ctor - AFVMapReader(QObject *parent = nullptr); - - Q_INVOKABLE void setOwnCallsign(const QString &callsign) { m_callsign = callsign; } - - void updateFromMap(); - - CSampleAtcStationModel *getAtcStationModel() { return m_model; } - -private: - CSampleAtcStationModel *m_model = nullptr; - QTimer *m_timer = nullptr; - QString m_callsign; -}; - -#endif // guard diff --git a/samples/afvclient/main.cpp b/samples/afvclient/main.cpp index 3ef628d60..f976c952a 100644 --- a/samples/afvclient/main.cpp +++ b/samples/afvclient/main.cpp @@ -1,8 +1,9 @@ // #include "voiceclientui.h" -#include "models/atcstationmodel.h" -#include "clients/afvclient.h" -#include "afvmapreader.h" +#include "blackcore/afv/model/atcstationmodel.h" +#include "blackcore/afv/model/afvmapreader.h" +#include "blackcore/afv/clients/afvclient.h" + #include "blackcore/application.h" #include @@ -12,6 +13,7 @@ #include using namespace BlackCore::Afv::Clients; +using namespace BlackCore::Afv::Model; int main(int argc, char *argv[]) { @@ -20,7 +22,7 @@ int main(int argc, char *argv[]) BlackCore::CApplication a("sampleafvclient", BlackMisc::CApplicationInfo::Sample); - AFVMapReader *afvMapReader = new AFVMapReader(&a); + CAfvMapReader *afvMapReader = new CAfvMapReader(&a); afvMapReader->updateFromMap(); CAfvClient voiceClient("https://voice1.vatsim.uk"); diff --git a/samples/afvclient/models/atcstationmodel.cpp b/samples/afvclient/models/atcstationmodel.cpp deleted file mode 100644 index a35ae6f6c..000000000 --- a/samples/afvclient/models/atcstationmodel.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright (C) 2019 - * swift Project Community / Contributors - * - * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level - * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, - * or distributed except according to the terms contained in the LICENSE file. - */ - -#include "atcstationmodel.h" -#include "dto.h" -#include - -using namespace BlackCore::Afv; - -CSampleAtcStation::CSampleAtcStation(const QString &callsign, const TransceiverDto &transceiver) : - m_callsign(callsign), - m_transceiver(transceiver) -{ } - -double CSampleAtcStation::latitude() const -{ - return m_transceiver.LatDeg; -} - -double CSampleAtcStation::longitude() const -{ - return m_transceiver.LonDeg; -} - -quint32 CSampleAtcStation::frequency() const -{ - return m_transceiver.frequency; -} - -QString CSampleAtcStation::formattedFrequency() const -{ - return QString::number(m_transceiver.frequency / 1000000.0, 'f', 3); -} - -double CSampleAtcStation::radioDistanceM() const -{ - double sqrtAltM = qSqrt(m_transceiver.HeightMslM); - const double radioFactor = 4193.18014745372; - - return radioFactor * sqrtAltM; -} - -CSampleAtcStationModel::CSampleAtcStationModel(QObject *parent) : - QAbstractListModel(parent) -{ } - -CSampleAtcStationModel::~CSampleAtcStationModel() {} - -void CSampleAtcStationModel::updateAtcStations(const QVector &atcStations) -{ - // Add stations which didn't exist yet - for (const auto &station : atcStations) - { - if (! m_atcStations.contains(station)) { addStation(station); } - } - - // Remove all stations which are no longer there - for (int i = m_atcStations.size() - 1; i >= 0; i--) - { - CSampleAtcStation &station = m_atcStations[i]; - if (! m_atcStations.contains(station)) - { - removeStationAtPosition(i); - } - } -} - -void CSampleAtcStationModel::addStation(const CSampleAtcStation &atcStation) -{ - beginInsertRows(QModelIndex(), rowCount(), rowCount()); - m_atcStations << atcStation; - endInsertRows(); -} - -void CSampleAtcStationModel::removeStationAtPosition(int i) -{ - beginRemoveRows(QModelIndex(), i, i); - m_atcStations.removeAt(i); - endRemoveRows(); -} - -int CSampleAtcStationModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return m_atcStations.count(); -} - -QVariant CSampleAtcStationModel::data(const QModelIndex &index, int role) const -{ - if (index.row() < 0 || index.row() >= m_atcStations.count()) - return QVariant(); - - const CSampleAtcStation &atcStation = m_atcStations[index.row()]; - if (role == CallsignRole) return atcStation.callsign(); - if (role == LatitudeRole) return atcStation.latitude(); - if (role == LongitudeRole) return atcStation.longitude(); - if (role == RadioDistanceRole) return atcStation.radioDistanceM(); - if (role == FrequencyRole) return atcStation.formattedFrequency(); - if (role == FrequencyKhzRole) return atcStation.frequency() / 1000; - return QVariant(); -} - -QHash CSampleAtcStationModel::roleNames() const -{ - QHash roles; - roles[CallsignRole] = "callsign"; - roles[LatitudeRole] = "latitude"; - roles[LongitudeRole] = "longitude"; - roles[RadioDistanceRole] = "radioDistanceM"; - roles[FrequencyRole] = "frequencyAsString"; - roles[FrequencyKhzRole] = "frequencyKhz"; - return roles; -} diff --git a/samples/afvclient/models/atcstationmodel.h b/samples/afvclient/models/atcstationmodel.h deleted file mode 100644 index b0039730c..000000000 --- a/samples/afvclient/models/atcstationmodel.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (C) 2019 - * swift Project Community / Contributors - * - * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level - * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, - * or distributed except according to the terms contained in the LICENSE file. - */ - -#ifndef BLACKSAMPLE_MODELS_ATCSTATIONMODEL_H -#define BLACKSAMPLE_MODELS_ATCSTATIONMODEL_H - -#include "dto.h" -#include -#include -#include -#include -#include -#include - -//! Sample ATC station -class CSampleAtcStation -{ -public: - //! Ctor - CSampleAtcStation() {} - - //! Ctor - CSampleAtcStation(const QString &callsign, const BlackCore::Afv::TransceiverDto &transceiver); - - //! Getter @{ - const QString &callsign() const { return m_callsign; } - QString formattedFrequency() const; - double latitude() const; - double longitude() const; - double radioDistanceM() const; - quint32 frequency() const; - //! @} - -private: - QString m_callsign; - BlackCore::Afv::TransceiverDto m_transceiver; -}; - -inline bool operator==(const CSampleAtcStation &lhs, const CSampleAtcStation &rhs) -{ - return lhs.callsign() == rhs.callsign() && - qFuzzyCompare(lhs.latitude(), rhs.latitude()) && - qFuzzyCompare(lhs.longitude(), rhs.longitude()); -} - -//! Sample list model -class CSampleAtcStationModel : public QAbstractListModel -{ - Q_OBJECT - -public: - //! Roles for model - enum AtcStationRoles - { - CallsignRole = Qt::UserRole + 1, - LatitudeRole, - LongitudeRole, - RadioDistanceRole, - FrequencyRole, - FrequencyKhzRole - }; - - //! Ctor - CSampleAtcStationModel(QObject *parent = nullptr); - - //! Dtor - virtual ~CSampleAtcStationModel() override; - - //! Update the stations - void updateAtcStations(const QVector &atcStations); - - //! copydoc QAbstractListModel::rowCount - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - //! copydoc QAbstractListModel::data - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -protected: - //! copydoc QAbstractListModel::roleNames - QHash roleNames() const override; - -private: - void addStation(const CSampleAtcStation &atcStation); - void removeStationAtPosition(int i); - - QList m_atcStations; -}; - -#endif // guard diff --git a/src/blackcore/afv/clients/afvclient.h b/src/blackcore/afv/clients/afvclient.h index fed5915f0..6b9ffa8b8 100644 --- a/src/blackcore/afv/clients/afvclient.h +++ b/src/blackcore/afv/clients/afvclient.h @@ -88,7 +88,6 @@ namespace BlackCore void setTransmittingTransceivers(const QVector &transceivers); Q_INVOKABLE void setPtt(bool active); - Q_INVOKABLE void setLoopBack(bool on) { m_loopbackOn = on; } //! Input volume in DB, +-18DB @{ diff --git a/src/blackcore/afv/model/afvmapreader.cpp b/src/blackcore/afv/model/afvmapreader.cpp new file mode 100644 index 000000000..d0bcf1214 --- /dev/null +++ b/src/blackcore/afv/model/afvmapreader.cpp @@ -0,0 +1,99 @@ +#include "afvmapreader.h" +#include "blackcore/application.h" +#include "blackcore/afv/dto.h" +#include +#include +#include +#include +#include + + +namespace BlackCore +{ + namespace Afv + { + namespace Model + { + CAfvMapReader::CAfvMapReader(QObject *parent) : QObject(parent) + { + m_model = new CSampleAtcStationModel(this); + m_timer = new QTimer(this); + connect(m_timer, &QTimer::timeout, this, &CAfvMapReader::updateFromMap); + m_timer->start(3000); + } + + void CAfvMapReader::updateFromMap() + { + if (!sApp || sApp->isShuttingDown()) { return; } + + QEventLoop loop; + connect(sApp->getNetworkAccessManager(), &QNetworkAccessManager::finished, &loop, &QEventLoop::quit); + QNetworkReply *reply = sApp->getNetworkAccessManager()->get(QNetworkRequest(QUrl("https://afv-map.vatsim.net/atis-map-data"))); + while (! reply->isFinished()) { loop.exec(); } + QByteArray jsonData = reply->readAll(); + reply->deleteLater(); + + if (jsonData.isEmpty()) { return; } + + QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); + if (jsonDoc.isObject()) + { + QJsonObject rootObject = jsonDoc.object(); + QVector transceivers; + + if (rootObject.contains("controllers")) + { + QJsonObject otherObject = rootObject.value("controllers").toObject(); + for (auto it = otherObject.begin(); it != otherObject.end(); ++it) + { + QString callsign = it.key(); + if (it.value().isObject()) + { + QJsonObject stationObject = it.value().toObject(); + if (stationObject.contains("transceivers")) + { + QJsonArray txArray = stationObject.value("transceivers").toArray(); + for (auto jt = txArray.begin(); jt != txArray.end(); ++jt) + { + TransceiverDto transceiver = TransceiverDto::fromJson(jt->toObject()); + transceivers.push_back({ callsign, transceiver}); + } + } + } + } + } + + if (rootObject.contains("other") && rootObject.value("other").isObject()) + { + QJsonObject otherObject = rootObject.value("other").toObject(); + for (auto it = otherObject.begin(); it != otherObject.end(); ++it) + { + QString callsign = it.key(); + if (it.value().isObject()) + { + QJsonObject stationObject = it.value().toObject(); + if (stationObject.contains("transceivers")) + { + QJsonArray txArray = stationObject.value("transceivers").toArray(); + for (auto jt = txArray.begin(); jt != txArray.end(); ++jt) + { + TransceiverDto transceiver = TransceiverDto::fromJson(jt->toObject()); + transceivers.push_back({ callsign, transceiver}); + } + } + } + } + } + + if (transceivers.isEmpty()) { return; } + transceivers.erase(std::remove_if(transceivers.begin(), transceivers.end(), [this](const CSampleAtcStation & s) + { + return s.callsign() == m_callsign; + }), + transceivers.end()); + m_model->updateAtcStations(transceivers); + } + } + } // ns + } // ns +} // ns diff --git a/src/blackcore/afv/model/afvmapreader.h b/src/blackcore/afv/model/afvmapreader.h new file mode 100644 index 000000000..97e3c75f9 --- /dev/null +++ b/src/blackcore/afv/model/afvmapreader.h @@ -0,0 +1,49 @@ +/* Copyright (C) 2019 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +#ifndef BLACKCORE_AFV_AFVMAPREADER_H +#define BLACKCORE_AFV_AFVMAPREADER_H + +#include "atcstationmodel.h" +#include "blackcore/blackcoreexport.h" + +#include +#include + +namespace BlackCore +{ + namespace Afv + { + namespace Model + { + //! Map reader + class BLACKCORE_EXPORT CAfvMapReader : public QObject + { + Q_OBJECT + Q_PROPERTY(CSampleAtcStationModel *atcStationModel READ getAtcStationModel CONSTANT) + + public: + //! Ctor + CAfvMapReader(QObject *parent = nullptr); + + Q_INVOKABLE void setOwnCallsign(const QString &callsign) { m_callsign = callsign; } + + void updateFromMap(); + + CSampleAtcStationModel *getAtcStationModel() { return m_model; } + + private: + CSampleAtcStationModel *m_model = nullptr; + QTimer *m_timer = nullptr; + QString m_callsign; + }; + } // ns + } // ns +} // ns + +#endif // guard diff --git a/src/blackcore/afv/model/atcstationmodel.cpp b/src/blackcore/afv/model/atcstationmodel.cpp new file mode 100644 index 000000000..914cc46d3 --- /dev/null +++ b/src/blackcore/afv/model/atcstationmodel.cpp @@ -0,0 +1,126 @@ +/* Copyright (C) 2019 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +#include "atcstationmodel.h" +#include + +using namespace BlackCore::Afv; + +namespace BlackCore +{ + namespace Afv + { + namespace Model + { + CSampleAtcStation::CSampleAtcStation(const QString &callsign, const TransceiverDto &transceiver) : + m_callsign(callsign), + m_transceiver(transceiver) + { } + + double CSampleAtcStation::latitude() const + { + return m_transceiver.LatDeg; + } + + double CSampleAtcStation::longitude() const + { + return m_transceiver.LonDeg; + } + + quint32 CSampleAtcStation::frequency() const + { + return m_transceiver.frequency; + } + + QString CSampleAtcStation::formattedFrequency() const + { + return QString::number(m_transceiver.frequency / 1000000.0, 'f', 3); + } + + double CSampleAtcStation::radioDistanceM() const + { + double sqrtAltM = qSqrt(m_transceiver.HeightMslM); + const double radioFactor = 4193.18014745372; + + return radioFactor * sqrtAltM; + } + + CSampleAtcStationModel::CSampleAtcStationModel(QObject *parent) : + QAbstractListModel(parent) + { } + + CSampleAtcStationModel::~CSampleAtcStationModel() {} + + void CSampleAtcStationModel::updateAtcStations(const QVector &atcStations) + { + // Add stations which didn't exist yet + for (const auto &station : atcStations) + { + if (! m_atcStations.contains(station)) { addStation(station); } + } + + // Remove all stations which are no longer there + for (int i = m_atcStations.size() - 1; i >= 0; i--) + { + CSampleAtcStation &station = m_atcStations[i]; + if (! m_atcStations.contains(station)) + { + removeStationAtPosition(i); + } + } + } + + void CSampleAtcStationModel::addStation(const CSampleAtcStation &atcStation) + { + beginInsertRows(QModelIndex(), rowCount(), rowCount()); + m_atcStations << atcStation; + endInsertRows(); + } + + void CSampleAtcStationModel::removeStationAtPosition(int i) + { + beginRemoveRows(QModelIndex(), i, i); + m_atcStations.removeAt(i); + endRemoveRows(); + } + + int CSampleAtcStationModel::rowCount(const QModelIndex &parent) const + { + Q_UNUSED(parent) + return m_atcStations.count(); + } + + QVariant CSampleAtcStationModel::data(const QModelIndex &index, int role) const + { + if (index.row() < 0 || index.row() >= m_atcStations.count()) + return QVariant(); + + const CSampleAtcStation &atcStation = m_atcStations[index.row()]; + if (role == CallsignRole) return atcStation.callsign(); + if (role == LatitudeRole) return atcStation.latitude(); + if (role == LongitudeRole) return atcStation.longitude(); + if (role == RadioDistanceRole) return atcStation.radioDistanceM(); + if (role == FrequencyRole) return atcStation.formattedFrequency(); + if (role == FrequencyKhzRole) return atcStation.frequency() / 1000; + return QVariant(); + } + + QHash CSampleAtcStationModel::roleNames() const + { + QHash roles; + roles[CallsignRole] = "callsign"; + roles[LatitudeRole] = "latitude"; + roles[LongitudeRole] = "longitude"; + roles[RadioDistanceRole] = "radioDistanceM"; + roles[FrequencyRole] = "frequencyAsString"; + roles[FrequencyKhzRole] = "frequencyKhz"; + return roles; + } + } + } +} diff --git a/src/blackcore/afv/model/atcstationmodel.h b/src/blackcore/afv/model/atcstationmodel.h new file mode 100644 index 000000000..64064b727 --- /dev/null +++ b/src/blackcore/afv/model/atcstationmodel.h @@ -0,0 +1,105 @@ +/* Copyright (C) 2019 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +#ifndef BLACKCORE_AFV_MODEL_ATCSTATIONMODEL_H +#define BLACKCORE_AFV_MODEL_ATCSTATIONMODEL_H + +#include "blackcore/afv/dto.h" +#include "blackcore/blackcoreexport.h" + +#include +#include +#include +#include +#include +#include + +namespace BlackCore +{ + namespace Afv + { + namespace Model + { + //! Sample ATC station + class BLACKCORE_EXPORT CSampleAtcStation + { + public: + //! Ctor + CSampleAtcStation() {} + + //! Ctor + CSampleAtcStation(const QString &callsign, const BlackCore::Afv::TransceiverDto &transceiver); + + //! Getter @{ + const QString &callsign() const { return m_callsign; } + QString formattedFrequency() const; + double latitude() const; + double longitude() const; + double radioDistanceM() const; + quint32 frequency() const; + //! @} + + private: + QString m_callsign; + TransceiverDto m_transceiver; + }; + + inline bool operator==(const CSampleAtcStation &lhs, const CSampleAtcStation &rhs) + { + return lhs.callsign() == rhs.callsign() && + qFuzzyCompare(lhs.latitude(), rhs.latitude()) && + qFuzzyCompare(lhs.longitude(), rhs.longitude()); + } + + //! Sample list model + class CSampleAtcStationModel : public QAbstractListModel + { + Q_OBJECT + + public: + //! Roles for model + enum AtcStationRoles + { + CallsignRole = Qt::UserRole + 1, + LatitudeRole, + LongitudeRole, + RadioDistanceRole, + FrequencyRole, + FrequencyKhzRole + }; + + //! Ctor + CSampleAtcStationModel(QObject *parent = nullptr); + + //! Dtor + virtual ~CSampleAtcStationModel() override; + + //! Update the stations + void updateAtcStations(const QVector &atcStations); + + //! copydoc QAbstractListModel::rowCount + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + //! copydoc QAbstractListModel::data + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + protected: + //! copydoc QAbstractListModel::roleNames + QHash roleNames() const override; + + private: + void addStation(const CSampleAtcStation &atcStation); + void removeStationAtPosition(int i); + + QList m_atcStations; + }; + } // ns + } // ns +} // ns + +#endif // guard diff --git a/src/blackcore/blackcore.pro b/src/blackcore/blackcore.pro index a49265313..171058b36 100644 --- a/src/blackcore/blackcore.pro +++ b/src/blackcore/blackcore.pro @@ -33,6 +33,7 @@ HEADERS += $$PWD/afv/audio/*.h HEADERS += $$PWD/afv/clients/*.h HEADERS += $$PWD/afv/crypto/*.h HEADERS += $$PWD/afv/connection/*.h +HEADERS += $$PWD/afv/model/*.h SOURCES += *.cpp SOURCES += $$PWD/context/*.cpp @@ -44,6 +45,7 @@ SOURCES += $$PWD/afv/audio/*.cpp SOURCES += $$PWD/afv/clients/*.cpp SOURCES += $$PWD/afv/crypto/*.cpp SOURCES += $$PWD/afv/connection/*.cpp +SOURCES += $$PWD/afv/model/*.cpp LIBS *= \ -lvatlib \ diff --git a/src/blackgui/blackgui.pro b/src/blackgui/blackgui.pro index 4778c3350..cb0f0423c 100644 --- a/src/blackgui/blackgui.pro +++ b/src/blackgui/blackgui.pro @@ -1,6 +1,6 @@ load(common_pre) -QT += core dbus gui network svg widgets quickwidgets +QT += core dbus gui network svg widgets multimedia quickwidgets TARGET = blackgui TEMPLATE = lib diff --git a/src/blackgui/components/afvmapdialog.cpp b/src/blackgui/components/afvmapdialog.cpp index 698f4e09d..d94290829 100644 --- a/src/blackgui/components/afvmapdialog.cpp +++ b/src/blackgui/components/afvmapdialog.cpp @@ -8,8 +8,15 @@ //! \file +#include "blackcore/afv/clients/afvclient.h" +#include "blackcore/afv/model/afvmapreader.h" + #include "afvmapdialog.h" #include "ui_afvmapdialog.h" +#include + +using namespace BlackCore::Afv::Model; +using namespace BlackCore::Afv::Clients; namespace BlackGui { @@ -20,6 +27,13 @@ namespace BlackGui ui(new Ui::CAfvMapDialog) { ui->setupUi(this); + m_afvMapReader = new CAfvMapReader(this); + m_afvMapReader->updateFromMap(); + m_afvClient = new CAfvClient("https://voice1.vatsim.uk"); + + QQmlContext *ctxt = ui->qw_AfvMap->rootContext(); + ctxt->setContextProperty("afvMapReader", m_afvMapReader); + ctxt->setContextProperty("voiceClient", m_afvClient); } CAfvMapDialog::~CAfvMapDialog() { } diff --git a/src/blackgui/components/afvmapdialog.h b/src/blackgui/components/afvmapdialog.h index 55be6d1d4..797f45448 100644 --- a/src/blackgui/components/afvmapdialog.h +++ b/src/blackgui/components/afvmapdialog.h @@ -15,6 +15,14 @@ #include #include +namespace BlackCore +{ + namespace Afv + { + namespace Model { class CAfvMapReader; } + namespace Clients { class CAfvClient; } + } +} namespace Ui { class CAfvMapDialog; } namespace BlackGui { @@ -34,6 +42,8 @@ namespace BlackGui private: QScopedPointer ui; + BlackCore::Afv::Model::CAfvMapReader *m_afvMapReader = nullptr; + BlackCore::Afv::Clients::CAfvClient *m_afvClient = nullptr; }; } // ns } // ns diff --git a/src/swiftguistandard/swiftguistd.cpp b/src/swiftguistandard/swiftguistd.cpp index c8177748a..8b63de858 100644 --- a/src/swiftguistandard/swiftguistd.cpp +++ b/src/swiftguistandard/swiftguistd.cpp @@ -638,6 +638,7 @@ bool SwiftGuiStd::startAFVMap() if (!m_mapDialog) { m_mapDialog.reset(new CAfvMapDialog(this)); + m_mapDialog->setWindowModality(Qt::NonModal); } m_mapDialog->exec(); return true;