[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.
main
Adriaan de Groot 5 years ago
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 )
{
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
Config::setConfigurationMap( const QVariantMap& )
{
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…
Cancel
Save