mirror of
https://github.com/parchlinux/calamares.git
synced 2025-02-25 03:15:44 -05:00
commit
a33d9f5a06
12 changed files with 1012 additions and 10 deletions
|
@ -33,9 +33,7 @@ Label::Label( const QString& locale, LabelFormat format, QObject* parent )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
, m_locale( Label::getLocale( locale ) )
|
, m_locale( Label::getLocale( locale ) )
|
||||||
, m_localeId( locale.isEmpty() ? m_locale.name() : locale )
|
, m_localeId( locale.isEmpty() ? m_locale.name() : locale )
|
||||||
|
|
||||||
{
|
{
|
||||||
//: language[name] (country[name])
|
|
||||||
QString longFormat = QObject::tr( "%1 (%2)" );
|
QString longFormat = QObject::tr( "%1 (%2)" );
|
||||||
|
|
||||||
QString languageName = m_locale.nativeLanguageName();
|
QString languageName = m_locale.nativeLanguageName();
|
||||||
|
|
|
@ -40,10 +40,6 @@ class Label : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY( QString label READ label CONSTANT FINAL )
|
|
||||||
Q_PROPERTY( QString englishLabel READ englishLabel CONSTANT FINAL )
|
|
||||||
Q_PROPERTY( QString localeId MEMBER m_localeId CONSTANT FINAL )
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Formatting option for label -- add (country) to label. */
|
/** @brief Formatting option for label -- add (country) to label. */
|
||||||
enum class LabelFormat
|
enum class LabelFormat
|
||||||
|
@ -65,6 +61,7 @@ public:
|
||||||
LabelFormat format = LabelFormat::IfNeededWithCountry,
|
LabelFormat format = LabelFormat::IfNeededWithCountry,
|
||||||
QObject* parent = nullptr );
|
QObject* parent = nullptr );
|
||||||
|
|
||||||
|
|
||||||
/** @brief Define a sorting order.
|
/** @brief Define a sorting order.
|
||||||
*
|
*
|
||||||
* Locales are sorted by their id, which means the ISO 2-letter code + country.
|
* Locales are sorted by their id, which means the ISO 2-letter code + country.
|
||||||
|
|
|
@ -239,7 +239,13 @@ CStringListModel::CStringListModel( CStringPairList l )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CStringListModel::~CStringListModel() {}
|
void
|
||||||
|
CStringListModel::setList( CalamaresUtils::Locale::CStringPairList l )
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_list = l;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
CStringListModel::rowCount( const QModelIndex& ) const
|
CStringListModel::rowCount( const QModelIndex& ) const
|
||||||
|
@ -264,6 +270,30 @@ CStringListModel::data( const QModelIndex& index, int role ) const
|
||||||
return item ? ( role == Qt::DisplayRole ? item->tr() : item->key() ) : QVariant();
|
return item ? ( role == Qt::DisplayRole ? item->tr() : item->key() ) : QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CStringListModel::setCurrentIndex( int index )
|
||||||
|
{
|
||||||
|
if ( ( index < 0 ) || ( index >= m_list.count() ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentIndex = index;
|
||||||
|
emit currentIndexChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CStringListModel::currentIndex() const
|
||||||
|
{
|
||||||
|
return m_currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash< int, QByteArray >
|
||||||
|
CStringListModel::roleNames() const
|
||||||
|
{
|
||||||
|
return { { Qt::DisplayRole, "label" }, { Qt::UserRole, "key" } };
|
||||||
|
}
|
||||||
|
|
||||||
const CStringPair*
|
const CStringPair*
|
||||||
CStringListModel::item( int index ) const
|
CStringListModel::item( int index ) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,8 +44,9 @@ namespace Locale
|
||||||
* QPair<QString, QString> because there is API that needs
|
* QPair<QString, QString> because there is API that needs
|
||||||
* C-style strings.
|
* C-style strings.
|
||||||
*/
|
*/
|
||||||
class CStringPair
|
class CStringPair : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/// @brief An empty pair
|
/// @brief An empty pair
|
||||||
CStringPair() {}
|
CStringPair() {}
|
||||||
|
@ -86,6 +87,7 @@ public:
|
||||||
/// @brief A pair of strings for timezone regions (e.g. "America")
|
/// @brief A pair of strings for timezone regions (e.g. "America")
|
||||||
class TZRegion : public CStringPair
|
class TZRegion : public CStringPair
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
using CStringPair::CStringPair;
|
using CStringPair::CStringPair;
|
||||||
virtual ~TZRegion() override;
|
virtual ~TZRegion() override;
|
||||||
|
@ -117,6 +119,7 @@ private:
|
||||||
/// @brief A pair of strings for specific timezone names (e.g. "New_York")
|
/// @brief A pair of strings for specific timezone names (e.g. "New_York")
|
||||||
class TZZone : public CStringPair
|
class TZZone : public CStringPair
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
using CStringPair::CStringPair;
|
using CStringPair::CStringPair;
|
||||||
QString tr() const override;
|
QString tr() const override;
|
||||||
|
@ -137,21 +140,52 @@ protected:
|
||||||
|
|
||||||
class CStringListModel : public QAbstractListModel
|
class CStringListModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY( int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @brief Create empty model
|
/// @brief Create empty model
|
||||||
CStringListModel();
|
CStringListModel() {}
|
||||||
/// @brief Create model from list (non-owning)
|
/// @brief Create model from list (non-owning)
|
||||||
CStringListModel( CStringPairList );
|
CStringListModel( CStringPairList );
|
||||||
virtual ~CStringListModel() override;
|
|
||||||
|
|
||||||
int rowCount( const QModelIndex& parent ) const override;
|
int rowCount( const QModelIndex& parent ) const override;
|
||||||
|
|
||||||
QVariant data( const QModelIndex& index, int role ) const override;
|
QVariant data( const QModelIndex& index, int role ) const override;
|
||||||
|
|
||||||
const CStringPair* item( int index ) const;
|
const CStringPair* item( int index ) const;
|
||||||
|
QHash< int, QByteArray > roleNames() const override;
|
||||||
|
|
||||||
|
void setCurrentIndex( int index );
|
||||||
|
int currentIndex() const;
|
||||||
|
|
||||||
|
void setList( CStringPairList );
|
||||||
|
|
||||||
|
inline int indexOf( const QString& key )
|
||||||
|
{
|
||||||
|
const auto it = std::find_if(
|
||||||
|
m_list.constBegin(), m_list.constEnd(), [&]( const CalamaresUtils::Locale::CStringPair* item ) -> bool {
|
||||||
|
return item->key() == key;
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( it != m_list.constEnd() )
|
||||||
|
{
|
||||||
|
// distance() is usually a long long
|
||||||
|
return int( std::distance( m_list.constBegin(), it ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CStringPairList m_list;
|
CStringPairList m_list;
|
||||||
|
int m_currentIndex = -1;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void currentIndexChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Locale
|
} // namespace Locale
|
||||||
|
|
|
@ -13,6 +13,7 @@ calamares_add_plugin( locale
|
||||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||||
SOURCES
|
SOURCES
|
||||||
${geoip_src}
|
${geoip_src}
|
||||||
|
Config.cpp
|
||||||
LCLocaleDialog.cpp
|
LCLocaleDialog.cpp
|
||||||
LocaleConfiguration.cpp
|
LocaleConfiguration.cpp
|
||||||
LocalePage.cpp
|
LocalePage.cpp
|
||||||
|
|
324
src/modules/locale/Config.cpp
Normal file
324
src/modules/locale/Config.cpp
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
/* === 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>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ) )
|
||||||
|
{
|
||||||
|
this->m_regionModel->setCurrentIndex( m_regionModel->indexOf( initialRegion ) );
|
||||||
|
m_zonesModel->setList( region->zones() );
|
||||||
|
this->m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( initialZone ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->m_regionModel->setCurrentIndex( m_regionModel->indexOf( "America" ) );
|
||||||
|
m_zonesModel->setList(
|
||||||
|
static_cast< const TZRegion* >( m_regionModel->item( m_regionModel->currentIndex() ) )->zones() );
|
||||||
|
this->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" ) );
|
||||||
|
|
||||||
|
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() ) );
|
||||||
|
}
|
87
src/modules/locale/Config.h
Normal file
87
src/modules/locale/Config.h
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/* === 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>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOCALE_CONFIG_H
|
||||||
|
#define LOCALE_CONFIG_H
|
||||||
|
|
||||||
|
#include "LocaleConfiguration.h"
|
||||||
|
#include "timezonewidget/localeglobal.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();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
42
src/modules/localeq/CMakeLists.txt
Normal file
42
src/modules/localeq/CMakeLists.txt
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# When debugging the timezone widget, add this debugging definition
|
||||||
|
# to have a debugging-friendly timezone widget, debug logging,
|
||||||
|
# and no intrusive timezone-setting while clicking around.
|
||||||
|
option( DEBUG_TIMEZONES "Debug-friendly timezone widget." OFF )
|
||||||
|
if( DEBUG_TIMEZONES )
|
||||||
|
add_definitions( -DDEBUG_TIMEZONES )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set( _locale ${CMAKE_CURRENT_SOURCE_DIR}/../locale )
|
||||||
|
|
||||||
|
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui ${CMAKE_CURRENT_SOURCE_DIR}/../../libcalamares ${_locale} )
|
||||||
|
|
||||||
|
calamares_add_plugin( localeq
|
||||||
|
TYPE viewmodule
|
||||||
|
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||||
|
SOURCES
|
||||||
|
${geoip_src}
|
||||||
|
LocaleQmlViewStep.cpp
|
||||||
|
${_locale}/LocaleConfiguration.cpp
|
||||||
|
${_locale}/Config.cpp
|
||||||
|
${_locale}/SetTimezoneJob.cpp
|
||||||
|
${_locale}/timezonewidget/localeglobal.cpp
|
||||||
|
RESOURCES
|
||||||
|
${_locale}/locale.qrc
|
||||||
|
LINK_PRIVATE_LIBRARIES
|
||||||
|
calamaresui
|
||||||
|
Qt5::Network
|
||||||
|
${geoip_libs}
|
||||||
|
${YAMLCPP_LIBRARY}
|
||||||
|
SHARED_LIB
|
||||||
|
)
|
||||||
|
|
||||||
|
# add_executable( localeqmltest qmlmain.cpp Config.cpp LocaleQmlViewStep.cpp LocaleConfiguration.cpp timezonewidget/localeglobal.cpp SetTimezoneJob.cpp ${geoip_src} )
|
||||||
|
# target_link_libraries( localeqmltest PRIVATE calamaresui Qt5::Core Qt5::Network Qt5::DBus ${geoip_libs})
|
||||||
|
# set_target_properties( localeqmltest
|
||||||
|
# PROPERTIES
|
||||||
|
# ENABLE_EXPORTS TRUE
|
||||||
|
# RUNTIME_OUTPUT_NAME localeqmltest
|
||||||
|
# )
|
||||||
|
# calamares_automoc( localeqmltest )
|
||||||
|
# calamares_autouic( localeqmltest )
|
||||||
|
|
203
src/modules/localeq/LocaleQmlViewStep.cpp
Normal file
203
src/modules/localeq/LocaleQmlViewStep.cpp
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||||
|
* Copyright 2018,2020 Adriaan de Groot <groot@kde.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "LocaleQmlViewStep.h"
|
||||||
|
|
||||||
|
#include "GlobalStorage.h"
|
||||||
|
#include "JobQueue.h"
|
||||||
|
|
||||||
|
#include "geoip/Handler.h"
|
||||||
|
#include "network/Manager.h"
|
||||||
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/Variant.h"
|
||||||
|
#include "utils/Yaml.h"
|
||||||
|
|
||||||
|
#include "timezonewidget/localeglobal.h"
|
||||||
|
|
||||||
|
#include "Branding.h"
|
||||||
|
#include "modulesystem/ModuleManager.h"
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( LocaleQmlViewStepFactory, registerPlugin< LocaleQmlViewStep >(); )
|
||||||
|
|
||||||
|
LocaleQmlViewStep::LocaleQmlViewStep( QObject* parent )
|
||||||
|
: Calamares::QmlViewStep( parent )
|
||||||
|
, m_config( new Config( this ) )
|
||||||
|
, m_nextEnabled( false )
|
||||||
|
, m_geoip( nullptr )
|
||||||
|
{
|
||||||
|
emit nextStatusChanged( m_nextEnabled );
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject*
|
||||||
|
LocaleQmlViewStep::getConfig()
|
||||||
|
{
|
||||||
|
return m_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocaleQmlViewStep::fetchGeoIpTimezone()
|
||||||
|
{
|
||||||
|
if ( m_geoip && m_geoip->isValid() )
|
||||||
|
{
|
||||||
|
m_startingTimezone = m_geoip->get();
|
||||||
|
if ( !m_startingTimezone.isValid() )
|
||||||
|
{
|
||||||
|
cWarning() << "GeoIP lookup at" << m_geoip->url() << "failed.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_config->setLocaleInfo(m_startingTimezone.first, m_startingTimezone.second, m_localeGenPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
Calamares::RequirementsList LocaleQmlViewStep::checkRequirements()
|
||||||
|
{
|
||||||
|
LocaleGlobal::init();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
LocaleQmlViewStep::prettyName() const
|
||||||
|
{
|
||||||
|
return tr( "Location" );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocaleQmlViewStep::isNextEnabled() const
|
||||||
|
{
|
||||||
|
// TODO: should return true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocaleQmlViewStep::isBackEnabled() const
|
||||||
|
{
|
||||||
|
// TODO: should return true (it's weird that you are not allowed to have welcome *after* anything
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocaleQmlViewStep::isAtBeginning() const
|
||||||
|
{
|
||||||
|
// TODO: adjust to "pages" in the QML
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocaleQmlViewStep::isAtEnd() const
|
||||||
|
{
|
||||||
|
// TODO: adjust to "pages" in the QML
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Calamares::JobList
|
||||||
|
LocaleQmlViewStep::jobs() const
|
||||||
|
{
|
||||||
|
return m_jobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocaleQmlViewStep::onActivate()
|
||||||
|
{
|
||||||
|
// TODO no sure if it is needed at all or for the abstract class to start something
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocaleQmlViewStep::onLeave()
|
||||||
|
{
|
||||||
|
if ( true )
|
||||||
|
{
|
||||||
|
m_jobs = m_config->createJobs();
|
||||||
|
// m_prettyStatus = m_actualWidget->prettyStatus();
|
||||||
|
|
||||||
|
auto map = m_config->localesMap();
|
||||||
|
QVariantMap vm;
|
||||||
|
for ( auto it = map.constBegin(); it != map.constEnd(); ++it )
|
||||||
|
{
|
||||||
|
vm.insert( it.key(), it.value() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Calamares::JobQueue::instance()->globalStorage()->insert( "localeConf", vm );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_jobs.clear();
|
||||||
|
Calamares::JobQueue::instance()->globalStorage()->remove( "localeConf" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocaleQmlViewStep::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" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_localeGenPath = CalamaresUtils::getString( configurationMap, "localeGenPath" );
|
||||||
|
if ( m_localeGenPath.isEmpty() )
|
||||||
|
{
|
||||||
|
m_localeGenPath = QStringLiteral( "/etc/locale.gen" );
|
||||||
|
}
|
||||||
|
|
||||||
|
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.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRequirements();
|
||||||
|
Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation last
|
||||||
|
setContextProperty( "Localeq", m_config );
|
||||||
|
}
|
76
src/modules/localeq/LocaleQmlViewStep.h
Normal file
76
src/modules/localeq/LocaleQmlViewStep.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019-2020 Adriaan de Groot <groot@kde.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOCALE_QMLVIEWSTEP_H
|
||||||
|
#define LOCALE_QMLVIEWSTEP_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "geoip/Handler.h"
|
||||||
|
#include "geoip/Interface.h"
|
||||||
|
#include "utils/PluginFactory.h"
|
||||||
|
#include "viewpages/QmlViewStep.h"
|
||||||
|
#include <DllMacro.h>
|
||||||
|
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class PLUGINDLLEXPORT LocaleQmlViewStep : public Calamares::QmlViewStep
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LocaleQmlViewStep( QObject* parent = nullptr );
|
||||||
|
|
||||||
|
QString prettyName() const override;
|
||||||
|
|
||||||
|
bool isNextEnabled() const override;
|
||||||
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
bool isAtBeginning() const override;
|
||||||
|
bool isAtEnd() const override;
|
||||||
|
|
||||||
|
Calamares::JobList jobs() const override;
|
||||||
|
void onActivate() override;
|
||||||
|
void onLeave() override;
|
||||||
|
|
||||||
|
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||||
|
QObject* getConfig() override;
|
||||||
|
|
||||||
|
virtual Calamares::RequirementsList checkRequirements() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// TODO: a generic QML viewstep should return a config object from a method
|
||||||
|
Config *m_config;
|
||||||
|
|
||||||
|
bool m_nextEnabled;
|
||||||
|
QString m_prettyStatus;
|
||||||
|
|
||||||
|
CalamaresUtils::GeoIP::RegionZonePair m_startingTimezone;
|
||||||
|
QString m_localeGenPath;
|
||||||
|
|
||||||
|
Calamares::JobList m_jobs;
|
||||||
|
std::unique_ptr< CalamaresUtils::GeoIP::Handler > m_geoip;
|
||||||
|
|
||||||
|
void fetchGeoIpTimezone();
|
||||||
|
};
|
||||||
|
|
||||||
|
CALAMARES_PLUGIN_FACTORY_DECLARATION( LocaleQmlViewStepFactory )
|
||||||
|
|
||||||
|
#endif
|
97
src/modules/localeq/localeq.conf
Normal file
97
src/modules/localeq/localeq.conf
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
---
|
||||||
|
# This settings are used to set your default system time zone.
|
||||||
|
# Time zones are usually located under /usr/share/zoneinfo and
|
||||||
|
# provided by the 'tzdata' package of your Distribution.
|
||||||
|
#
|
||||||
|
# Distributions using systemd can list available
|
||||||
|
# time zones by using the timedatectl command.
|
||||||
|
# timedatectl list-timezones
|
||||||
|
#
|
||||||
|
# The starting timezone (e.g. the pin-on-the-map) when entering
|
||||||
|
# the locale page can be set through keys *region* and *zone*.
|
||||||
|
# If either is not set, defaults to America/New_York.
|
||||||
|
#
|
||||||
|
region: "America"
|
||||||
|
zone: "New_York"
|
||||||
|
|
||||||
|
|
||||||
|
# System locales are detected in the following order:
|
||||||
|
#
|
||||||
|
# - /usr/share/i18n/SUPPORTED
|
||||||
|
# - localeGenPath (defaults to /etc/locale.gen if not set)
|
||||||
|
# - 'locale -a' output
|
||||||
|
#
|
||||||
|
# Enable only when your Distribution is using an
|
||||||
|
# custom path for locale.gen
|
||||||
|
#
|
||||||
|
#localeGenPath: "PATH_TO/locale.gen"
|
||||||
|
|
||||||
|
# GeoIP based Language settings: Leave commented out to disable GeoIP.
|
||||||
|
#
|
||||||
|
# GeoIP needs a working Internet connection.
|
||||||
|
# This can be managed from `welcome.conf` by adding
|
||||||
|
# internet to the list of required conditions.
|
||||||
|
#
|
||||||
|
# The configuration
|
||||||
|
# is in three parts: a *style*, which can be "json" or "xml"
|
||||||
|
# depending on the kind of data returned by the service, and
|
||||||
|
# a *url* where the data is retrieved, and an optional *selector*
|
||||||
|
# to pick the right field out of the returned data (e.g. field
|
||||||
|
# name in JSON or element name in XML).
|
||||||
|
#
|
||||||
|
# The default selector (when the setting is blank) is picked to
|
||||||
|
# work with existing JSON providers (which use "time_zone") and
|
||||||
|
# Ubiquity's XML providers (which use "TimeZone").
|
||||||
|
#
|
||||||
|
# If the service configured via *url* uses
|
||||||
|
# a different attribute name (e.g. "timezone") in JSON or a
|
||||||
|
# different element tag (e.g. "<Time_Zone>") in XML, set this
|
||||||
|
# string to the name or tag to be used.
|
||||||
|
#
|
||||||
|
# In JSON:
|
||||||
|
# - if the string contains "." characters, this is used as a
|
||||||
|
# multi-level selector, e.g. "a.b" will select the timezone
|
||||||
|
# from data "{a: {b: "Europe/Amsterdam" } }".
|
||||||
|
# - each part of the string split by "." characters is used as
|
||||||
|
# a key into the JSON data.
|
||||||
|
# In XML:
|
||||||
|
# - all elements with the named tag (e.g. all TimeZone) elements
|
||||||
|
# from the document are checked; the first one with non-empty
|
||||||
|
# text value is used.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# An HTTP(S) request is made to *url*. The request should return
|
||||||
|
# valid data in a suitable format, depending on *style*;
|
||||||
|
# generally this includes a string value with the timezone
|
||||||
|
# in <region>/<zone> format. For services that return data which
|
||||||
|
# does not follow the conventions of "suitable data" described
|
||||||
|
# below, *selector* may be used to pick different data.
|
||||||
|
#
|
||||||
|
# Note that this example URL works, but the service is shutting
|
||||||
|
# down in June 2018.
|
||||||
|
#
|
||||||
|
# Suitable JSON data looks like
|
||||||
|
# ```
|
||||||
|
# {"time_zone":"America/New_York"}
|
||||||
|
# ```
|
||||||
|
# Suitable XML data looks like
|
||||||
|
# ```
|
||||||
|
# <Response><TimeZone>Europe/Brussels</TimeZone></Response>
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# To accommodate providers of GeoIP timezone data with peculiar timezone
|
||||||
|
# naming conventions, the following cleanups are performed automatically:
|
||||||
|
# - backslashes are removed
|
||||||
|
# - spaces are replaced with _
|
||||||
|
#
|
||||||
|
# Legacy settings "geoipStyle", "geoipUrl" and "geoipSelector"
|
||||||
|
# in the top-level are still supported, but I'd advise against.
|
||||||
|
#
|
||||||
|
# To disable GeoIP checking, either comment-out the entire geoip section,
|
||||||
|
# or set the *style* key to an unsupported format (e.g. `none`).
|
||||||
|
# Also, note the analogous feature in src/modules/welcome/welcome.conf.
|
||||||
|
#
|
||||||
|
geoip:
|
||||||
|
style: "json"
|
||||||
|
url: "https://geoip.kde.org/v1/calamares"
|
||||||
|
selector: "" # leave blank for the default
|
113
src/modules/localeq/localeq.qml
Normal file
113
src/modules/localeq/localeq.qml
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
import io.calamares.modules 1.0 as Modules
|
||||||
|
import io.calamares.ui 1.0
|
||||||
|
|
||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Controls 2.10
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import org.kde.kirigami 2.7 as Kirigami
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
ResponsiveBase
|
||||||
|
{
|
||||||
|
id: control
|
||||||
|
|
||||||
|
Modules.Locale //locale handler
|
||||||
|
{
|
||||||
|
id: _locale
|
||||||
|
}
|
||||||
|
|
||||||
|
title: stackView.currentItem.title
|
||||||
|
subtitle: stackView.currentItem.subtitle
|
||||||
|
message: stackView.currentItem.message
|
||||||
|
|
||||||
|
stackView.initialItem: Item
|
||||||
|
{
|
||||||
|
id: _regionsListComponent
|
||||||
|
|
||||||
|
property string title: qsTr("Region")
|
||||||
|
property string subtitle: qsTr("Pick your preferred region or use the default one based on your current location")
|
||||||
|
property string message: qsTr("Select your preferred zone within your location to continue with the installation")
|
||||||
|
|
||||||
|
ListViewTemplate
|
||||||
|
{
|
||||||
|
id: _regionListView
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitWidth: Math.min(parent.width, 500)
|
||||||
|
implicitHeight: Math.min(contentHeight, 500)
|
||||||
|
currentIndex: model.currentIndex
|
||||||
|
model: _locale.Config.regionModel
|
||||||
|
|
||||||
|
delegate: ListItemDelegate
|
||||||
|
{
|
||||||
|
id: _delegate
|
||||||
|
label1.text: model.label
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
_regionListView.model.currentIndex = index
|
||||||
|
_stackView.push(_zonesListComponent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: RowLayout
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
z: 99999
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Timezones")
|
||||||
|
icon.name: "go-previous"
|
||||||
|
onClicked: control.stackView.push(_zonesListComponent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Component
|
||||||
|
{
|
||||||
|
id: _zonesListComponent
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
property string title: qsTr("Timezone")
|
||||||
|
property string subtitle: _locale.Config.prettyStatus
|
||||||
|
property string message: ""
|
||||||
|
ListViewTemplate
|
||||||
|
{
|
||||||
|
id: _zonesListView
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitWidth: Math.min(parent.width, 500)
|
||||||
|
implicitHeight: Math.min(contentHeight, 500)
|
||||||
|
currentIndex: model.currentIndex
|
||||||
|
model: _locale.Config.zonesModel
|
||||||
|
|
||||||
|
delegate: ListItemDelegate
|
||||||
|
{
|
||||||
|
id: _delegate
|
||||||
|
label1.text: model.label
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
_zonesListView.model.currentIndex = index
|
||||||
|
positionViewAtIndex(index, ListView.Center)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: RowLayout
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
z: 99999
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
icon.name: "go-previous"
|
||||||
|
text: qsTr("Regions")
|
||||||
|
onClicked: control.stackView.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue