diff --git a/src/modules/locale/Config.cpp b/src/modules/locale/Config.cpp index fc797c0aa..42b6d616f 100644 --- a/src/modules/locale/Config.cpp +++ b/src/modules/locale/Config.cpp @@ -26,6 +26,8 @@ #include "JobQueue.h" #include "Settings.h" #include "locale/Label.h" +#include "modulesystem/ModuleManager.h" +#include "network/Manager.h" #include "utils/Logger.h" #include "utils/Variant.h" @@ -204,6 +206,15 @@ Config::timezoneData() const return ::timezoneData(); } +void +Config::setCurrentLocation() +{ + if ( !m_currentLocation && m_startingTimezone.isValid() ) + { + setCurrentLocation( m_startingTimezone.first, m_startingTimezone.second ); + } +} + void Config::setCurrentLocation( const QString& regionName, const QString& zoneName ) { @@ -252,7 +263,6 @@ Config::setCurrentLocation( const CalamaresUtils::Locale::TZZone* location ) } } - LocaleConfiguration Config::automaticLocaleConfiguration() const { @@ -341,8 +351,8 @@ getLocaleGenLines( const QVariantMap& configurationMap, QStringList& localeGenLi static inline void getAdjustLiveTimezone( const QVariantMap& configurationMap, bool& adjustLiveTimezone ) { - adjustLiveTimezone - = CalamaresUtils::getBool( configurationMap, "adjustLiveTimezone", Calamares::Settings::instance()->doChroot() ); + adjustLiveTimezone = CalamaresUtils::getBool( + configurationMap, "adjustLiveTimezone", Calamares::Settings::instance()->doChroot() ); #ifdef DEBUG_TIMEZONES if ( m_adjustLiveTimezone ) { @@ -411,6 +421,12 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) getAdjustLiveTimezone( configurationMap, m_adjustLiveTimezone ); getStartingTimezone( configurationMap, m_startingTimezone ); getGeoIP( configurationMap, m_geoip ); + + if ( m_geoip && m_geoip->isValid() ) + { + connect( + Calamares::ModuleManager::instance(), &Calamares::ModuleManager::modulesLoaded, this, &Config::startGeoIP ); + } } Calamares::JobList @@ -427,3 +443,42 @@ Config::createJobs() return list; } + +void +Config::startGeoIP() +{ + if ( m_geoip && m_geoip->isValid() ) + { + auto& network = CalamaresUtils::Network::Manager::instance(); + if ( network.hasInternet() || network.synchronousPing( m_geoip->url() ) ) + { + using Watcher = QFutureWatcher< CalamaresUtils::GeoIP::RegionZonePair >; + m_geoipWatcher = std::make_unique< Watcher >(); + m_geoipWatcher->setFuture( m_geoip->query() ); + connect( m_geoipWatcher.get(), &Watcher::finished, this, &Config::completeGeoIP ); + } + } +} + +void +Config::completeGeoIP() +{ + if ( !currentLocation() ) + { + auto r = m_geoipWatcher->result(); + if ( r.isValid() ) + { + m_startingTimezone = r; + } + else + { + cWarning() << "GeoIP returned invalid result."; + } + } + else + { + cWarning() << "GeoIP result ignored because a location is already set."; + } + m_geoipWatcher.reset(); + m_geoip.reset(); +} diff --git a/src/modules/locale/Config.h b/src/modules/locale/Config.h index 421bb7998..3d048bc28 100644 --- a/src/modules/locale/Config.h +++ b/src/modules/locale/Config.h @@ -28,6 +28,7 @@ #include "geoip/Interface.h" #include "locale/TimeZone.h" +#include #include #include @@ -59,7 +60,6 @@ public: /** @brief The currently selected location (timezone) * * The location is a pointer into the date that timezoneData() returns. - * It is possible to return nullptr, if no location has been picked yet. */ const CalamaresUtils::Locale::TZZone* currentLocation() const { return m_currentLocation; } @@ -79,6 +79,9 @@ public: CalamaresUtils::Locale::CStringListModel* regionModel() const { return m_regionModel.get(); } CalamaresUtils::Locale::CStringListModel* zonesModel() const { return m_zonesModel.get(); } + /// Special case, set location from starting timezone if not already set + void setCurrentLocation(); + public Q_SLOTS: /// Set a language by user-choice, overriding future location changes void setLanguageExplicitly( const QString& language ); @@ -149,6 +152,11 @@ private: * by explicitly calling *TODO* */ std::unique_ptr< CalamaresUtils::GeoIP::Handler > m_geoip; + + // Implementation details for doing GeoIP lookup + void startGeoIP(); + void completeGeoIP(); + std::unique_ptr< QFutureWatcher< CalamaresUtils::GeoIP::RegionZonePair > > m_geoipWatcher; }; diff --git a/src/modules/locale/LocaleViewStep.cpp b/src/modules/locale/LocaleViewStep.cpp index 5baf68b43..8ae894aa8 100644 --- a/src/modules/locale/LocaleViewStep.cpp +++ b/src/modules/locale/LocaleViewStep.cpp @@ -43,7 +43,6 @@ LocaleViewStep::LocaleViewStep( QObject* parent ) , m_widget( new QWidget() ) , m_actualWidget( nullptr ) , m_nextEnabled( false ) - , m_geoip( nullptr ) , m_config( std::make_unique< Config >() ) { QBoxLayout* mainLayout = new QHBoxLayout; @@ -66,11 +65,11 @@ LocaleViewStep::~LocaleViewStep() void LocaleViewStep::setUpPage() { + m_config->setCurrentLocation(); if ( !m_actualWidget ) { m_actualWidget = new LocalePage( m_config.get() ); } - m_config->setCurrentLocation( m_startingTimezone.first, m_startingTimezone.second ); m_widget->layout()->addWidget( m_actualWidget ); ensureSize( m_actualWidget->sizeHint() ); @@ -80,20 +79,6 @@ LocaleViewStep::setUpPage() } -void -LocaleViewStep::fetchGeoIpTimezone() -{ - if ( m_geoip && m_geoip->isValid() ) - { - m_startingTimezone = m_geoip->get(); - if ( !m_startingTimezone.isValid() ) - { - cWarning() << "GeoIP lookup at" << m_geoip->url() << "failed."; - } - } -} - - QString LocaleViewStep::prettyName() const { @@ -171,54 +156,5 @@ LocaleViewStep::onLeave() void LocaleViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { - QString region = CalamaresUtils::getString( configurationMap, "region" ); - QString zone = CalamaresUtils::getString( configurationMap, "zone" ); - if ( !region.isEmpty() && !zone.isEmpty() ) - { - m_startingTimezone = CalamaresUtils::GeoIP::RegionZonePair( region, zone ); - } - else - { - m_startingTimezone - = CalamaresUtils::GeoIP::RegionZonePair( QStringLiteral( "America" ), QStringLiteral( "New_York" ) ); - } - - bool ok = false; - QVariantMap geoip = CalamaresUtils::getSubMap( configurationMap, "geoip", ok ); - if ( ok ) - { - QString url = CalamaresUtils::getString( geoip, "url" ); - QString style = CalamaresUtils::getString( geoip, "style" ); - QString selector = CalamaresUtils::getString( geoip, "selector" ); - - m_geoip = std::make_unique< CalamaresUtils::GeoIP::Handler >( style, url, selector ); - if ( !m_geoip->isValid() ) - { - cWarning() << "GeoIP Style" << style << "is not recognized."; - } - } - m_config->setConfigurationMap( configurationMap ); } - -Calamares::RequirementsList -LocaleViewStep::checkRequirements() -{ - if ( m_geoip && m_geoip->isValid() ) - { - auto& network = CalamaresUtils::Network::Manager::instance(); - if ( network.hasInternet() ) - { - fetchGeoIpTimezone(); - } - else - { - if ( network.synchronousPing( m_geoip->url() ) ) - { - fetchGeoIpTimezone(); - } - } - } - - return Calamares::RequirementsList(); -} diff --git a/src/modules/locale/LocaleViewStep.h b/src/modules/locale/LocaleViewStep.h index a1456764f..f02a3205d 100644 --- a/src/modules/locale/LocaleViewStep.h +++ b/src/modules/locale/LocaleViewStep.h @@ -58,22 +58,15 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; - /// @brief Do setup (returns empty list) asynchronously - virtual Calamares::RequirementsList checkRequirements() override; - private slots: void setUpPage(); private: - void fetchGeoIpTimezone(); QWidget* m_widget; LocalePage* m_actualWidget; bool m_nextEnabled; - CalamaresUtils::GeoIP::RegionZonePair m_startingTimezone; - std::unique_ptr< CalamaresUtils::GeoIP::Handler > m_geoip; - std::unique_ptr< Config > m_config; };