From 8119c7e72a861df5d85394cd602963d86e059cc9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Jul 2020 12:37:27 +0200 Subject: [PATCH] [locale] Reset Config object The Config object wasn't being used at all in the locale module; reset it to empty and start using it in locale, so that configuration functionality can be added to it as-needed, and with the necessary refactoring built-in. --- src/modules/locale/Config.cpp | 306 +------------------------- src/modules/locale/Config.h | 56 +---- src/modules/locale/LocaleViewStep.cpp | 4 +- src/modules/locale/LocaleViewStep.h | 10 +- 4 files changed, 17 insertions(+), 359 deletions(-) diff --git a/src/modules/locale/Config.cpp b/src/modules/locale/Config.cpp index cde0a5e09..ae8595734 100644 --- a/src/modules/locale/Config.cpp +++ b/src/modules/locale/Config.cpp @@ -1,7 +1,8 @@ /* === This file is part of Calamares - === * - * Copyright 2019-2020, Adriaan de Groot - * Copyright 2020, Camilo Higuita + * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * License-Filename: LICENSE * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,313 +20,16 @@ #include "Config.h" -#include "LCLocaleDialog.h" -#include "SetTimezoneJob.h" -#include "timezonewidget/timezonewidget.h" - -#include "GlobalStorage.h" -#include "JobQueue.h" -#include "Settings.h" - -#include "locale/Label.h" -#include "locale/TimeZone.h" -#include "utils/CalamaresUtilsGui.h" #include "utils/Logger.h" -#include "utils/Retranslator.h" - -#include -#include -#include Config::Config( QObject* parent ) : QObject( parent ) - , m_regionList( CalamaresUtils::Locale::TZRegion::fromZoneTab() ) - , m_regionModel( new CalamaresUtils::Locale::CStringListModel( m_regionList ) ) - , m_zonesModel( new CalamaresUtils::Locale::CStringListModel() ) - , m_blockTzWidgetSet( false ) { - connect( m_regionModel, &CalamaresUtils::Locale::CStringListModel::currentIndexChanged, [&]() { - m_zonesModel->setList( static_cast< const CalamaresUtils::Locale::TZRegion* >( - m_regionModel->item( m_regionModel->currentIndex() ) ) - ->zones() ); - updateLocaleLabels(); - } ); - - connect( - m_zonesModel, &CalamaresUtils::Locale::CStringListModel::currentIndexChanged, [&]() { updateLocaleLabels(); } ); } -Config::~Config() -{ - qDeleteAll( m_regionList ); -} - -CalamaresUtils::Locale::CStringListModel* -Config::zonesModel() const -{ - return m_zonesModel; -} - -CalamaresUtils::Locale::CStringListModel* -Config::regionModel() const -{ - return m_regionModel; -} +Config::~Config() {} void -Config::setLocaleInfo( const QString& initialRegion, const QString& initialZone, const QString& localeGenPath ) -{ - using namespace CalamaresUtils::Locale; - - cDebug() << "REGION MODEL SIZE" << initialRegion << initialZone; - auto* region = m_regionList.find< TZRegion >( initialRegion ); - if ( region && region->zones().find< TZZone >( initialZone ) ) - { - m_regionModel->setCurrentIndex( m_regionModel->indexOf( initialRegion ) ); - m_zonesModel->setList( region->zones() ); - m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( initialZone ) ); - } - else - { - m_regionModel->setCurrentIndex( m_regionModel->indexOf( "America" ) ); - m_zonesModel->setList( - static_cast< const TZRegion* >( m_regionModel->item( m_regionModel->currentIndex() ) )->zones() ); - m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( "New_York" ) ); - } - - // Some distros come with a meaningfully commented and easy to parse locale.gen, - // and others ship a separate file /usr/share/i18n/SUPPORTED with a clean list of - // supported locales. We first try that one, and if it doesn't exist, we fall back - // to parsing the lines from locale.gen - m_localeGenLines.clear(); - QFile supported( "/usr/share/i18n/SUPPORTED" ); - QByteArray ba; - - if ( supported.exists() && supported.open( QIODevice::ReadOnly | QIODevice::Text ) ) - { - ba = supported.readAll(); - supported.close(); - - const auto lines = ba.split( '\n' ); - for ( const QByteArray& line : lines ) - { - m_localeGenLines.append( QString::fromLatin1( line.simplified() ) ); - } - } - else - { - QFile localeGen( localeGenPath ); - if ( localeGen.open( QIODevice::ReadOnly | QIODevice::Text ) ) - { - ba = localeGen.readAll(); - localeGen.close(); - } - else - { - cWarning() << "Cannot open file" << localeGenPath - << ". Assuming the supported languages are already built into " - "the locale archive."; - QProcess localeA; - localeA.start( "locale", QStringList() << "-a" ); - localeA.waitForFinished(); - ba = localeA.readAllStandardOutput(); - } - const auto lines = ba.split( '\n' ); - for ( const QByteArray& line : lines ) - { - if ( line.startsWith( "## " ) || line.startsWith( "# " ) || line.simplified() == "#" ) - { - continue; - } - - QString lineString = QString::fromLatin1( line.simplified() ); - if ( lineString.startsWith( "#" ) ) - { - lineString.remove( '#' ); - } - lineString = lineString.simplified(); - - if ( lineString.isEmpty() ) - { - continue; - } - - m_localeGenLines.append( lineString ); - } - } - - if ( m_localeGenLines.isEmpty() ) - { - cWarning() << "cannot acquire a list of available locales." - << "The locale and localecfg modules will be broken as long as this " - "system does not provide" - << "\n\t " - << "* a well-formed" << supported.fileName() << "\n\tOR" - << "* a well-formed" - << ( localeGenPath.isEmpty() ? QLatin1String( "/etc/locale.gen" ) : localeGenPath ) << "\n\tOR" - << "* a complete pre-compiled locale-gen database which allows complete locale -a output."; - return; // something went wrong and there's nothing we can do about it. - } - - // Assuming we have a list of supported locales, we usually only want UTF-8 ones - // because it's not 1995. - for ( auto it = m_localeGenLines.begin(); it != m_localeGenLines.end(); ) - { - if ( !it->contains( "UTF-8", Qt::CaseInsensitive ) && !it->contains( "utf8", Qt::CaseInsensitive ) ) - { - it = m_localeGenLines.erase( it ); - } - else - { - ++it; - } - } - - // We strip " UTF-8" from "en_US.UTF-8 UTF-8" because it's redundant redundant. - for ( auto it = m_localeGenLines.begin(); it != m_localeGenLines.end(); ++it ) - { - if ( it->endsWith( " UTF-8" ) ) - { - it->chop( 6 ); - } - *it = it->simplified(); - } - updateGlobalStorage(); - updateLocaleLabels(); -} - -void -Config::updateGlobalLocale() -{ - auto* gs = Calamares::JobQueue::instance()->globalStorage(); - const QString bcp47 = m_selectedLocaleConfiguration.toBcp47(); - gs->insert( "locale", bcp47 ); -} - -void -Config::updateGlobalStorage() -{ - auto* gs = Calamares::JobQueue::instance()->globalStorage(); - - const auto* location = currentLocation(); - bool locationChanged = ( location->region() != gs->value( "locationRegion" ) ) - || ( location->zone() != gs->value( "locationZone" ) ); -#ifdef DEBUG_TIMEZONES - if ( locationChanged ) - { - cDebug() << "Location changed" << gs->value( "locationRegion" ) << ',' << gs->value( "locationZone" ) << "to" - << location->region() << ',' << location->zone(); - } -#endif - gs->insert( "locationRegion", location->region() ); - gs->insert( "locationZone", location->zone() ); - - updateGlobalLocale(); - - // If we're in chroot mode (normal install mode), then we immediately set the - // timezone on the live system. When debugging timezones, don't bother. -#ifndef DEBUG_TIMEZONES - if ( locationChanged && Calamares::Settings::instance()->doChroot() ) - { - QProcess::execute( "timedatectl", // depends on systemd - { "set-timezone", location->region() + '/' + location->zone() } ); - } -#endif - - // Preserve those settings that have been made explicit. - auto newLocale = guessLocaleConfiguration(); - if ( !m_selectedLocaleConfiguration.isEmpty() && m_selectedLocaleConfiguration.explicit_lang ) - { - newLocale.setLanguage( m_selectedLocaleConfiguration.language() ); - } - if ( !m_selectedLocaleConfiguration.isEmpty() && m_selectedLocaleConfiguration.explicit_lc ) - { - newLocale.lc_numeric = m_selectedLocaleConfiguration.lc_numeric; - newLocale.lc_time = m_selectedLocaleConfiguration.lc_time; - newLocale.lc_monetary = m_selectedLocaleConfiguration.lc_monetary; - newLocale.lc_paper = m_selectedLocaleConfiguration.lc_paper; - newLocale.lc_name = m_selectedLocaleConfiguration.lc_name; - newLocale.lc_address = m_selectedLocaleConfiguration.lc_address; - newLocale.lc_telephone = m_selectedLocaleConfiguration.lc_telephone; - newLocale.lc_measurement = m_selectedLocaleConfiguration.lc_measurement; - newLocale.lc_identification = m_selectedLocaleConfiguration.lc_identification; - } - newLocale.explicit_lang = m_selectedLocaleConfiguration.explicit_lang; - newLocale.explicit_lc = m_selectedLocaleConfiguration.explicit_lc; - - m_selectedLocaleConfiguration = newLocale; - updateLocaleLabels(); -} - -void -Config::updateLocaleLabels() -{ - LocaleConfiguration lc - = m_selectedLocaleConfiguration.isEmpty() ? guessLocaleConfiguration() : m_selectedLocaleConfiguration; - auto labels = prettyLocaleStatus( lc ); - emit prettyStatusChanged(); -} - - -std::pair< QString, QString > -Config::prettyLocaleStatus( const LocaleConfiguration& lc ) const -{ - using CalamaresUtils::Locale::Label; - - Label lang( lc.language(), Label::LabelFormat::AlwaysWithCountry ); - Label num( lc.lc_numeric, Label::LabelFormat::AlwaysWithCountry ); - - return std::make_pair< QString, QString >( - tr( "The system language will be set to %1." ).arg( lang.label() ), - tr( "The numbers and dates locale will be set to %1." ).arg( num.label() ) ); -} - -Calamares::JobList -Config::createJobs() -{ - QList< Calamares::job_ptr > list; - const CalamaresUtils::Locale::TZZone* location = currentLocation(); - - Calamares::Job* j = new SetTimezoneJob( location->region(), location->zone() ); - list.append( Calamares::job_ptr( j ) ); - - return list; -} - -LocaleConfiguration -Config::guessLocaleConfiguration() const -{ - return LocaleConfiguration::fromLanguageAndLocation( - QLocale().name(), m_localeGenLines, currentLocation() ? currentLocation()->country() : "" ); -} - -QMap< QString, QString > -Config::localesMap() -{ - return m_selectedLocaleConfiguration.isEmpty() ? guessLocaleConfiguration().toMap() - : m_selectedLocaleConfiguration.toMap(); -} - -QString -Config::prettyStatus() const -{ - QString status; - status += tr( "Set timezone to %1/%2.
" ) - .arg( m_regionModel->item( m_regionModel->currentIndex() )->tr() ) - .arg( m_zonesModel->item( m_zonesModel->currentIndex() )->tr() ); - - LocaleConfiguration lc - = m_selectedLocaleConfiguration.isEmpty() ? guessLocaleConfiguration() : m_selectedLocaleConfiguration; - auto labels = prettyLocaleStatus( lc ); - status += labels.first + "
"; - status += labels.second + "
"; - - return status; -} - - -const CalamaresUtils::Locale::TZZone* -Config::currentLocation() const +Config::setConfigurationMap( const QVariantMap& ) { - return static_cast< const CalamaresUtils::Locale::TZZone* >( m_zonesModel->item( m_zonesModel->currentIndex() ) ); } diff --git a/src/modules/locale/Config.h b/src/modules/locale/Config.h index cfbed7bae..fcfc22a98 100644 --- a/src/modules/locale/Config.h +++ b/src/modules/locale/Config.h @@ -1,7 +1,8 @@ /* === This file is part of Calamares - === * - * Copyright 2019-2020, Adriaan de Groot - * Copyright 2020, Camilo Higuita + * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * License-Filename: LICENSE * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,66 +21,17 @@ #ifndef LOCALE_CONFIG_H #define LOCALE_CONFIG_H -#include "LocaleConfiguration.h" - -#include "Job.h" -#include "locale/TimeZone.h" - -#include #include -#include - class Config : public QObject { Q_OBJECT - Q_PROPERTY( CalamaresUtils::Locale::CStringListModel* zonesModel READ zonesModel CONSTANT FINAL ) - Q_PROPERTY( CalamaresUtils::Locale::CStringListModel* regionModel READ regionModel CONSTANT FINAL ) - Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL ) public: Config( QObject* parent = nullptr ); ~Config(); - CalamaresUtils::Locale::CStringListModel* regionModel() const; - CalamaresUtils::Locale::CStringListModel* zonesModel() const; - - void setLocaleInfo( const QString& initialRegion, const QString& initialZone, const QString& localeGenPath ); - - Calamares::JobList createJobs(); - QMap< QString, QString > localesMap(); - QString prettyStatus() const; - -private: - CalamaresUtils::Locale::CStringPairList m_regionList; - CalamaresUtils::Locale::CStringListModel* m_regionModel; - CalamaresUtils::Locale::CStringListModel* m_zonesModel; - - LocaleConfiguration m_selectedLocaleConfiguration; - - QStringList m_localeGenLines; - int m_currentRegion = -1; - - bool m_blockTzWidgetSet; - - LocaleConfiguration guessLocaleConfiguration() const; - - // For the given locale config, return two strings describing - // the settings for language and numbers. - std::pair< QString, QString > prettyLocaleStatus( const LocaleConfiguration& ) const; - - /** @brief Update the GS *locale* key with the selected system language. - * - * This uses whatever is set in m_selectedLocaleConfiguration as the language, - * and writes it to GS *locale* key (as a string, in BCP47 format). - */ - void updateGlobalLocale(); - void updateGlobalStorage(); - void updateLocaleLabels(); - - const CalamaresUtils::Locale::TZZone* currentLocation() const; -signals: - void prettyStatusChanged(); + void setConfigurationMap( const QVariantMap& ); }; diff --git a/src/modules/locale/LocaleViewStep.cpp b/src/modules/locale/LocaleViewStep.cpp index 3a8c37673..880f42a7d 100644 --- a/src/modules/locale/LocaleViewStep.cpp +++ b/src/modules/locale/LocaleViewStep.cpp @@ -34,7 +34,6 @@ #include #include -#include CALAMARES_PLUGIN_FACTORY_DEFINITION( LocaleViewStepFactory, registerPlugin< LocaleViewStep >(); ) @@ -45,6 +44,7 @@ LocaleViewStep::LocaleViewStep( QObject* parent ) , m_actualWidget( nullptr ) , m_nextEnabled( false ) , m_geoip( nullptr ) + , m_config( std::make_unique< Config >() ) { QBoxLayout* mainLayout = new QHBoxLayout; m_widget->setLayout( mainLayout ); @@ -221,6 +221,8 @@ LocaleViewStep::setConfigurationMap( const QVariantMap& configurationMap ) cWarning() << "GeoIP Style" << style << "is not recognized."; } } + + m_config->setConfigurationMap( configurationMap ); } Calamares::RequirementsList diff --git a/src/modules/locale/LocaleViewStep.h b/src/modules/locale/LocaleViewStep.h index 841aba97f..4e6c3d262 100644 --- a/src/modules/locale/LocaleViewStep.h +++ b/src/modules/locale/LocaleViewStep.h @@ -20,16 +20,14 @@ #ifndef LOCALEVIEWSTEP_H #define LOCALEVIEWSTEP_H +#include "Config.h" + +#include "DllMacro.h" #include "geoip/Handler.h" #include "geoip/Interface.h" #include "utils/PluginFactory.h" #include "viewpages/ViewStep.h" -#include "DllMacro.h" - -#include -#include - #include class LocalePage; @@ -79,6 +77,8 @@ private: Calamares::JobList m_jobs; std::unique_ptr< CalamaresUtils::GeoIP::Handler > m_geoip; + + std::unique_ptr< Config > m_config; }; CALAMARES_PLUGIN_FACTORY_DECLARATION( LocaleViewStepFactory )