diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index c5eed0a8..6d307676 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -82,9 +82,11 @@ set(SRC_MAP source/scwx/qt/map/color_table_layer.cpp source/scwx/qt/map/radar_product_layer.cpp source/scwx/qt/map/radar_range_layer.cpp) set(HDR_MODEL source/scwx/qt/model/radar_product_model.hpp + source/scwx/qt/model/radar_site_model.hpp source/scwx/qt/model/tree_item.hpp source/scwx/qt/model/tree_model.hpp) set(SRC_MODEL source/scwx/qt/model/radar_product_model.cpp + source/scwx/qt/model/radar_site_model.cpp source/scwx/qt/model/tree_item.cpp source/scwx/qt/model/tree_model.cpp) set(HDR_REQUEST source/scwx/qt/request/nexrad_file_request.hpp) diff --git a/scwx-qt/source/scwx/qt/config/radar_site.cpp b/scwx-qt/source/scwx/qt/config/radar_site.cpp index b54ae1e6..e275fb64 100644 --- a/scwx-qt/source/scwx/qt/config/radar_site.cpp +++ b/scwx-qt/source/scwx/qt/config/radar_site.cpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace scwx @@ -22,6 +23,7 @@ static const std::string defaultRadarSiteFile_ = static std::unordered_map> radarSiteMap_; static std::unordered_map siteIdMap_; +static std::shared_mutex siteMutex_; static bool ValidateJsonEntry(const boost::json::object& o); @@ -53,7 +55,7 @@ public: RadarSite::RadarSite() : p(std::make_unique()) {} RadarSite::~RadarSite() = default; -RadarSite::RadarSite(RadarSite&&) noexcept = default; +RadarSite::RadarSite(RadarSite&&) noexcept = default; RadarSite& RadarSite::operator=(RadarSite&&) noexcept = default; std::string RadarSite::type() const @@ -116,6 +118,7 @@ std::string RadarSite::location_name() const std::shared_ptr RadarSite::Get(const std::string& id) { + std::shared_lock lock(siteMutex_); std::shared_ptr radarSite = nullptr; if (radarSiteMap_.contains(id)) @@ -126,9 +129,25 @@ std::shared_ptr RadarSite::Get(const std::string& id) return radarSite; } +std::vector> RadarSite::GetAll() +{ + std::shared_lock lock(siteMutex_); + std::vector> radarSites; + + radarSites.reserve(radarSiteMap_.size()); + + for (const auto& site : radarSiteMap_) + { + radarSites.push_back(site.second); + } + + return std::move(radarSites); +} + std::string GetRadarIdFromSiteId(const std::string& siteId) { - std::string id = "???"; + std::shared_lock lock(siteMutex_); + std::string id = "???"; if (siteIdMap_.contains(siteId)) { @@ -156,6 +175,8 @@ size_t RadarSite::ReadConfig(const std::string& path) if (dataValid) { + std::unique_lock lock(siteMutex_); + for (auto& v : j.as_array()) { auto& o = v.as_object(); diff --git a/scwx-qt/source/scwx/qt/config/radar_site.hpp b/scwx-qt/source/scwx/qt/config/radar_site.hpp index 47f344d6..548772b8 100644 --- a/scwx-qt/source/scwx/qt/config/radar_site.hpp +++ b/scwx-qt/source/scwx/qt/config/radar_site.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace scwx { @@ -18,7 +19,7 @@ public: explicit RadarSite(); ~RadarSite(); - RadarSite(const RadarSite&) = delete; + RadarSite(const RadarSite&) = delete; RadarSite& operator=(const RadarSite&) = delete; RadarSite(RadarSite&&) noexcept; @@ -33,7 +34,8 @@ public: std::string place() const; std::string location_name() const; - static std::shared_ptr Get(const std::string& id); + static std::shared_ptr Get(const std::string& id); + static std::vector> GetAll(); static void Initialize(); static size_t ReadConfig(const std::string& path); diff --git a/scwx-qt/source/scwx/qt/model/radar_site_model.cpp b/scwx-qt/source/scwx/qt/model/radar_site_model.cpp new file mode 100644 index 00000000..961ac430 --- /dev/null +++ b/scwx-qt/source/scwx/qt/model/radar_site_model.cpp @@ -0,0 +1,121 @@ +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace model +{ + +static const std::string logPrefix_ = "scwx::qt::model::radar_site_model"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +static constexpr size_t kNumColumns = 7u; + +class RadarSiteModelImpl +{ +public: + explicit RadarSiteModelImpl(); + ~RadarSiteModelImpl() = default; + + QList> radarSites_; +}; + +RadarSiteModel::RadarSiteModel(QObject* parent) : + QAbstractTableModel(parent), p(std::make_unique()) +{ +} +RadarSiteModel::~RadarSiteModel() = default; + +int RadarSiteModel::rowCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : p->radarSites_.size(); +} + +int RadarSiteModel::columnCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : static_cast(kNumColumns); +} + +QVariant RadarSiteModel::data(const QModelIndex& index, int role) const +{ + if (index.isValid() && index.row() >= 0 && + index.row() < p->radarSites_.size() && role == Qt::DisplayRole) + { + const auto& site = p->radarSites_.at(index.row()); + + switch (index.column()) + { + case 0: + return QString::fromStdString(site->id()); + case 1: + return QString::fromStdString(site->place()); + case 2: + return QString::fromStdString(site->state()); + case 3: + return QString::fromStdString(site->country()); + case 4: + return QString("%1").arg(site->latitude()); + case 5: + return QString("%1").arg(site->longitude()); + case 6: + return QString::fromStdString(site->type()); + default: + break; + } + } + + return QVariant(); +} + +QVariant RadarSiteModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + if (role == Qt::DisplayRole) + { + if (orientation == Qt::Horizontal) + { + switch (section) + { + case 0: + return tr("Site ID"); + case 1: + return tr("Place"); + case 2: + return tr("State"); + case 3: + return tr("Country"); + case 4: + return tr("Latitude"); + case 5: + return tr("Longitude"); + case 6: + return tr("Type"); + default: + break; + } + } + } + + return QVariant(); +} + +RadarSiteModelImpl::RadarSiteModelImpl() : radarSites_ {} +{ + // Get all loaded radar sites + std::vector> radarSites = + config::RadarSite::GetAll(); + + // Setup radar site list + for (auto& site : radarSites) + { + radarSites_.emplace_back(std::move(site)); + } +} + +} // namespace model +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/model/radar_site_model.hpp b/scwx-qt/source/scwx/qt/model/radar_site_model.hpp new file mode 100644 index 00000000..dad7a7cc --- /dev/null +++ b/scwx-qt/source/scwx/qt/model/radar_site_model.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace model +{ + +class RadarSiteModelImpl; + +class RadarSiteModel : public QAbstractTableModel +{ +public: + explicit RadarSiteModel(QObject* parent = nullptr); + ~RadarSiteModel(); + + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + + QVariant data(const QModelIndex& index, + int role = Qt::DisplayRole) const override; + QVariant headerData(int section, + Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + +private: + std::unique_ptr p; + + friend class RadarSiteModelImpl; +}; + +} // namespace model +} // namespace qt +} // namespace scwx