mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:00:05 +00:00
Save (works) and reload (doesn't work) placefiles from settings
This commit is contained in:
parent
ad5c2b583d
commit
6f14745a59
3 changed files with 158 additions and 18 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
#include <scwx/qt/manager/placefile_manager.hpp>
|
#include <scwx/qt/manager/placefile_manager.hpp>
|
||||||
#include <scwx/qt/manager/resource_manager.hpp>
|
#include <scwx/qt/manager/resource_manager.hpp>
|
||||||
|
#include <scwx/qt/util/json.hpp>
|
||||||
#include <scwx/qt/util/network.hpp>
|
#include <scwx/qt/util/network.hpp>
|
||||||
#include <scwx/gr/placefile.hpp>
|
#include <scwx/gr/placefile.hpp>
|
||||||
#include <scwx/network/cpr.hpp>
|
#include <scwx/network/cpr.hpp>
|
||||||
|
|
@ -11,11 +12,13 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
|
#include <QStandardPaths>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/asio/post.hpp>
|
#include <boost/asio/post.hpp>
|
||||||
#include <boost/asio/steady_timer.hpp>
|
#include <boost/asio/steady_timer.hpp>
|
||||||
#include <boost/asio/thread_pool.hpp>
|
#include <boost/asio/thread_pool.hpp>
|
||||||
|
#include <boost/json.hpp>
|
||||||
#include <boost/tokenizer.hpp>
|
#include <boost/tokenizer.hpp>
|
||||||
#include <cpr/cpr.h>
|
#include <cpr/cpr.h>
|
||||||
|
|
||||||
|
|
@ -29,6 +32,11 @@ namespace manager
|
||||||
static const std::string logPrefix_ = "scwx::qt::manager::placefile_manager";
|
static const std::string logPrefix_ = "scwx::qt::manager::placefile_manager";
|
||||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
|
static const std::string kEnabledName_ = "enabled";
|
||||||
|
static const std::string kThresholdedName_ = "thresholded";
|
||||||
|
static const std::string kTitleName_ = "title";
|
||||||
|
static const std::string kNameName_ = "name";
|
||||||
|
|
||||||
class PlacefileManager::Impl
|
class PlacefileManager::Impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -37,12 +45,18 @@ public:
|
||||||
explicit Impl(PlacefileManager* self) : self_ {self} {}
|
explicit Impl(PlacefileManager* self) : self_ {self} {}
|
||||||
~Impl() {}
|
~Impl() {}
|
||||||
|
|
||||||
|
void InitializePlacefileSettings();
|
||||||
|
void ReadPlacefileSettings();
|
||||||
|
void WritePlacefileSettings();
|
||||||
|
|
||||||
static void LoadResources(const std::shared_ptr<gr::Placefile>& placefile);
|
static void LoadResources(const std::shared_ptr<gr::Placefile>& placefile);
|
||||||
|
|
||||||
boost::asio::thread_pool threadPool_ {1u};
|
boost::asio::thread_pool threadPool_ {1u};
|
||||||
|
|
||||||
PlacefileManager* self_;
|
PlacefileManager* self_;
|
||||||
|
|
||||||
|
std::string placefileSettingsPath_ {};
|
||||||
|
|
||||||
std::shared_ptr<config::RadarSite> radarSite_ {};
|
std::shared_ptr<config::RadarSite> radarSite_ {};
|
||||||
|
|
||||||
std::vector<std::shared_ptr<PlacefileRecord>> placefileRecords_ {};
|
std::vector<std::shared_ptr<PlacefileRecord>> placefileRecords_ {};
|
||||||
|
|
@ -57,8 +71,15 @@ public:
|
||||||
explicit PlacefileRecord(Impl* impl,
|
explicit PlacefileRecord(Impl* impl,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
std::shared_ptr<gr::Placefile> placefile,
|
std::shared_ptr<gr::Placefile> placefile,
|
||||||
bool enabled = true) :
|
const std::string& title = {},
|
||||||
p {impl}, name_ {name}, placefile_ {placefile}, enabled_ {enabled}
|
bool enabled = false,
|
||||||
|
bool thresholded = false) :
|
||||||
|
p {impl},
|
||||||
|
name_ {name},
|
||||||
|
placefile_ {placefile},
|
||||||
|
title_ {title},
|
||||||
|
enabled_ {enabled},
|
||||||
|
thresholded_ {thresholded}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
~PlacefileRecord()
|
~PlacefileRecord()
|
||||||
|
|
@ -71,19 +92,56 @@ public:
|
||||||
void UpdateAsync();
|
void UpdateAsync();
|
||||||
void UpdatePlacefile(const std::shared_ptr<gr::Placefile>& placefile);
|
void UpdatePlacefile(const std::shared_ptr<gr::Placefile>& placefile);
|
||||||
|
|
||||||
|
friend void tag_invoke(boost::json::value_from_tag,
|
||||||
|
boost::json::value& jv,
|
||||||
|
const std::shared_ptr<PlacefileRecord>& record)
|
||||||
|
{
|
||||||
|
jv = {{kEnabledName_, record->enabled_},
|
||||||
|
{kThresholdedName_, record->thresholded_},
|
||||||
|
{kTitleName_, record->title_},
|
||||||
|
{kNameName_, record->name_}};
|
||||||
|
}
|
||||||
|
|
||||||
|
friend PlacefileRecord tag_invoke(boost::json::value_to_tag<PlacefileRecord>,
|
||||||
|
const boost::json::value& jv)
|
||||||
|
{
|
||||||
|
return PlacefileRecord {
|
||||||
|
nullptr,
|
||||||
|
boost::json::value_to<std::string>(jv.at(kNameName_)),
|
||||||
|
nullptr,
|
||||||
|
boost::json::value_to<std::string>(jv.at(kTitleName_)),
|
||||||
|
jv.at(kEnabledName_).as_bool(),
|
||||||
|
jv.at(kThresholdedName_).as_bool()};
|
||||||
|
}
|
||||||
|
|
||||||
Impl* p;
|
Impl* p;
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
std::string title_;
|
||||||
std::shared_ptr<gr::Placefile> placefile_;
|
std::shared_ptr<gr::Placefile> placefile_;
|
||||||
bool enabled_;
|
bool enabled_;
|
||||||
bool thresholded_ {false};
|
bool thresholded_;
|
||||||
boost::asio::thread_pool threadPool_ {1u};
|
boost::asio::thread_pool threadPool_ {1u};
|
||||||
boost::asio::steady_timer refreshTimer_ {threadPool_};
|
boost::asio::steady_timer refreshTimer_ {threadPool_};
|
||||||
std::mutex refreshMutex_ {};
|
std::mutex refreshMutex_ {};
|
||||||
};
|
};
|
||||||
|
|
||||||
PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this)) {}
|
PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this))
|
||||||
PlacefileManager::~PlacefileManager() = default;
|
{
|
||||||
|
boost::asio::post(p->threadPool_,
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
// Read placefile settings on startup
|
||||||
|
p->InitializePlacefileSettings();
|
||||||
|
p->ReadPlacefileSettings();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
PlacefileManager::~PlacefileManager()
|
||||||
|
{
|
||||||
|
// Write placefile settings on shutdown
|
||||||
|
p->WritePlacefileSettings();
|
||||||
|
};
|
||||||
|
|
||||||
bool PlacefileManager::placefile_enabled(const std::string& name)
|
bool PlacefileManager::placefile_enabled(const std::string& name)
|
||||||
{
|
{
|
||||||
|
|
@ -109,6 +167,18 @@ bool PlacefileManager::placefile_thresholded(const std::string& name)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PlacefileManager::placefile_title(const std::string& name)
|
||||||
|
{
|
||||||
|
std::shared_lock lock(p->placefileRecordLock_);
|
||||||
|
|
||||||
|
auto it = p->placefileRecordMap_.find(name);
|
||||||
|
if (it != p->placefileRecordMap_.cend())
|
||||||
|
{
|
||||||
|
return it->second->title_;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<gr::Placefile>
|
std::shared_ptr<gr::Placefile>
|
||||||
PlacefileManager::placefile(const std::string& name)
|
PlacefileManager::placefile(const std::string& name)
|
||||||
{
|
{
|
||||||
|
|
@ -189,6 +259,71 @@ void PlacefileManager::set_placefile_url(const std::string& name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlacefileManager::Impl::InitializePlacefileSettings()
|
||||||
|
{
|
||||||
|
std::string appDataPath {
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)
|
||||||
|
.toStdString()};
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(appDataPath))
|
||||||
|
{
|
||||||
|
if (!std::filesystem::create_directories(appDataPath))
|
||||||
|
{
|
||||||
|
logger_->error("Unable to create application data directory: \"{}\"",
|
||||||
|
appDataPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
placefileSettingsPath_ = appDataPath + "/placefiles.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlacefileManager::Impl::ReadPlacefileSettings()
|
||||||
|
{
|
||||||
|
logger_->info("Reading placefile settings");
|
||||||
|
|
||||||
|
boost::json::value placefileJson = nullptr;
|
||||||
|
|
||||||
|
// Determine if placefile settings exists
|
||||||
|
if (std::filesystem::exists(placefileSettingsPath_))
|
||||||
|
{
|
||||||
|
placefileJson = util::json::ReadJsonFile(placefileSettingsPath_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If placefile settings was successfully read
|
||||||
|
if (placefileJson != nullptr && placefileJson.is_array())
|
||||||
|
{
|
||||||
|
// For each placefile entry
|
||||||
|
auto& placefileArray = placefileJson.as_array();
|
||||||
|
for (auto& placefileEntry : placefileArray)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Convert placefile entry to a record
|
||||||
|
PlacefileRecord record =
|
||||||
|
boost::json::value_to<PlacefileRecord>(placefileEntry);
|
||||||
|
|
||||||
|
self_->AddUrl(record.name_,
|
||||||
|
record.title_,
|
||||||
|
record.enabled_,
|
||||||
|
record.thresholded_);
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
logger_->warn("Invalid placefile entry: {}", ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlacefileManager::Impl::WritePlacefileSettings()
|
||||||
|
{
|
||||||
|
logger_->info("Saving placefile settings");
|
||||||
|
|
||||||
|
std::shared_lock lock {placefileRecordLock_};
|
||||||
|
auto placefileJson = boost::json::value_from(placefileRecords_);
|
||||||
|
util::json::WriteJsonFile(placefileSettingsPath_, placefileJson);
|
||||||
|
}
|
||||||
|
|
||||||
void PlacefileManager::SetRadarSite(
|
void PlacefileManager::SetRadarSite(
|
||||||
std::shared_ptr<config::RadarSite> radarSite)
|
std::shared_ptr<config::RadarSite> radarSite)
|
||||||
{
|
{
|
||||||
|
|
@ -231,7 +366,10 @@ PlacefileManager::GetActivePlacefiles()
|
||||||
return placefiles;
|
return placefiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlacefileManager::AddUrl(const std::string& urlString)
|
void PlacefileManager::AddUrl(const std::string& urlString,
|
||||||
|
const std::string& title,
|
||||||
|
bool enabled,
|
||||||
|
bool thresholded)
|
||||||
{
|
{
|
||||||
std::string normalizedUrl = util::network::NormalizeUrl(urlString);
|
std::string normalizedUrl = util::network::NormalizeUrl(urlString);
|
||||||
|
|
||||||
|
|
@ -254,7 +392,7 @@ void PlacefileManager::AddUrl(const std::string& urlString)
|
||||||
// Add an empty placefile record for the new URL
|
// Add an empty placefile record for the new URL
|
||||||
auto& record =
|
auto& record =
|
||||||
p->placefileRecords_.emplace_back(std::make_shared<Impl::PlacefileRecord>(
|
p->placefileRecords_.emplace_back(std::make_shared<Impl::PlacefileRecord>(
|
||||||
p.get(), normalizedUrl, nullptr, false));
|
p.get(), normalizedUrl, nullptr, title, enabled, thresholded));
|
||||||
p->placefileRecordMap_.insert_or_assign(normalizedUrl, record);
|
p->placefileRecordMap_.insert_or_assign(normalizedUrl, record);
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
@ -303,7 +441,7 @@ void PlacefileManager::LoadFile(const std::string& filename)
|
||||||
// If this is a new placefile, add it
|
// If this is a new placefile, add it
|
||||||
auto& record = p->placefileRecords_.emplace_back(
|
auto& record = p->placefileRecords_.emplace_back(
|
||||||
std::make_shared<Impl::PlacefileRecord>(
|
std::make_shared<Impl::PlacefileRecord>(
|
||||||
p.get(), placefileName, placefile));
|
p.get(), placefileName, placefile, placefile->title(), true));
|
||||||
p->placefileRecordMap_.insert_or_assign(placefileName, record);
|
p->placefileRecordMap_.insert_or_assign(placefileName, record);
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
@ -434,6 +572,7 @@ void PlacefileManager::Impl::PlacefileRecord::Update()
|
||||||
{
|
{
|
||||||
// Update the placefile
|
// Update the placefile
|
||||||
placefile_ = updatedPlacefile;
|
placefile_ = updatedPlacefile;
|
||||||
|
title_ = placefile_->title();
|
||||||
|
|
||||||
// Notify slots of the placefile update
|
// Notify slots of the placefile update
|
||||||
Q_EMIT p->self_->PlacefileUpdated(name);
|
Q_EMIT p->self_->PlacefileUpdated(name);
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,9 @@ public:
|
||||||
explicit PlacefileManager();
|
explicit PlacefileManager();
|
||||||
~PlacefileManager();
|
~PlacefileManager();
|
||||||
|
|
||||||
bool placefile_enabled(const std::string& name);
|
bool placefile_enabled(const std::string& name);
|
||||||
bool placefile_thresholded(const std::string& name);
|
bool placefile_thresholded(const std::string& name);
|
||||||
|
std::string placefile_title(const std::string& name);
|
||||||
std::shared_ptr<gr::Placefile> placefile(const std::string& name);
|
std::shared_ptr<gr::Placefile> placefile(const std::string& name);
|
||||||
|
|
||||||
void set_placefile_enabled(const std::string& name, bool enabled);
|
void set_placefile_enabled(const std::string& name, bool enabled);
|
||||||
|
|
@ -37,7 +38,10 @@ public:
|
||||||
*/
|
*/
|
||||||
std::vector<std::shared_ptr<gr::Placefile>> GetActivePlacefiles();
|
std::vector<std::shared_ptr<gr::Placefile>> GetActivePlacefiles();
|
||||||
|
|
||||||
void AddUrl(const std::string& urlString);
|
void AddUrl(const std::string& urlString,
|
||||||
|
const std::string& title = {},
|
||||||
|
bool enabled = false,
|
||||||
|
bool thresholded = false);
|
||||||
void LoadFile(const std::string& filename);
|
void LoadFile(const std::string& filename);
|
||||||
void RemoveUrl(const std::string& urlString);
|
void RemoveUrl(const std::string& urlString);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,14 +159,11 @@ QVariant PlacefileModel::data(const QModelIndex& index, int role) const
|
||||||
role == Qt::ItemDataRole::ToolTipRole)
|
role == Qt::ItemDataRole::ToolTipRole)
|
||||||
{
|
{
|
||||||
std::string description = placefileName;
|
std::string description = placefileName;
|
||||||
auto placefile = p->placefileManager_->placefile(placefileName);
|
std::string title =
|
||||||
if (placefile != nullptr)
|
p->placefileManager_->placefile_title(placefileName);
|
||||||
|
if (!title.empty())
|
||||||
{
|
{
|
||||||
std::string title = placefile->title();
|
description = title + '\n' + description;
|
||||||
if (!title.empty())
|
|
||||||
{
|
|
||||||
description = title + '\n' + description;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QString::fromStdString(description);
|
return QString::fromStdString(description);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue