From 014ea9d39ee8d5666bcbb08c50f373e90c7bb030 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sun, 23 Jul 2023 00:14:48 -0500 Subject: [PATCH] Display placefiles in settings view --- scwx-qt/scwx-qt.cmake | 2 + .../scwx/qt/manager/placefile_manager.cpp | 1 + .../source/scwx/qt/model/placefile_model.cpp | 185 ++++++++++++++++++ .../source/scwx/qt/model/placefile_model.hpp | 54 +++++ .../scwx/qt/ui/placefile_settings_widget.cpp | 32 ++- .../scwx/qt/ui/placefile_settings_widget.ui | 9 +- 6 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 scwx-qt/source/scwx/qt/model/placefile_model.cpp create mode 100644 scwx-qt/source/scwx/qt/model/placefile_model.hpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index a2c758bd..745cd8a2 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -104,6 +104,7 @@ set(SRC_MAP source/scwx/qt/map/alert_layer.cpp set(HDR_MODEL source/scwx/qt/model/alert_model.hpp source/scwx/qt/model/alert_proxy_model.hpp source/scwx/qt/model/imgui_context_model.hpp + source/scwx/qt/model/placefile_model.hpp source/scwx/qt/model/radar_product_model.hpp source/scwx/qt/model/radar_site_model.hpp source/scwx/qt/model/tree_item.hpp @@ -111,6 +112,7 @@ set(HDR_MODEL source/scwx/qt/model/alert_model.hpp set(SRC_MODEL source/scwx/qt/model/alert_model.cpp source/scwx/qt/model/alert_proxy_model.cpp source/scwx/qt/model/imgui_context_model.cpp + source/scwx/qt/model/placefile_model.cpp source/scwx/qt/model/radar_product_model.cpp source/scwx/qt/model/radar_site_model.cpp source/scwx/qt/model/tree_item.cpp diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp index 88e8f232..0318d03e 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp @@ -117,6 +117,7 @@ void PlacefileManager::LoadFile(const std::string& filename) std::make_unique(filename, placefile)); Q_EMIT PlacefileEnabled(filename, record->enabled_); + Q_EMIT PlacefileUpdated(filename); } }); } diff --git a/scwx-qt/source/scwx/qt/model/placefile_model.cpp b/scwx-qt/source/scwx/qt/model/placefile_model.cpp new file mode 100644 index 00000000..5975547e --- /dev/null +++ b/scwx-qt/source/scwx/qt/model/placefile_model.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace model +{ + +static const std::string logPrefix_ = "scwx::qt::model::placefile_model"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +static constexpr int kFirstColumn = + static_cast(PlacefileModel::Column::Enabled); +static constexpr int kLastColumn = + static_cast(PlacefileModel::Column::Description); +static constexpr int kNumColumns = kLastColumn - kFirstColumn + 1; + +class PlacefileModelImpl +{ +public: + explicit PlacefileModelImpl() {} + ~PlacefileModelImpl() = default; + + std::shared_ptr placefileManager_ { + manager::PlacefileManager::Instance()}; + + std::vector placefileNames_ {}; +}; + +PlacefileModel::PlacefileModel(QObject* parent) : + QAbstractTableModel(parent), p(std::make_unique()) +{ + connect(p->placefileManager_.get(), + &manager::PlacefileManager::PlacefileUpdated, + this, + &PlacefileModel::HandlePlacefileUpdate); +} +PlacefileModel::~PlacefileModel() = default; + +int PlacefileModel::rowCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : static_cast(p->placefileNames_.size()); +} + +int PlacefileModel::columnCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : kNumColumns; +} + +Qt::ItemFlags PlacefileModel::flags(const QModelIndex& index) const +{ + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + + switch (index.column()) + { + case static_cast(Column::Enabled): + case static_cast(Column::Thresholds): + flags |= Qt::ItemFlag::ItemIsUserCheckable; + + default: + break; + } + + return flags; +} + +QVariant PlacefileModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid() || index.row() < 0 || + index.row() >= p->placefileNames_.size()) + { + return QVariant(); + } + + const auto& placefileName = p->placefileNames_.at(index.row()); + + if (role == Qt::ItemDataRole::DisplayRole || + role == types::ItemDataRole::SortRole) + { + switch (index.column()) + { + case static_cast(Column::Enabled): + if (role == types::ItemDataRole::SortRole) + { + return true; // TODO + } + break; + + case static_cast(Column::Thresholds): + if (role == types::ItemDataRole::SortRole) + { + return true; // TODO + } + break; + + case static_cast(Column::Url): + return QString::fromStdString(placefileName); + + case static_cast(Column::Description): + return QString {}; + + default: + break; + } + } + else if (role == Qt::ItemDataRole::CheckStateRole) + { + switch (index.column()) + { + case static_cast(Column::Enabled): + return true; // TODO + + case static_cast(Column::Thresholds): + return true; // TODO + + default: + break; + } + } + + return QVariant(); +} + +QVariant PlacefileModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + if (role == Qt::DisplayRole) + { + if (orientation == Qt::Horizontal) + { + switch (section) + { + case static_cast(Column::Enabled): + return tr("Enabled"); + + case static_cast(Column::Thresholds): + return tr("Thresholds"); + + case static_cast(Column::Url): + return tr("URL"); + + case static_cast(Column::Description): + return tr("Description"); + + default: + break; + } + } + } + + return QVariant(); +} + +void PlacefileModel::HandlePlacefileUpdate(const std::string& name) +{ + auto it = + std::find(p->placefileNames_.begin(), p->placefileNames_.end(), name); + + if (it != p->placefileNames_.end()) + { + // Placefile exists, mark row as updated + const int row = std::distance(p->placefileNames_.begin(), it); + QModelIndex topLeft = createIndex(row, kFirstColumn); + QModelIndex bottomRight = createIndex(row, kLastColumn); + + Q_EMIT dataChanged(topLeft, bottomRight); + } + else + { + // Placefile is new, append row + const int newIndex = static_cast(p->placefileNames_.size()); + beginInsertRows(QModelIndex(), newIndex, newIndex); + p->placefileNames_.push_back(name); + endInsertRows(); + } +} + +} // namespace model +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/model/placefile_model.hpp b/scwx-qt/source/scwx/qt/model/placefile_model.hpp new file mode 100644 index 00000000..0f5a1b10 --- /dev/null +++ b/scwx-qt/source/scwx/qt/model/placefile_model.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include +#include + +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace model +{ + +class PlacefileModelImpl; + +class PlacefileModel : public QAbstractTableModel +{ +public: + enum class Column : int + { + Enabled = 0, + Thresholds = 1, + Url = 2, + Description = 3 + }; + + explicit PlacefileModel(QObject* parent = nullptr); + ~PlacefileModel(); + + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + + Qt::ItemFlags flags(const QModelIndex& index) 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; + +public slots: + void HandlePlacefileUpdate(const std::string& name); + +private: + friend class PlacefileModelImpl; + std::unique_ptr p; +}; + +} // namespace model +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp b/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp index 420f915a..f75522a7 100644 --- a/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp @@ -1,9 +1,13 @@ #include "placefile_settings_widget.hpp" #include "ui_placefile_settings_widget.h" +#include +#include #include #include +#include + namespace scwx { namespace qt @@ -18,15 +22,25 @@ class PlacefileSettingsWidgetImpl { public: explicit PlacefileSettingsWidgetImpl(PlacefileSettingsWidget* self) : - self_ {self} + self_ {self}, + openUrlDialog_ {new OpenUrlDialog(QObject::tr("Add Placefile"), self_)}, + placefileModel_ {new model::PlacefileModel(self_)}, + placefileProxyModel_ {new QSortFilterProxyModel(self_)} { + placefileProxyModel_->setSourceModel(placefileModel_); + placefileProxyModel_->setSortRole(types::SortRole); + placefileProxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive); + placefileProxyModel_->setFilterKeyColumn(-1); } ~PlacefileSettingsWidgetImpl() = default; void ConnectSignals(); PlacefileSettingsWidget* self_; - OpenUrlDialog* openUrlDialog_ {nullptr}; + OpenUrlDialog* openUrlDialog_; + + model::PlacefileModel* placefileModel_; + QSortFilterProxyModel* placefileProxyModel_; }; PlacefileSettingsWidget::PlacefileSettingsWidget(QWidget* parent) : @@ -36,7 +50,14 @@ PlacefileSettingsWidget::PlacefileSettingsWidget(QWidget* parent) : { ui->setupUi(this); - p->openUrlDialog_ = new OpenUrlDialog("Add Placefile", this); + ui->placefileView->setModel(p->placefileProxyModel_); + ui->placefileView->header()->setSortIndicator( + static_cast(model::PlacefileModel::Column::Url), Qt::AscendingOrder); + + ui->placefileView->resizeColumnToContents( + static_cast(model::PlacefileModel::Column::Enabled)); + ui->placefileView->resizeColumnToContents( + static_cast(model::PlacefileModel::Column::Thresholds)); p->ConnectSignals(); } @@ -59,6 +80,11 @@ void PlacefileSettingsWidgetImpl::ConnectSignals() self_, [this]() { logger_->info("Add URL: {}", openUrlDialog_->url().toStdString()); }); + + QObject::connect(self_->ui->placefileFilter, + &QLineEdit::textChanged, + placefileProxyModel_, + &QSortFilterProxyModel::setFilterWildcard); } } // namespace ui diff --git a/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.ui b/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.ui index 145aef86..ef2f24fd 100644 --- a/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.ui +++ b/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.ui @@ -15,7 +15,14 @@ - + + + 0 + + + true + +