[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.
This commit is contained in:
parent
0d5db2dd06
commit
8119c7e72a
@ -1,7 +1,8 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019-2020, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2020, Camilo Higuita <milo.h@aol.com>
|
||||
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
* 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 <QDebug>
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
|
||||
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 )
|
||||
Config::setConfigurationMap( const QVariantMap& )
|
||||
{
|
||||
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.<br/>" )
|
||||
.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 + "<br/>";
|
||||
status += labels.second + "<br/>";
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
const CalamaresUtils::Locale::TZZone*
|
||||
Config::currentLocation() const
|
||||
{
|
||||
return static_cast< const CalamaresUtils::Locale::TZZone* >( m_zonesModel->item( m_zonesModel->currentIndex() ) );
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019-2020, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2020, Camilo Higuita <milo.h@aol.com>
|
||||
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
* 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 <QAbstractListModel>
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
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& );
|
||||
};
|
||||
|
||||
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QtConcurrent/QtConcurrentRun>
|
||||
|
||||
|
||||
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
|
||||
|
@ -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 <QFutureWatcher>
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
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 )
|
||||
|
Loading…
Reference in New Issue
Block a user