#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace scwx::qt::ui::setup { static const std::unordered_map kUrl_ { {map::MapProvider::Mapbox, QUrl {"https://www.mapbox.com/"}}, {map::MapProvider::MapTiler, QUrl {"https://www.maptiler.com/"}}}; struct MapProviderGroup { QLabel* apiKeyLabel_ {}; QApiKeyEdit* apiKeyEdit_ {}; }; class MapProviderPage::Impl { public: explicit Impl(MapProviderPage* self) : self_ {self} {}; ~Impl() = default; void SelectMapProvider(const QString& text); void SelectMapProvider(map::MapProvider mapProvider); void SetupMapProviderGroup(const map::MapProvider mapProvider, MapProviderGroup& group, int row); void SetupSettingsInterface(); static void SetGroupVisible(MapProviderGroup& group, bool visible); MapProviderPage* self_; QLayout* layout_ {}; QFrame* mapProviderFrame_ {}; QGridLayout* mapProviderLayout_ {}; QLabel* mapProviderLabel_ {}; QComboBox* mapProviderComboBox_ {}; QLabel* descriptionLabel_ {}; QFrame* buttonFrame_ {}; QHBoxLayout* buttonLayout_ {}; QPushButton* apiKeyButton_ {}; QSpacerItem* buttonSpacer_ {}; MapProviderGroup mapboxGroup_ {}; MapProviderGroup maptilerGroup_ {}; map::MapProvider currentMapProvider_ {}; settings::SettingsInterface mapProvider_ {}; settings::SettingsInterface mapboxApiKey_ {}; settings::SettingsInterface mapTilerApiKey_ {}; std::unordered_map providerGroup_ { {map::MapProvider::Mapbox, mapboxGroup_}, {map::MapProvider::MapTiler, maptilerGroup_}}; }; MapProviderPage::MapProviderPage(QWidget* parent) : QWizardPage(parent), p {std::make_shared(this)} { setTitle(tr("Map Provider")); setSubTitle(tr("Configure the Supercell Wx map provider.")); p->mapProviderFrame_ = new QFrame(this); p->mapProviderLayout_ = new QGridLayout(p->mapProviderFrame_); p->mapProviderLabel_ = new QLabel(this); p->mapProviderComboBox_ = new QComboBox(this); p->descriptionLabel_ = new QLabel(this); p->buttonFrame_ = new QFrame(this); p->buttonLayout_ = new QHBoxLayout(p->buttonFrame_); p->apiKeyButton_ = new QPushButton(this); p->buttonSpacer_ = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); // Map Provider p->mapProviderLabel_->setText(tr("Map Provider")); for (const auto& mapProvider : map::MapProviderIterator()) { p->mapProviderComboBox_->addItem( QString::fromStdString(map::GetMapProviderName(mapProvider))); } p->mapProviderLayout_->setContentsMargins(0, 0, 0, 0); p->mapProviderLayout_->addWidget(p->mapProviderLabel_, 0, 0, 1, 1); p->mapProviderLayout_->addWidget(p->mapProviderComboBox_, 0, 1, 1, 1); p->mapProviderFrame_->setLayout(p->mapProviderLayout_); // Description p->descriptionLabel_->setText( tr("You must get an API key from the map provider. After creating an " "account and reviewing terms of service, create an API key (or public " "token) with default scopes (unless one is created for you). Enter " "this API key here.")); p->descriptionLabel_->setWordWrap(true); // API Key Button p->buttonLayout_->setContentsMargins(0, 0, 0, 0); p->buttonLayout_->addWidget(p->apiKeyButton_); p->buttonLayout_->addItem(p->buttonSpacer_); p->buttonFrame_->setLayout(p->buttonLayout_); p->SetupMapProviderGroup(map::MapProvider::Mapbox, p->mapboxGroup_, 1); p->SetupMapProviderGroup(map::MapProvider::MapTiler, p->maptilerGroup_, 2); // Overall layout p->layout_ = new QVBoxLayout(this); p->layout_->addWidget(p->mapProviderFrame_); p->layout_->addWidget(p->descriptionLabel_); p->layout_->addWidget(p->buttonFrame_); setLayout(p->layout_); // Configure settings interface p->SetupSettingsInterface(); // Connect signals connect(p->mapProviderComboBox_, &QComboBox::currentTextChanged, this, [this](const QString& text) { p->SelectMapProvider(text); }); connect(p->apiKeyButton_, &QAbstractButton::clicked, this, [this]() { QDesktopServices::openUrl(kUrl_.at(p->currentMapProvider_)); }); // Map provider value map::MapProvider currentMapProvider = map::GetMapProvider( settings::GeneralSettings::Instance().map_provider().GetValue()); std::string currentMapProviderName = map::GetMapProviderName(currentMapProvider); p->mapProviderComboBox_->setCurrentText( QString::fromStdString(currentMapProviderName)); p->SelectMapProvider(currentMapProvider); } MapProviderPage::~MapProviderPage() = default; void MapProviderPage::Impl::SetupMapProviderGroup( const map::MapProvider provider, MapProviderGroup& group, int row) { group.apiKeyLabel_ = new QLabel(self_); group.apiKeyEdit_ = new QApiKeyEdit(self_); group.apiKeyEdit_->setMapProvider(provider); group.apiKeyLabel_->setText(tr("API Key")); mapProviderLayout_->addWidget(group.apiKeyLabel_, row, 0, 1, 1); mapProviderLayout_->addWidget(group.apiKeyEdit_, row, 1, 1, 1); QObject::connect(group.apiKeyEdit_, &QApiKeyEdit::textChanged, self_, &QWizardPage::completeChanged); } void MapProviderPage::Impl::SetupSettingsInterface() { auto& generalSettings = settings::GeneralSettings::Instance(); mapProvider_.SetSettingsVariable(generalSettings.map_provider()); mapProvider_.SetMapFromValueFunction( [](const std::string& text) -> std::string { for (map::MapProvider mapProvider : map::MapProviderIterator()) { const std::string mapProviderName = map::GetMapProviderName(mapProvider); if (boost::iequals(text, mapProviderName)) { // Return map provider label return mapProviderName; } } // Map provider label not found, return unknown return "?"; }); mapProvider_.SetMapToValueFunction( [](std::string text) -> std::string { // Convert label to lower case and return boost::to_lower(text); return text; }); mapProvider_.SetEditWidget(mapProviderComboBox_); mapboxApiKey_.SetSettingsVariable(generalSettings.mapbox_api_key()); mapboxApiKey_.EnableTrimming(); mapboxApiKey_.SetEditWidget(mapboxGroup_.apiKeyEdit_); mapTilerApiKey_.SetSettingsVariable(generalSettings.maptiler_api_key()); mapTilerApiKey_.EnableTrimming(); mapTilerApiKey_.SetEditWidget(maptilerGroup_.apiKeyEdit_); } void MapProviderPage::Impl::SelectMapProvider(const QString& text) { SelectMapProvider(map::GetMapProvider(text.toStdString())); } void MapProviderPage::Impl::SelectMapProvider(map::MapProvider mapProvider) { std::string name = map::GetMapProviderName(mapProvider); switch (mapProvider) { case map::MapProvider::Mapbox: SetGroupVisible(mapboxGroup_, true); SetGroupVisible(maptilerGroup_, false); break; case map::MapProvider::MapTiler: SetGroupVisible(mapboxGroup_, false); SetGroupVisible(maptilerGroup_, true); break; default: break; } apiKeyButton_->setText( tr("Get %1 API Key").arg(QString::fromStdString(name))); currentMapProvider_ = mapProvider; Q_EMIT self_->completeChanged(); } void MapProviderPage::Impl::SetGroupVisible(MapProviderGroup& group, bool visible) { group.apiKeyLabel_->setVisible(visible); group.apiKeyEdit_->setVisible(visible); } bool MapProviderPage::isComplete() const { return p->providerGroup_.at(p->currentMapProvider_) .apiKeyEdit_->text() .size() > 1; } bool MapProviderPage::validatePage() { bool committed = false; committed |= p->mapProvider_.Commit(); committed |= p->mapboxApiKey_.Commit(); committed |= p->mapTilerApiKey_.Commit(); if (committed) { manager::SettingsManager::Instance().SaveSettings(); } return true; } bool MapProviderPage::IsRequired() { auto& generalSettings = settings::GeneralSettings::Instance(); std::string mapboxApiKey = generalSettings.mapbox_api_key().GetValue(); std::string maptilerApiKey = generalSettings.maptiler_api_key().GetValue(); // Setup is required if either API key is empty, or contains a single // character ("?") return (mapboxApiKey.size() <= 1 && maptilerApiKey.size() <= 1); } } // namespace scwx::qt::ui::setup