Skip to content

Commit 3a8526d

Browse files
authored
Merge pull request #596 from dpaulat/feature/map-provider-and-api-key-hot-change
Map Provider and API Key changes no longer require restart
2 parents 56bc8f7 + 538b6fe commit 3a8526d

16 files changed

+485
-200
lines changed

scwx-qt/source/scwx/qt/main/main.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <QTranslator>
3535
#include <QPalette>
3636
#include <QStyle>
37+
#include <QSysInfo>
3738

3839
#define QT6CT_LIBRARY
3940
#include <qt6ct-common/qt6ct.h>
@@ -65,6 +66,7 @@ int main(int argc, char* argv[])
6566
logManager.Initialize();
6667

6768
QCoreApplication::setApplicationName("Supercell Wx");
69+
const std::string osName = QSysInfo::prettyProductName().toStdString();
6870

6971
logManager.InitializeLogFile();
7072

@@ -74,13 +76,14 @@ int main(int argc, char* argv[])
7476
scwx::qt::main::kCommitString_);
7577
logger_->info("Qt version {}",
7678
QLibraryInfo::version().toString().toStdString());
79+
logger_->info("Running on {}", osName);
7780

7881
InitializeOpenGL();
7982

8083
QApplication a(argc, argv);
8184

82-
scwx::network::cpr::SetUserAgent(
83-
fmt::format("SupercellWx/{}", scwx::qt::main::kVersionString_));
85+
scwx::network::cpr::SetUserAgent(fmt::format(
86+
"SupercellWx/{} ({})", scwx::qt::main::kVersionString_, osName));
8487

8588
// Enable internationalization support
8689
QTranslator translator;

scwx-qt/source/scwx/qt/main/main_window.cpp

Lines changed: 69 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include <QFileDialog>
5656
#include <QMessageBox>
5757
#include <QScreen>
58+
#include <QSignalBlocker>
5859
#include <QSplitter>
5960
#include <QStandardPaths>
6061
#include <QTimer>
@@ -93,16 +94,9 @@ class MainWindowImpl : public QObject
9394
updateManager_ {manager::UpdateManager::Instance()},
9495
maps_ {}
9596
{
96-
mapProvider_ = map::GetMapProvider(
97-
settings::GeneralSettings::Instance().map_provider().GetValue());
98-
const map::MapProviderInfo& mapProviderInfo =
99-
map::GetMapProviderInfo(mapProvider_);
100-
10197
std::string appDataPath {
10298
QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
10399
.toStdString()};
104-
std::string cacheDbPath {appDataPath + "/" +
105-
mapProviderInfo.cacheDbName_};
106100

107101
if (!std::filesystem::exists(appDataPath))
108102
{
@@ -114,35 +108,25 @@ class MainWindowImpl : public QObject
114108
}
115109
}
116110

117-
std::string mapProviderApiKey = map::GetMapProviderApiKey(mapProvider_);
118-
119-
if (mapProvider_ == map::MapProvider::Mapbox)
120-
{
121-
settings_.setProviderTemplate(mapProviderInfo.providerTemplate_);
122-
settings_.setApiKey(QString {mapProviderApiKey.c_str()});
123-
}
124-
settings_.setCacheDatabasePath(QString {cacheDbPath.c_str()});
125-
settings_.setCacheDatabaseMaximumSize(20 * 1024 * 1024);
111+
mapProvider_ = map::GetMapProvider(
112+
settings::GeneralSettings::Instance().map_provider().GetValue());
113+
map::ConfigureMapSettings(mapProvider_, settings_);
126114

