Make placefile settings view editable

This commit is contained in:
Dan Paulat 2023-07-25 23:15:12 -05:00
parent 3ff34caa02
commit 7c21ccaf41
6 changed files with 234 additions and 77 deletions

View file

@ -66,7 +66,7 @@ public:
PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this)) {} PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this)) {}
PlacefileManager::~PlacefileManager() = default; PlacefileManager::~PlacefileManager() = default;
bool PlacefileManager::PlacefileEnabled(const std::string& name) bool PlacefileManager::placefile_enabled(const std::string& name)
{ {
std::shared_lock lock(p->placefileRecordLock_); std::shared_lock lock(p->placefileRecordLock_);
@ -78,7 +78,7 @@ bool PlacefileManager::PlacefileEnabled(const std::string& name)
return false; return false;
} }
bool PlacefileManager::PlacefileThresholded(const std::string& name) bool PlacefileManager::placefile_thresholded(const std::string& name)
{ {
std::shared_lock lock(p->placefileRecordLock_); std::shared_lock lock(p->placefileRecordLock_);
@ -91,7 +91,7 @@ bool PlacefileManager::PlacefileThresholded(const std::string& name)
} }
std::shared_ptr<const gr::Placefile> std::shared_ptr<const gr::Placefile>
PlacefileManager::Placefile(const std::string& name) PlacefileManager::placefile(const std::string& name)
{ {
std::shared_lock lock(p->placefileRecordLock_); std::shared_lock lock(p->placefileRecordLock_);
@ -103,6 +103,60 @@ PlacefileManager::Placefile(const std::string& name)
return nullptr; return nullptr;
} }
void PlacefileManager::set_placefile_enabled(const std::string& name,
bool enabled)
{
std::shared_lock lock(p->placefileRecordLock_);
auto it = p->placefileRecordMap_.find(name);
if (it != p->placefileRecordMap_.cend())
{
it->second->enabled_ = enabled;
lock.unlock();
Q_EMIT PlacefileEnabled(name, enabled);
}
}
void PlacefileManager::set_placefile_thresholded(const std::string& name,
bool thresholded)
{
std::shared_lock lock(p->placefileRecordLock_);
auto it = p->placefileRecordMap_.find(name);
if (it != p->placefileRecordMap_.cend())
{
it->second->thresholded_ = thresholded;
lock.unlock();
Q_EMIT PlacefileUpdated(name);
}
}
void PlacefileManager::set_placefile_url(const std::string& name,
const std::string& newUrl)
{
std::unique_lock lock(p->placefileRecordLock_);
auto it = p->placefileRecordMap_.find(name);
auto itNew = p->placefileRecordMap_.find(newUrl);
if (it != p->placefileRecordMap_.cend() &&
itNew == p->placefileRecordMap_.cend())
{
auto placefileRecord = it->second;
placefileRecord->name_ = newUrl;
placefileRecord->placefile_ = nullptr;
p->placefileRecordMap_.erase(it);
p->placefileRecordMap_.emplace(newUrl, placefileRecord);
lock.unlock();
Q_EMIT PlacefileRenamed(name, newUrl);
}
}
std::vector<std::shared_ptr<gr::Placefile>> std::vector<std::shared_ptr<gr::Placefile>>
PlacefileManager::GetActivePlacefiles() PlacefileManager::GetActivePlacefiles()
{ {
@ -112,7 +166,7 @@ PlacefileManager::GetActivePlacefiles()
for (const auto& record : p->placefileRecords_) for (const auto& record : p->placefileRecords_)
{ {
if (record->enabled_) if (record->enabled_ && record->placefile_ != nullptr)
{ {
placefiles.emplace_back(record->placefile_); placefiles.emplace_back(record->placefile_);
} }

View file

@ -19,9 +19,13 @@ public:
explicit PlacefileManager(); explicit PlacefileManager();
~PlacefileManager(); ~PlacefileManager();
bool PlacefileEnabled(const std::string& name); bool placefile_enabled(const std::string& name);
bool PlacefileThresholded(const std::string& name); bool placefile_thresholded(const std::string& name);
std::shared_ptr<const gr::Placefile> Placefile(const std::string& name); std::shared_ptr<const gr::Placefile> placefile(const std::string& name);
void set_placefile_enabled(const std::string& name, bool enabled);
void set_placefile_thresholded(const std::string& name, bool thresholded);
void set_placefile_url(const std::string& name, const std::string& newUrl);
/** /**
* @brief Gets a list of active placefiles * @brief Gets a list of active placefiles
@ -37,6 +41,8 @@ public:
signals: signals:
void PlacefileEnabled(const std::string& name, bool enabled); void PlacefileEnabled(const std::string& name, bool enabled);
void PlacefileRenamed(const std::string& oldName,
const std::string& newName);
void PlacefileUpdated(const std::string& name); void PlacefileUpdated(const std::string& name);
private: private:

View file

@ -40,6 +40,16 @@ public:
PlacefileModel::PlacefileModel(QObject* parent) : PlacefileModel::PlacefileModel(QObject* parent) :
QAbstractTableModel(parent), p(std::make_unique<PlacefileModelImpl>()) QAbstractTableModel(parent), p(std::make_unique<PlacefileModelImpl>())
{ {
connect(p->placefileManager_.get(),
&manager::PlacefileManager::PlacefileEnabled,
this,
&PlacefileModel::HandlePlacefileUpdate);
connect(p->placefileManager_.get(),
&manager::PlacefileManager::PlacefileRenamed,
this,
&PlacefileModel::HandlePlacefileRenamed);
connect(p->placefileManager_.get(), connect(p->placefileManager_.get(),
&manager::PlacefileManager::PlacefileUpdated, &manager::PlacefileManager::PlacefileUpdated,
this, this,
@ -65,7 +75,12 @@ Qt::ItemFlags PlacefileModel::flags(const QModelIndex& index) const
{ {
case static_cast<int>(Column::Enabled): case static_cast<int>(Column::Enabled):
case static_cast<int>(Column::Thresholds): case static_cast<int>(Column::Thresholds):
flags |= Qt::ItemFlag::ItemIsUserCheckable; flags |= Qt::ItemFlag::ItemIsUserCheckable | Qt::ItemFlag::ItemIsEditable;
break;
case static_cast<int>(Column::Placefile):
flags |= Qt::ItemFlag::ItemIsEditable;
break;
default: default:
break; break;
@ -76,6 +91,14 @@ Qt::ItemFlags PlacefileModel::flags(const QModelIndex& index) const
QVariant PlacefileModel::data(const QModelIndex& index, int role) const QVariant PlacefileModel::data(const QModelIndex& index, int role) const
{ {
static const QString enabledString = QObject::tr("Enabled");
static const QString disabledString = QObject::tr("Disabled");
static const QString thresholdsEnabledString =
QObject::tr("Thresholds Enabled");
static const QString thresholdsDisabledString =
QObject::tr("Thresholds Disabled");
if (!index.isValid() || index.row() < 0 || if (!index.isValid() || index.row() < 0 ||
static_cast<std::size_t>(index.row()) >= p->placefileNames_.size()) static_cast<std::size_t>(index.row()) >= p->placefileNames_.size())
{ {
@ -84,41 +107,54 @@ QVariant PlacefileModel::data(const QModelIndex& index, int role) const
const auto& placefileName = p->placefileNames_.at(index.row()); const auto& placefileName = p->placefileNames_.at(index.row());
if (role == Qt::ItemDataRole::DisplayRole || switch (index.column())
role == Qt::ItemDataRole::ToolTipRole)
{ {
static const QString enabledString = QObject::tr("Enabled"); case static_cast<int>(Column::Enabled):
static const QString disabledString = QObject::tr("Disabled"); if (role == Qt::ItemDataRole::ToolTipRole)
static const QString thresholdsEnabledString =
QObject::tr("Thresholds Enabled");
static const QString thresholdsDisabledString =
QObject::tr("Thresholds Disabled");
switch (index.column())
{ {
case static_cast<int>(Column::Enabled): return p->placefileManager_->placefile_enabled(placefileName) ?
if (role == Qt::ItemDataRole::ToolTipRole) enabledString :
{ disabledString;
return p->placefileManager_->PlacefileEnabled(placefileName) ? }
enabledString : else if (role == Qt::ItemDataRole::CheckStateRole)
disabledString; {
} return static_cast<int>(
break; p->placefileManager_->placefile_enabled(placefileName) ?
Qt::CheckState::Checked :
Qt::CheckState::Unchecked);
}
else if (role == types::ItemDataRole::SortRole)
{
return p->placefileManager_->placefile_enabled(placefileName);
}
break;
case static_cast<int>(Column::Thresholds): case static_cast<int>(Column::Thresholds):
if (role == Qt::ItemDataRole::ToolTipRole) if (role == Qt::ItemDataRole::ToolTipRole)
{ {
return p->placefileManager_->PlacefileThresholded(placefileName) ? return p->placefileManager_->placefile_thresholded(placefileName) ?
thresholdsEnabledString : thresholdsEnabledString :
thresholdsDisabledString; thresholdsDisabledString;
} }
break; else if (role == Qt::ItemDataRole::CheckStateRole)
{
return static_cast<int>(
p->placefileManager_->placefile_thresholded(placefileName) ?
Qt::CheckState::Checked :
Qt::CheckState::Unchecked);
}
else if (role == types::ItemDataRole::SortRole)
{
return p->placefileManager_->placefile_thresholded(placefileName);
}
break;
case static_cast<int>(Column::Placefile): case static_cast<int>(Column::Placefile):
if (role == Qt::ItemDataRole::DisplayRole ||
role == Qt::ItemDataRole::ToolTipRole)
{ {
std::string description = placefileName; std::string description = placefileName;
auto placefile = p->placefileManager_->Placefile(placefileName); auto placefile = p->placefileManager_->placefile(placefileName);
if (placefile != nullptr) if (placefile != nullptr)
{ {
std::string title = placefile->title(); std::string title = placefile->title();
@ -130,47 +166,15 @@ QVariant PlacefileModel::data(const QModelIndex& index, int role) const
return QString::fromStdString(description); return QString::fromStdString(description);
} }
else if (role == Qt::ItemDataRole::EditRole ||
default: role == types::ItemDataRole::SortRole)
break;
}
}
else if (role == types::ItemDataRole::SortRole)
{
switch (index.column())
{ {
case static_cast<int>(Column::Enabled):
return p->placefileManager_->PlacefileEnabled(placefileName);
case static_cast<int>(Column::Thresholds):
return p->placefileManager_->PlacefileThresholded(placefileName);
case static_cast<int>(Column::Placefile):
return QString::fromStdString(placefileName); return QString::fromStdString(placefileName);
default:
break;
} }
} break;
else if (role == Qt::ItemDataRole::CheckStateRole)
{
switch (index.column())
{
case static_cast<int>(Column::Enabled):
return static_cast<int>(
p->placefileManager_->PlacefileEnabled(placefileName) ?
Qt::CheckState::Checked :
Qt::CheckState::Unchecked);
case static_cast<int>(Column::Thresholds): default:
return static_cast<int>( break;
p->placefileManager_->PlacefileThresholded(placefileName) ?
Qt::CheckState::Checked :
Qt::CheckState::Unchecked);
default:
break;
}
} }
return QVariant(); return QVariant();
@ -240,6 +244,82 @@ QVariant PlacefileModel::headerData(int section,
return QVariant(); return QVariant();
} }
bool PlacefileModel::setData(const QModelIndex& index,
const QVariant& value,
int role)
{
if (!index.isValid() || index.row() < 0 ||
static_cast<std::size_t>(index.row()) >= p->placefileNames_.size())
{
return false;
}
const auto& placefileName = p->placefileNames_.at(index.row());
switch (index.column())
{
case static_cast<int>(Column::Enabled):
if (role == Qt::ItemDataRole::CheckStateRole)
{
p->placefileManager_->set_placefile_enabled(placefileName,
value.toBool());
return true;
}
break;
case static_cast<int>(Column::Thresholds):
if (role == Qt::ItemDataRole::CheckStateRole)
{
p->placefileManager_->set_placefile_thresholded(placefileName,
value.toBool());
return true;
}
break;
case static_cast<int>(Column::Placefile):
if (role == Qt::ItemDataRole::EditRole)
{
p->placefileManager_->set_placefile_url(
placefileName, value.toString().toStdString());
return true;
}
break;
default:
break;
}
return true;
}
void PlacefileModel::HandlePlacefileRenamed(const std::string& oldName,
const std::string& newName)
{
auto it =
std::find(p->placefileNames_.begin(), p->placefileNames_.end(), oldName);
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);
// Rename placefile
*it = newName;
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(newName);
endInsertRows();
}
}
void PlacefileModel::HandlePlacefileUpdate(const std::string& name) void PlacefileModel::HandlePlacefileUpdate(const std::string& name)
{ {
auto it = auto it =

View file

@ -40,7 +40,13 @@ public:
Qt::Orientation orientation, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override; int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex& index,
const QVariant& value,
int role = Qt::EditRole) override;
public slots: public slots:
void HandlePlacefileRenamed(const std::string& oldName,
const std::string& newName);
void HandlePlacefileUpdate(const std::string& name); void HandlePlacefileUpdate(const std::string& name);
private: private:

View file

@ -84,12 +84,14 @@ public:
*/ */
std::vector<std::shared_ptr<DrawItem>> GetDrawItems(); std::vector<std::shared_ptr<DrawItem>> GetDrawItems();
std::string name() const;
std::string title() const; std::string title() const;
std::unordered_map<std::size_t, std::shared_ptr<Font>> fonts(); std::unordered_map<std::size_t, std::shared_ptr<Font>> fonts();
std::shared_ptr<Font> font(std::size_t i); std::shared_ptr<Font> font(std::size_t i);
static std::shared_ptr<Placefile> Load(const std::string& filename); static std::shared_ptr<Placefile> Load(const std::string& filename);
static std::shared_ptr<Placefile> Load(std::istream& is); static std::shared_ptr<Placefile> Load(const std::string& name,
std::istream& is);
private: private:
class Impl; class Impl;

View file

@ -51,6 +51,7 @@ public:
static void ProcessEscapeCharacters(std::string& s); static void ProcessEscapeCharacters(std::string& s);
static void TrimQuotes(std::string& s); static void TrimQuotes(std::string& s);
std::string name_ {};
std::string title_ {}; std::string title_ {};
std::chrono::seconds refresh_ {-1}; std::chrono::seconds refresh_ {-1};
@ -85,6 +86,11 @@ std::vector<std::shared_ptr<Placefile::DrawItem>> Placefile::GetDrawItems()
return p->drawItems_; return p->drawItems_;
} }
std::string Placefile::name() const
{
return p->name_;
}
std::string Placefile::title() const std::string Placefile::title() const
{ {
return p->title_; return p->title_;
@ -110,13 +116,16 @@ std::shared_ptr<Placefile> Placefile::Load(const std::string& filename)
{ {
logger_->debug("Loading placefile: {}", filename); logger_->debug("Loading placefile: {}", filename);
std::ifstream f(filename, std::ios_base::in); std::ifstream f(filename, std::ios_base::in);
return Load(f); return Load(filename, f);
} }
std::shared_ptr<Placefile> Placefile::Load(std::istream& is) std::shared_ptr<Placefile> Placefile::Load(const std::string& name,
std::istream& is)
{ {
std::shared_ptr<Placefile> placefile = std::make_shared<Placefile>(); std::shared_ptr<Placefile> placefile = std::make_shared<Placefile>();
placefile->p->name_ = name;
std::string line; std::string line;
while (scwx::util::getline(is, line)) while (scwx::util::getline(is, line))
{ {