Display placefiles in settings view

This commit is contained in:
Dan Paulat 2023-07-23 00:14:48 -05:00
parent 157500e20a
commit 014ea9d39e
6 changed files with 279 additions and 4 deletions

View file

@ -104,6 +104,7 @@ set(SRC_MAP source/scwx/qt/map/alert_layer.cpp
set(HDR_MODEL source/scwx/qt/model/alert_model.hpp set(HDR_MODEL source/scwx/qt/model/alert_model.hpp
source/scwx/qt/model/alert_proxy_model.hpp source/scwx/qt/model/alert_proxy_model.hpp
source/scwx/qt/model/imgui_context_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_product_model.hpp
source/scwx/qt/model/radar_site_model.hpp source/scwx/qt/model/radar_site_model.hpp
source/scwx/qt/model/tree_item.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 set(SRC_MODEL source/scwx/qt/model/alert_model.cpp
source/scwx/qt/model/alert_proxy_model.cpp source/scwx/qt/model/alert_proxy_model.cpp
source/scwx/qt/model/imgui_context_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_product_model.cpp
source/scwx/qt/model/radar_site_model.cpp source/scwx/qt/model/radar_site_model.cpp
source/scwx/qt/model/tree_item.cpp source/scwx/qt/model/tree_item.cpp

View file

@ -117,6 +117,7 @@ void PlacefileManager::LoadFile(const std::string& filename)
std::make_unique<PlacefileRecord>(filename, placefile)); std::make_unique<PlacefileRecord>(filename, placefile));
Q_EMIT PlacefileEnabled(filename, record->enabled_); Q_EMIT PlacefileEnabled(filename, record->enabled_);
Q_EMIT PlacefileUpdated(filename);
} }
}); });
} }

View file

@ -0,0 +1,185 @@
#include <scwx/qt/model/placefile_model.hpp>
#include <scwx/qt/manager/placefile_manager.hpp>
#include <scwx/qt/types/qt_types.hpp>
#include <scwx/util/logger.hpp>
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<int>(PlacefileModel::Column::Enabled);
static constexpr int kLastColumn =
static_cast<int>(PlacefileModel::Column::Description);
static constexpr int kNumColumns = kLastColumn - kFirstColumn + 1;
class PlacefileModelImpl
{
public:
explicit PlacefileModelImpl() {}
~PlacefileModelImpl() = default;
std::shared_ptr<manager::PlacefileManager> placefileManager_ {
manager::PlacefileManager::Instance()};
std::vector<std::string> placefileNames_ {};
};
PlacefileModel::PlacefileModel(QObject* parent) :
QAbstractTableModel(parent), p(std::make_unique<PlacefileModelImpl>())
{
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<int>(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<int>(Column::Enabled):
case static_cast<int>(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<int>(Column::Enabled):
if (role == types::ItemDataRole::SortRole)
{
return true; // TODO
}
break;
case static_cast<int>(Column::Thresholds):
if (role == types::ItemDataRole::SortRole)
{
return true; // TODO
}
break;
case static_cast<int>(Column::Url):
return QString::fromStdString(placefileName);
case static_cast<int>(Column::Description):
return QString {};
default:
break;
}
}
else if (role == Qt::ItemDataRole::CheckStateRole)
{
switch (index.column())
{
case static_cast<int>(Column::Enabled):
return true; // TODO
case static_cast<int>(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<int>(Column::Enabled):
return tr("Enabled");
case static_cast<int>(Column::Thresholds):
return tr("Thresholds");
case static_cast<int>(Column::Url):
return tr("URL");
case static_cast<int>(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<int>(p->placefileNames_.size());
beginInsertRows(QModelIndex(), newIndex, newIndex);
p->placefileNames_.push_back(name);
endInsertRows();
}
}
} // namespace model
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,54 @@
#pragma once
#include <scwx/qt/types/text_event_key.hpp>
#include <scwx/common/geographic.hpp>
#include <memory>
#include <QAbstractTableModel>
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<PlacefileModelImpl> p;
};
} // namespace model
} // namespace qt
} // namespace scwx

View file

@ -1,9 +1,13 @@
#include "placefile_settings_widget.hpp" #include "placefile_settings_widget.hpp"
#include "ui_placefile_settings_widget.h" #include "ui_placefile_settings_widget.h"
#include <scwx/qt/model/placefile_model.hpp>
#include <scwx/qt/types/qt_types.hpp>
#include <scwx/qt/ui/open_url_dialog.hpp> #include <scwx/qt/ui/open_url_dialog.hpp>
#include <scwx/util/logger.hpp> #include <scwx/util/logger.hpp>
#include <QSortFilterProxyModel>
namespace scwx namespace scwx
{ {
namespace qt namespace qt
@ -18,15 +22,25 @@ class PlacefileSettingsWidgetImpl
{ {
public: public:
explicit PlacefileSettingsWidgetImpl(PlacefileSettingsWidget* self) : 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; ~PlacefileSettingsWidgetImpl() = default;
void ConnectSignals(); void ConnectSignals();
PlacefileSettingsWidget* self_; PlacefileSettingsWidget* self_;
OpenUrlDialog* openUrlDialog_ {nullptr}; OpenUrlDialog* openUrlDialog_;
model::PlacefileModel* placefileModel_;
QSortFilterProxyModel* placefileProxyModel_;
}; };
PlacefileSettingsWidget::PlacefileSettingsWidget(QWidget* parent) : PlacefileSettingsWidget::PlacefileSettingsWidget(QWidget* parent) :
@ -36,7 +50,14 @@ PlacefileSettingsWidget::PlacefileSettingsWidget(QWidget* parent) :
{ {
ui->setupUi(this); ui->setupUi(this);
p->openUrlDialog_ = new OpenUrlDialog("Add Placefile", this); ui->placefileView->setModel(p->placefileProxyModel_);
ui->placefileView->header()->setSortIndicator(
static_cast<int>(model::PlacefileModel::Column::Url), Qt::AscendingOrder);
ui->placefileView->resizeColumnToContents(
static_cast<int>(model::PlacefileModel::Column::Enabled));
ui->placefileView->resizeColumnToContents(
static_cast<int>(model::PlacefileModel::Column::Thresholds));
p->ConnectSignals(); p->ConnectSignals();
} }
@ -59,6 +80,11 @@ void PlacefileSettingsWidgetImpl::ConnectSignals()
self_, self_,
[this]() [this]()
{ logger_->info("Add URL: {}", openUrlDialog_->url().toStdString()); }); { logger_->info("Add URL: {}", openUrlDialog_->url().toStdString()); });
QObject::connect(self_->ui->placefileFilter,
&QLineEdit::textChanged,
placefileProxyModel_,
&QSortFilterProxyModel::setFilterWildcard);
} }
} // namespace ui } // namespace ui

View file

@ -15,7 +15,14 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QTreeView" name="placefileView"/> <widget class="QTreeView" name="placefileView">
<property name="indentation">
<number>0</number>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item> </item>
<item> <item>
<widget class="QFrame" name="buttonFrame"> <widget class="QFrame" name="buttonFrame">