diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp index 0318d03e..b235ded2 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include #include @@ -39,6 +41,7 @@ public: std::string name_; std::shared_ptr placefile_; bool enabled_; + bool thresholded_ {true}; boost::asio::thread_pool threadPool_ {1u}; boost::asio::steady_timer refreshTimer_ {threadPool_}; std::mutex refreshMutex_ {}; @@ -54,13 +57,52 @@ public: PlacefileManager* self_; - std::vector> placefileRecords_ {}; - std::shared_mutex placefileRecordLock_ {}; + std::vector> placefileRecords_ {}; + std::unordered_map> + placefileRecordMap_ {}; + std::shared_mutex placefileRecordLock_ {}; }; PlacefileManager::PlacefileManager() : p(std::make_unique(this)) {} PlacefileManager::~PlacefileManager() = default; +bool PlacefileManager::PlacefileEnabled(const std::string& name) +{ + std::shared_lock lock(p->placefileRecordLock_); + + auto it = p->placefileRecordMap_.find(name); + if (it != p->placefileRecordMap_.cend()) + { + return it->second->enabled_; + } + return false; +} + +bool PlacefileManager::PlacefileThresholded(const std::string& name) +{ + std::shared_lock lock(p->placefileRecordLock_); + + auto it = p->placefileRecordMap_.find(name); + if (it != p->placefileRecordMap_.cend()) + { + return it->second->thresholded_; + } + return false; +} + +std::shared_ptr +PlacefileManager::Placefile(const std::string& name) +{ + std::shared_lock lock(p->placefileRecordLock_); + + auto it = p->placefileRecordMap_.find(name); + if (it != p->placefileRecordMap_.cend()) + { + return it->second->placefile_; + } + return nullptr; +} + std::vector> PlacefileManager::GetActivePlacefiles() { @@ -79,6 +121,47 @@ PlacefileManager::GetActivePlacefiles() return placefiles; } +void PlacefileManager::AddUrl(const std::string& urlString) +{ + std::string normalizedUrl; + + // Normalize URL string + QUrl url = QUrl::fromUserInput(QString::fromStdString(urlString)); + if (url.isLocalFile()) + { + normalizedUrl = QDir::toNativeSeparators(url.toLocalFile()).toStdString(); + } + else + { + normalizedUrl = urlString; + } + + std::unique_lock lock(p->placefileRecordLock_); + + // Determine if the placefile has been loaded previously + auto it = std::find_if(p->placefileRecords_.begin(), + p->placefileRecords_.end(), + [&normalizedUrl](auto& record) + { return record->name_ == normalizedUrl; }); + if (it != p->placefileRecords_.end()) + { + logger_->debug("Placefile already added: {}", normalizedUrl); + return; + } + + // Placefile is new, proceed with adding + logger_->info("AddUrl: {}", normalizedUrl); + + // Add an empty placefile record for the new URL + auto placefileRecord = p->placefileRecords_.emplace_back( + std::make_shared(normalizedUrl, nullptr, false)); + p->placefileRecordMap_.insert_or_assign(normalizedUrl, placefileRecord); + + lock.unlock(); + + Q_EMIT PlacefileUpdated(normalizedUrl); +} + void PlacefileManager::LoadFile(const std::string& filename) { logger_->debug("LoadFile: {}", filename); @@ -99,14 +182,13 @@ void PlacefileManager::LoadFile(const std::string& filename) std::unique_lock lock(p->placefileRecordLock_); // Determine if the placefile has been loaded previously - auto it = std::find_if(p->placefileRecords_.begin(), - p->placefileRecords_.end(), - [&filename](auto& record) - { return record->name_ == filename; }); - if (it != p->placefileRecords_.end()) + auto it = p->placefileRecordMap_.find(filename); + if (it != p->placefileRecordMap_.end()) { // If the placefile has been loaded previously, update it - (*it)->Update(placefile); + it->second->Update(placefile); + + lock.unlock(); Q_EMIT PlacefileUpdated(filename); } @@ -114,7 +196,10 @@ void PlacefileManager::LoadFile(const std::string& filename) { // If this is a new placefile, add it auto& record = p->placefileRecords_.emplace_back( - std::make_unique(filename, placefile)); + std::make_shared(filename, placefile)); + p->placefileRecordMap_.insert_or_assign(filename, record); + + lock.unlock(); Q_EMIT PlacefileEnabled(filename, record->enabled_); Q_EMIT PlacefileUpdated(filename); diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp index 55be1e90..4036a3b0 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp @@ -19,6 +19,10 @@ public: explicit PlacefileManager(); ~PlacefileManager(); + bool PlacefileEnabled(const std::string& name); + bool PlacefileThresholded(const std::string& name); + std::shared_ptr Placefile(const std::string& name); + /** * @brief Gets a list of active placefiles * @@ -26,6 +30,7 @@ public: */ std::vector> GetActivePlacefiles(); + void AddUrl(const std::string& urlString); void LoadFile(const std::string& filename); static std::shared_ptr Instance(); diff --git a/scwx-qt/source/scwx/qt/model/placefile_model.cpp b/scwx-qt/source/scwx/qt/model/placefile_model.cpp index 50b5ad73..716e54a4 100644 --- a/scwx-qt/source/scwx/qt/model/placefile_model.cpp +++ b/scwx-qt/source/scwx/qt/model/placefile_model.cpp @@ -90,14 +90,14 @@ QVariant PlacefileModel::data(const QModelIndex& index, int role) const case static_cast(Column::Enabled): if (role == types::ItemDataRole::SortRole) { - return true; // TODO + return p->placefileManager_->PlacefileEnabled(placefileName); } break; case static_cast(Column::Thresholds): if (role == types::ItemDataRole::SortRole) { - return true; // TODO + return p->placefileManager_->PlacefileThresholded(placefileName); } break; @@ -105,7 +105,14 @@ QVariant PlacefileModel::data(const QModelIndex& index, int role) const return QString::fromStdString(placefileName); case static_cast(Column::Description): + { + auto placefile = p->placefileManager_->Placefile(placefileName); + if (placefile != nullptr) + { + return QString::fromStdString(placefile->title()); + } return QString {}; + } default: break; @@ -116,10 +123,10 @@ QVariant PlacefileModel::data(const QModelIndex& index, int role) const switch (index.column()) { case static_cast(Column::Enabled): - return true; // TODO + return p->placefileManager_->PlacefileEnabled(placefileName); case static_cast(Column::Thresholds): - return true; // TODO + return p->placefileManager_->PlacefileThresholded(placefileName); default: break; @@ -133,7 +140,7 @@ QVariant PlacefileModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role == Qt::DisplayRole) + if (role == Qt::ItemDataRole::DisplayRole) { if (orientation == Qt::Horizontal) { 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 01612320..d9167fb6 100644 --- a/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp @@ -1,6 +1,7 @@ #include "placefile_settings_widget.hpp" #include "ui_placefile_settings_widget.h" +#include #include #include #include @@ -41,6 +42,9 @@ public: PlacefileSettingsWidget* self_; OpenUrlDialog* openUrlDialog_; + std::shared_ptr placefileManager_ { + manager::PlacefileManager::Instance()}; + model::PlacefileModel* placefileModel_; QSortFilterProxyModel* placefileProxyModel_; LeftElidedItemDelegate* leftElidedItemDelegate_; @@ -88,7 +92,7 @@ void PlacefileSettingsWidgetImpl::ConnectSignals() &OpenUrlDialog::accepted, self_, [this]() - { logger_->info("Add URL: {}", openUrlDialog_->url().toStdString()); }); + { placefileManager_->AddUrl(openUrlDialog_->url().toStdString()); }); QObject::connect(self_->ui->placefileFilter, &QLineEdit::textChanged, diff --git a/wxdata/include/scwx/gr/placefile.hpp b/wxdata/include/scwx/gr/placefile.hpp index 20672008..9a111468 100644 --- a/wxdata/include/scwx/gr/placefile.hpp +++ b/wxdata/include/scwx/gr/placefile.hpp @@ -89,8 +89,7 @@ public: std::shared_ptr font(std::size_t i); static std::shared_ptr Load(const std::string& filename); - static std::shared_ptr Load(const std::string& name, - std::istream& is); + static std::shared_ptr Load(std::istream& is); private: class Impl; diff --git a/wxdata/source/scwx/gr/placefile.cpp b/wxdata/source/scwx/gr/placefile.cpp index a3ef8f16..249d7e89 100644 --- a/wxdata/source/scwx/gr/placefile.cpp +++ b/wxdata/source/scwx/gr/placefile.cpp @@ -110,16 +110,13 @@ std::shared_ptr Placefile::Load(const std::string& filename) { logger_->debug("Loading placefile: {}", filename); std::ifstream f(filename, std::ios_base::in); - return Load(filename, f); + return Load(f); } -std::shared_ptr Placefile::Load(const std::string& name, - std::istream& is) +std::shared_ptr Placefile::Load(std::istream& is) { std::shared_ptr placefile = std::make_shared(); - placefile->p->title_ = name; - std::string line; while (scwx::util::getline(is, line)) {