127115
if (settings::GeneralSettings::Instance().track_location().GetValue())
128116
{
129117
positionManager_->TrackLocation(true);
130118
}
131119
}
120+
132121
~MainWindowImpl()
133122
{
134123
homeRadarConnection_.disconnect();
124+
clockFormatConnection_.disconnect();
135125
defaultTimeZoneConnection_.disconnect();
136-
137-
auto& generalSettings = settings::GeneralSettings::Instance();
138-
139-
auto& customStyleUrl = generalSettings.custom_style_url();
140-
auto& customStyleDrawLayer = generalSettings.custom_style_draw_layer();
141-
142-
customStyleUrl.UnregisterValueChangedCallback(
143-
customStyleUrlChangedCallbackUuid_);
144-
customStyleDrawLayer.UnregisterValueChangedCallback(
145-
customStyleDrawLayerChangedCallbackUuid_);
126+
for (auto& connection : connections_)
127+
{
128+
connection.disconnect();
129+
}
146130

147131
clockTimer_.stop();
148132
threadPool_.join();
@@ -214,9 +198,9 @@ class MainWindowImpl : public QObject
214198

215199
QTimer clockTimer_ {};
216200

217-
bool customStyleAvailable_ {false};
218-
boost::uuids::uuid customStyleDrawLayerChangedCallbackUuid_ {};
219-
boost::uuids::uuid customStyleUrlChangedCallbackUuid_ {};
201+
bool customStyleAvailable_ {false};
202+
203+
std::vector<boost::signals2::scoped_connection> connections_ {};
220204

221205
#ifdef Q_OS_WIN
222206
QRect priorFullScreenGeometry_ {};
@@ -907,29 +891,38 @@ void MainWindowImpl::ConfigureMapStyles()
907891

908892
for (std::size_t i = 0; i < maps_.size(); i++)
909893
{
910-
std::string styleName = mapSettings.map_style(i).GetValue();
911-
912-
if ((customStyleAvailable_ && styleName == "Custom") ||
913-
styleName == "None" ||
914-
std::ranges::find_if(mapProviderInfo.mapStyles_,
915-
[&](const auto& mapStyle)
916-
{ return mapStyle.name_ == styleName; }) !=
917-
mapProviderInfo.mapStyles_.cend())
894+
const std::string configuredStyleName =
895+
mapSettings.map_style(i).GetValue();
896+
std::string styleName = configuredStyleName;
897+
898+
if (!((customStyleAvailable_ && styleName == "Custom") ||
899+
styleName == "None" ||
900+
std::ranges::find_if(mapProviderInfo.mapStyles_,
901+
[&](const auto& mapStyle)
902+
{ return mapStyle.name_ == styleName; }) !=
903+
mapProviderInfo.mapStyles_.cend()))
918904
{
919-
// Initialize map style from settings
920-
maps_.at(i)->SetInitialMapStyle(styleName);
905+
styleName = !mapProviderInfo.mapStyles_.empty() ?
906+
mapProviderInfo.mapStyles_.at(0).name_ :
907+
"None";
908+
}
921909

922-
// Update the active map's style
923-
if (maps_[i] == activeMap_)
924-
{
925-
UpdateMapStyle(styleName);
926-
}
910+
const std::string currentStyleName = maps_.at(i)->GetMapStyle();
911+
if (currentStyleName != "?")
912+
{
913+
styleName = currentStyleName;
914+
}
915+
916+
maps_.at(i)->SetInitialMapStyle(styleName);
917+
918+
if (maps_[i] == activeMap_)
919+
{
920+
UpdateMapStyle(styleName);
927921
}
928-
else if (!mapProviderInfo.mapStyles_.empty())
922+
923+
if (configuredStyleName != styleName)
929924
{
930-
// Stage first valid map style from map provider
931-
mapSettings.map_style(i).StageValue(
932-
mapProviderInfo.mapStyles_.at(0).name_);
925+
mapSettings.map_style(i).StageValue(styleName);
933926
}
934927
}
935928
}
@@ -1398,14 +1391,11 @@ void MainWindowImpl::ConnectOtherSignals()
13981391
auto& generalSettings = settings::GeneralSettings::Instance();
13991392
homeRadarConnection_ =
14001393
generalSettings.default_radar_site().changed_signal().connect(
1401-
[this]()
1394+
[this](const auto& event)
14021395
{
14031396
const std::shared_ptr<config::RadarSite> radarSite =
14041397
activeMap_->GetRadarSite();
1405-
const std::string homeRadarSite =
1406-
settings::GeneralSettings::Instance()
1407-
.default_radar_site()
1408-
.GetValue();
1398+
const std::string& homeRadarSite = event.newValue_;
14091399
if (radarSite == nullptr)
14101400
{
14111401
mainWindow_->ui->saveRadarProductsButton->setVisible(false);
@@ -1419,21 +1409,36 @@ void MainWindowImpl::ConnectOtherSignals()
14191409

14201410
clockFormatConnection_ =
14211411
generalSettings.clock_format().changed_signal().connect(
1422-
[]()
1412+
[](const auto& event)
14231413
{
1424-
auto& generalSettings = settings::GeneralSettings::Instance();
14251414
util::time::set_default_clock_format(
1426-
util::GetClockFormat(generalSettings.clock_format().GetValue()));
1415+
util::GetClockFormat(event.newValue_));
14271416
});
14281417
defaultTimeZoneConnection_ =
14291418
generalSettings.default_time_zone().changed_signal().connect(
1430-
[this]()
1419+
[this](auto&&...)
14311420
{
14321421
const auto defaultTimeZone = activeMap_->GetDefaultTimeZone();
14331422
util::time::set_current_time_zone(defaultTimeZone);
14341423
animationDockWidget_->UpdateTimeZone(defaultTimeZone);
14351424
});
14361425

1426+
connections_.emplace_back(
1427+
generalSettings.custom_style_url().changed_signal().connect(
1428+
[this](auto&&...) { PopulateCustomMapStyle(); }));
1429+
connections_.emplace_back(
1430+
generalSettings.custom_style_draw_layer().changed_signal().connect(
1431+
[this](auto&&...) { PopulateCustomMapStyle(); }));
1432+
1433+
connections_.emplace_back(
1434+
generalSettings.map_provider().changed_signal().connect(
1435+
[this](const auto& event)
1436+
{
1437+
mapProvider_ = map::GetMapProvider(event.newValue_);
1438+
PopulateMapStyles();
1439+
ConfigureMapStyles();
1440+
}));
1441+
14371442
// Ensure default clock format is initialized
14381443
util::time::set_default_clock_format(
14391444
util::GetClockFormat(generalSettings.clock_format().GetValue()));
@@ -1552,6 +1557,10 @@ void MainWindowImpl::PopulateCustomMapStyle()
15521557

15531558
void MainWindowImpl::PopulateMapStyles()
15541559
{
1560+
const QSignalBlocker blocker(mainWindow_->ui->mapStyleComboBox);
1561+
1562+
mainWindow_->ui->mapStyleComboBox->clear();
1563+
15551564
const auto& mapProviderInfo = map::GetMapProviderInfo(mapProvider_);
15561565
for (const auto& mapStyle : mapProviderInfo.mapStyles_)
15571566
{
@@ -1562,19 +1571,8 @@ void MainWindowImpl::PopulateMapStyles()
15621571
const std::string kNone = "None";
15631572
mainWindow_->ui->mapStyleComboBox->addItem(QString::fromStdString(kNone));
15641573

1565-
auto& generalSettings = settings::GeneralSettings::Instance();
1566-
1567-
auto& customStyleUrl = generalSettings.custom_style_url();
1568-
auto& customStyleDrawLayer = generalSettings.custom_style_draw_layer();
1569-
1570-
customStyleUrlChangedCallbackUuid_ =
1571-
customStyleUrl.RegisterValueChangedCallback(
1572-
[this]([[maybe_unused]] const std::string& value)
1573-
{ PopulateCustomMapStyle(); });
1574-
customStyleDrawLayerChangedCallbackUuid_ =
1575-
customStyleDrawLayer.RegisterValueChangedCallback(
1576-
[this]([[maybe_unused]] const std::string& value)
1577-
{ PopulateCustomMapStyle(); });
1574+
// The combobox was cleared above, so force re-evaluation of custom style.
1575+
customStyleAvailable_ = false;
15781576

15791577
PopulateCustomMapStyle();
15801578
}
@@ -1660,6 +1658,7 @@ void MainWindowImpl::UpdateMapStyle(const std::string& styleName)
16601658
QString::fromStdString(styleName));
16611659
if (index != -1)
16621660
{
1661+
const QSignalBlocker blocker(mainWindow_->ui->mapStyleComboBox);
16631662
mainWindow_->ui->mapStyleComboBox->setCurrentIndex(index);
16641663

16651664
// Update settings for active map

scwx-qt/source/scwx/qt/manager/placefile_manager.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,11 +653,15 @@ void PlacefileManager::Impl::PlacefileRecord::Update()
653653
}
654654
else if (response.status_code == 0 && enabled_)
655655
{
656-
logger_->error("Error loading placefile: {}", response.error.message);
656+
logger_->error("Error loading placefile: {} ({})",
657+
decodedUrl,
658+
response.error.message);
657659
}
658660
else if (enabled_)
659661
{
660-
logger_->error("Error loading placefile: {}", response.status_line);
662+
logger_->error("Error loading placefile: {} ({})",
663+
decodedUrl,
664+
response.status_line);
661665
}
662666
else
663667
{

scwx-qt/source/scwx/qt/map/map_provider.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <unordered_map>
55

66
#include <boost/algorithm/string.hpp>
7+
#include <QStandardPaths>
78

89
namespace scwx::qt::map
910
{
@@ -185,6 +186,38 @@ bool MapStyle::IsValid() const
185186
return !url_.empty() && !drawBelow_.empty();
186187
}
187188

189+
void ConfigureMapSettings(MapProvider mapProvider,
190+
QMapLibre::Settings& settings)
191+
{
192+
static constexpr std::size_t kMaxCacheSize =
193+
20ull * 1024ull * 1024ull; // 20 MB
194+
195+
const auto& mapProviderInfo = GetMapProviderInfo(mapProvider);
196+
197+
const std::string appDataPath {
198+
QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
199+
.toStdString()};
200+
const std::string cacheDbPath {appDataPath + "/" +
201+
mapProviderInfo.cacheDbName_};
202+
203+
const std::string mapProviderApiKey = map::GetMapProviderApiKey(mapProvider);
204+
205+
if (mapProvider == map::MapProvider::Mapbox)
206+
{
207+
settings.setProviderTemplate(mapProviderInfo.providerTemplate_);
208+
settings.setApiKey(QString {mapProviderApiKey.c_str()});
209+
}
210+
else
211+
{
212+
settings.setProviderTemplate(
213+
QMapLibre::Settings::ProviderTemplate::NoProvider);
214+
settings.setApiKey({});
215+
}
216+
217+
settings.setCacheDatabasePath(QString {cacheDbPath.c_str()});
218+
settings.setCacheDatabaseMaximumSize(kMaxCacheSize);
219+
}
220+
188221
MapProvider GetMapProvider(const std::string& name)
189222
{
190223
auto result =

scwx-qt/source/scwx/qt/map/map_provider.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ struct MapProviderInfo
3535
std::vector<MapStyle> mapStyles_ {};
3636
};
3737

38+
void ConfigureMapSettings(MapProvider mapProvider,
39+
QMapLibre::Settings& settings);
3840
MapProvider GetMapProvider(const std::string& name);
3941
std::string GetMapProviderName(MapProvider mapProvider);
4042
std::string GetMapProviderApiKey(MapProvider mapProvider);

0 commit comments

Comments
 (0)