diff --git a/scwx-qt/source/scwx/qt/model/radar_product_model.cpp b/scwx-qt/source/scwx/qt/model/radar_product_model.cpp index b5c33400..0e12f55f 100644 --- a/scwx-qt/source/scwx/qt/model/radar_product_model.cpp +++ b/scwx-qt/source/scwx/qt/model/radar_product_model.cpp @@ -1,6 +1,8 @@ #include +#include #include #include +#include namespace scwx { @@ -17,14 +19,15 @@ class RadarProductModelImpl : public QObject Q_OBJECT public: - explicit RadarProductModelImpl(); + explicit RadarProductModelImpl(RadarProductModel* self); ~RadarProductModelImpl() = default; + RadarProductModel* self_; std::shared_ptr rootItem_; }; RadarProductModel::RadarProductModel(QObject* parent) : - TreeModel(parent), p(std::make_unique()) + TreeModel(parent), p(std::make_unique(this)) { } RadarProductModel::~RadarProductModel() = default; @@ -34,18 +37,69 @@ const std::shared_ptr RadarProductModel::root_item() const return p->rootItem_; } -RadarProductModelImpl::RadarProductModelImpl() : +RadarProductModelImpl::RadarProductModelImpl(RadarProductModel* self) : + self_ {self}, rootItem_ {std::make_shared( std::vector {QObject::tr("Name"), QObject::tr("Info")})} { - connect(&manager::RadarProductManagerNotifier::Instance(), - &manager::RadarProductManagerNotifier::RadarProductManagerCreated, - this, - [=](const std::string& radarSite) - { - rootItem_->AppendChild(new TreeItem( - std::vector {QString::fromStdString(radarSite)})); - }); + connect( + &manager::RadarProductManagerNotifier::Instance(), + &manager::RadarProductManagerNotifier::RadarProductManagerCreated, + this, + [=](const std::string& radarSite) + { + TreeItem* radarSiteItem = + new TreeItem({QString::fromStdString(radarSite)}); + + rootItem_->AppendChild(radarSiteItem); + + connect( + manager::RadarProductManager::Instance(radarSite).get(), + &manager::RadarProductManager::NewDataAvailable, + this, + [=](common::RadarProductGroup group, + const std::string& product, + std::chrono::system_clock::time_point latestTime) + { + const QString groupName {QString::fromStdString( + common::GetRadarProductGroupName(group))}; + + // Find existing group item (e.g., Level 2, Level 3) + TreeItem* groupItem = radarSiteItem->FindChild(0, groupName); + + if (groupItem == nullptr) + { + groupItem = new TreeItem({groupName}); + radarSiteItem->AppendChild(groupItem); + } + + TreeItem* productItem = nullptr; + + if (group == common::RadarProductGroup::Level2) + { + // Level 2 items are not separated by product + productItem = groupItem; + } + else + { + // Find existing product item (e.g., N0B, N0Q) + const QString productName {QString::fromStdString(product)}; + productItem = groupItem->FindChild(0, productName); + + if (productItem == nullptr) + { + productItem = new TreeItem({productName}); + groupItem->AppendChild(productItem); + } + } + + // Create leaf item for product time + productItem->AppendChild(new TreeItem { + QString::fromStdString(util::TimeString(latestTime))}); + }, + Qt::QueuedConnection); + }, + Qt::QueuedConnection); } #include "radar_product_model.moc" diff --git a/scwx-qt/source/scwx/qt/model/tree_item.cpp b/scwx-qt/source/scwx/qt/model/tree_item.cpp index 4780dd3d..e43ef4c2 100644 --- a/scwx-qt/source/scwx/qt/model/tree_item.cpp +++ b/scwx-qt/source/scwx/qt/model/tree_item.cpp @@ -28,6 +28,11 @@ TreeItem::TreeItem(const std::vector& data, TreeItem* parent) : { } +TreeItem::TreeItem(std::initializer_list data, TreeItem* parent) : + TreeItem(std::vector {data}, parent) +{ +} + TreeItem::~TreeItem() {} TreeItem::TreeItem(TreeItem&&) noexcept = default; @@ -39,6 +44,24 @@ void TreeItem::AppendChild(TreeItem* item) p->childItems_.push_back(item); } +TreeItem* TreeItem::FindChild(int column, const QVariant& data) +{ + auto it = std::find_if(p->childItems_.begin(), + p->childItems_.end(), + [&](auto& item) { + return (column < item->column_count() && + item->data(column) == data); + }); + + TreeItem* item = nullptr; + if (it != p->childItems_.end()) + { + item = *it; + } + + return item; +} + const TreeItem* TreeItem::child(int row) const { const TreeItem* item = nullptr; @@ -51,6 +74,23 @@ const TreeItem* TreeItem::child(int row) const return item; } +TreeItem* TreeItem::child(int row) +{ + TreeItem* item = nullptr; + + if (0 <= row && row < p->childItems_.size()) + { + item = p->childItems_[row]; + } + + return item; +} + +std::vector TreeItem::children() +{ + return p->childItems_; +} + int TreeItem::child_count() const { return static_cast(p->childItems_.size()); diff --git a/scwx-qt/source/scwx/qt/model/tree_item.hpp b/scwx-qt/source/scwx/qt/model/tree_item.hpp index 37e3bd6f..de3eb54e 100644 --- a/scwx-qt/source/scwx/qt/model/tree_item.hpp +++ b/scwx-qt/source/scwx/qt/model/tree_item.hpp @@ -17,6 +17,8 @@ class TreeItem public: explicit TreeItem(const std::vector& data, TreeItem* parent = nullptr); + explicit TreeItem(std::initializer_list data, + TreeItem* parent = nullptr); virtual ~TreeItem(); TreeItem(const TreeItem&) = delete; @@ -25,14 +27,17 @@ public: TreeItem(TreeItem&&) noexcept; TreeItem& operator=(TreeItem&&) noexcept; - void AppendChild(TreeItem* child); + void AppendChild(TreeItem* child); + TreeItem* FindChild(int column, const QVariant& data); - const TreeItem* child(int row) const; - int child_count() const; - int column_count() const; - QVariant data(int column) const; - int row() const; - const TreeItem* parent_item() const; + const TreeItem* child(int row) const; + TreeItem* child(int row); + std::vector children(); + int child_count() const; + int column_count() const; + QVariant data(int column) const; + int row() const; + const TreeItem* parent_item() const; private: class Impl; diff --git a/scwx-qt/source/scwx/qt/model/tree_model.cpp b/scwx-qt/source/scwx/qt/model/tree_model.cpp index 6ee59366..fc2c823f 100644 --- a/scwx-qt/source/scwx/qt/model/tree_model.cpp +++ b/scwx-qt/source/scwx/qt/model/tree_model.cpp @@ -17,7 +17,7 @@ public: }; TreeModel::TreeModel(QObject* parent) : - QAbstractTableModel(parent), p(std::make_unique()) + QAbstractItemModel(parent), p(std::make_unique()) { } TreeModel::~TreeModel() = default; diff --git a/scwx-qt/source/scwx/qt/model/tree_model.hpp b/scwx-qt/source/scwx/qt/model/tree_model.hpp index 41bd527c..6c85c299 100644 --- a/scwx-qt/source/scwx/qt/model/tree_model.hpp +++ b/scwx-qt/source/scwx/qt/model/tree_model.hpp @@ -2,7 +2,7 @@ #include -#include +#include namespace scwx { @@ -13,7 +13,7 @@ namespace model class TreeModelImpl; -class TreeModel : public QAbstractTableModel +class TreeModel : public QAbstractItemModel { public: explicit TreeModel(QObject* parent = nullptr);