From 2ca58c6f91345308cadd6c4ad4927df7c90a8aaa Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 25 Nov 2014 17:41:27 +0100 Subject: [PATCH] Massive cleanup in LocalePage. Add LCLocale setting, with autodetect. --- src/modules/locale/LocalePage.cpp | 204 ++++++++++++++++++++++++++---- src/modules/locale/LocalePage.h | 23 +++- 2 files changed, 196 insertions(+), 31 deletions(-) diff --git a/src/modules/locale/LocalePage.cpp b/src/modules/locale/LocalePage.cpp index 0650eb22f..dca681eea 100644 --- a/src/modules/locale/LocalePage.cpp +++ b/src/modules/locale/LocalePage.cpp @@ -20,11 +20,16 @@ #include "timezonewidget/timezonewidget.h" #include "SetTimezoneJob.h" +#include "utils/Logger.h" #include "utils/Retranslator.h" +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "LCLocaleDialog.h" #include #include #include +#include LocalePage::LocalePage( QWidget* parent ) @@ -44,26 +49,37 @@ LocalePage::LocalePage( QWidget* parent ) QBoxLayout* bottomLayout = new QHBoxLayout; mainLayout->addLayout( bottomLayout ); - m_cityLabel = new QLabel( this ); - bottomLayout->addWidget( m_cityLabel ); + m_regionLabel = new QLabel( this ); + bottomLayout->addWidget( m_regionLabel ); m_regionCombo = new QComboBox( this ); bottomLayout->addWidget( m_regionCombo ); m_regionCombo->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); - m_cityLabel->setBuddy( m_regionCombo ); + m_regionLabel->setBuddy( m_regionCombo ); bottomLayout->addSpacing( 20 ); - m_timezoneLabel = new QLabel( this ); - bottomLayout->addWidget( m_timezoneLabel ); + m_zoneLabel = new QLabel( this ); + bottomLayout->addWidget( m_zoneLabel ); - m_timezoneCombo = new QComboBox( this ); - m_timezoneCombo->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); - bottomLayout->addWidget( m_timezoneCombo ); - m_timezoneLabel->setBuddy( m_timezoneCombo ); + m_zoneCombo = new QComboBox( this ); + m_zoneCombo->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + bottomLayout->addWidget( m_zoneCombo ); + m_zoneLabel->setBuddy( m_zoneCombo ); mainLayout->addStretch(); + QBoxLayout* localeLayout = new QHBoxLayout; + m_localeLabel = new QLabel( this ); + m_localeLabel->setWordWrap( true ); + m_localeLabel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + localeLayout->addWidget( m_localeLabel ); + + m_localeChangeButton = new QPushButton( this ); + m_localeChangeButton->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + localeLayout->addWidget( m_localeChangeButton ); + mainLayout->addLayout( localeLayout ); + setLayout( mainLayout ); connect( m_regionCombo, @@ -74,30 +90,30 @@ LocalePage::LocalePage( QWidget* parent ) if ( !regions.contains( current ) ) return; - m_timezoneCombo->blockSignals( true ); + m_zoneCombo->blockSignals( true ); - m_timezoneCombo->clear(); + m_zoneCombo->clear(); QList< LocaleGlobal::Location > zones = regions.value( current ); foreach ( const LocaleGlobal::Location& zone, zones ) { - m_timezoneCombo->addItem( zone.zone ); + m_zoneCombo->addItem( zone.zone ); } - m_timezoneCombo->model()->sort( 0 ); + m_zoneCombo->model()->sort( 0 ); - m_timezoneCombo->blockSignals( false ); + m_zoneCombo->blockSignals( false ); - m_timezoneCombo->currentIndexChanged( m_timezoneCombo->currentText() ); - }); + m_zoneCombo->currentIndexChanged( m_zoneCombo->currentText() ); + } ); - connect( m_timezoneCombo, + connect( m_zoneCombo, static_cast< void ( QComboBox::* )( const QString& ) >( &QComboBox::currentIndexChanged ), [this]( const QString& current ) { if ( !m_blockTzWidgetSet ) m_tzWidget->setCurrentLocation( m_regionCombo->currentText(), current ); - }); + } ); connect( m_tzWidget, &TimeZoneWidget::locationChanged, [this]( LocaleGlobal::Location location ) @@ -112,27 +128,61 @@ LocalePage::LocalePage( QWidget* parent ) m_regionCombo->setCurrentIndex( index ); // Set zone index - index = m_timezoneCombo->findText( location.zone ); + index = m_zoneCombo->findText( location.zone ); if ( index < 0 ) return; - m_timezoneCombo->setCurrentIndex( index ); + m_zoneCombo->setCurrentIndex( index ); m_blockTzWidgetSet = false; - }); + + Calamares::JobQueue::instance()->globalStorage() + ->insert( "locationRegion", location.region ); + Calamares::JobQueue::instance()->globalStorage() + ->insert( "locationZone", location.zone ); + } ); + + connect( m_localeChangeButton, &QPushButton::clicked, + [this]() + { + LCLocaleDialog* dlg = new LCLocaleDialog( lcLocale(), + m_localeGenLines, + this ); + dlg->exec(); + if ( dlg->result() == QDialog::Accepted && + !dlg->selectedLCLocale().isEmpty() ) + { + m_selectedLocale = dlg->selectedLCLocale(); + m_localeLabel->setText( tr( "The system encoding is set to %1." ) + .arg( prettyLCLocale( m_selectedLocale ) ) ); + } + + dlg->deleteLater(); + } ); CALAMARES_RETRANSLATE( - m_cityLabel->setText( tr( "Region:" ) ); - m_timezoneLabel->setText( tr( "Zone:" ) ); + m_regionLabel->setText( tr( "Region:" ) ); + m_zoneLabel->setText( tr( "Zone:" ) ); + + m_localeLabel->setText( tr( "The system encoding is set to %1." ) + .arg( prettyLCLocale( lcLocale() ) ) ); + + m_localeChangeButton->setText( tr( "&Change..." ) ); ) } +LocalePage::~LocalePage() +{} + + void -LocalePage::init( const QString& initialRegion, const QString& initialZone ) +LocalePage::init( const QString& initialRegion, + const QString& initialZone, + const QString& localeGenPath ) { m_regionCombo->blockSignals( true ); - m_timezoneCombo->blockSignals( true ); + m_zoneCombo->blockSignals( true ); // Setup locations QHash< QString, QList< LocaleGlobal::Location > > regions = LocaleGlobal::getLocations(); @@ -146,7 +196,7 @@ LocalePage::init( const QString& initialRegion, const QString& initialZone ) } m_regionCombo->blockSignals( false ); - m_timezoneCombo->blockSignals( false ); + m_zoneCombo->blockSignals( false ); m_regionCombo->currentIndexChanged( m_regionCombo->currentText() ); @@ -172,6 +222,28 @@ LocalePage::init( const QString& initialRegion, const QString& initialZone ) m_tzWidget->setCurrentLocation( "Europe", "Berlin" ); } emit m_tzWidget->locationChanged( m_tzWidget->getCurrentLocation() ); + + // Fill in meaningful locale/charset lines from locale.gen + m_localeGenLines.clear(); + QFile localeGen( localeGenPath ); + if ( !localeGen.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + cDebug() << "ERROR: Cannot open file" << localeGenPath << "."; + return; + } + QByteArray ba = localeGen.readAll(); + foreach ( QByteArray line, ba.split( '\n' ) ) + { + if ( line.startsWith( "# " ) || line.simplified() == "#" ) + continue; + + QString lineString = QString::fromLatin1( line.simplified() ); + + if ( lineString.startsWith( "#" ) ) + lineString.remove( '#' ); + + m_localeGenLines.append( lineString ); + } } @@ -181,7 +253,7 @@ LocalePage::prettyStatus() const QString status; status += tr( "Set timezone to %1/%2.
" ) .arg( m_regionCombo->currentText() ) - .arg( m_timezoneCombo->currentText() ); + .arg( m_zoneCombo->currentText() ); return status; } @@ -199,3 +271,81 @@ LocalePage::createJobs() return list; } + +QString +LocalePage::lcLocale() +{ + return m_selectedLocale.isEmpty() ? guessLCLocale() : m_selectedLocale; +} + + +QString +LocalePage::guessLCLocale() +{ + QLocale myLocale = QLocale(); + + if ( m_localeGenLines.isEmpty() ) + return "en_US.UTF-8 UTF-8"; + + QStringList linesForLanguage; + foreach ( QString line, m_localeGenLines ) + { + if ( line.startsWith( myLocale.name().left( 2 ) ) ) + linesForLanguage.append( line ); + } + + if ( linesForLanguage.length() == 0 ) + return "en_US.UTF-8 UTF-8"; + else if ( linesForLanguage.length() == 1 ) + return linesForLanguage.first(); + else + { + QStringList linesForLanguageUtf; + foreach ( QString line, linesForLanguage ) + { + if ( line.contains( "UTF-8" ) ) + linesForLanguageUtf.append( line ); + } + + if ( linesForLanguageUtf.length() == 1 ) + return linesForLanguageUtf.first(); + } + + // FIXME: use reverse geocoding to guess the country + QStringList linesForLanguageAndCountry; + foreach ( QString line, linesForLanguage ) + { + QString prefix = myLocale.name(); + if ( line.startsWith( prefix ) ) + linesForLanguageAndCountry.append( line ); + } + + if ( linesForLanguageAndCountry.length() == 0 ) + return "en_US.UTF-8 UTF-8"; + else if ( linesForLanguageAndCountry.length() == 1 ) + return linesForLanguageAndCountry.first(); + else + { + QStringList linesForLanguageAndCountryUtf; + foreach ( QString line, linesForLanguageAndCountry ) + { + if ( line.contains( "UTF-8" ) ) + linesForLanguageAndCountryUtf.append( line ); + } + + if ( linesForLanguageAndCountryUtf.length() == 1 ) + return linesForLanguageAndCountryUtf.first(); + } + + return "en_US.UTF-8 UTF-8"; +} + + +QString +LocalePage::prettyLCLocale( const QString& lcLocale ) +{ + QString localeString = lcLocale; + if ( localeString.endsWith( " UTF-8" ) ) + localeString.remove( " UTF-8" ); + return localeString; +} diff --git a/src/modules/locale/LocalePage.h b/src/modules/locale/LocalePage.h index 71b1da770..3691f791f 100644 --- a/src/modules/locale/LocalePage.h +++ b/src/modules/locale/LocalePage.h @@ -25,6 +25,7 @@ class QComboBox; class QLabel; +class QPushButton; class TimeZoneWidget; class LocalePage : public QWidget @@ -32,20 +33,34 @@ class LocalePage : public QWidget Q_OBJECT public: explicit LocalePage( QWidget* parent = nullptr ); + virtual ~LocalePage(); - void init( const QString& initialRegion, const QString& initialZone ); + void init( const QString& initialRegion, + const QString& initialZone, + const QString& localeGenPath ); QString prettyStatus() const; QList< Calamares::job_ptr > createJobs(); + QString lcLocale(); + private: + QString guessLCLocale(); + QString prettyLCLocale( const QString& lcLocale ); + TimeZoneWidget* m_tzWidget; QComboBox* m_regionCombo; - QComboBox* m_timezoneCombo; + QComboBox* m_zoneCombo; - QLabel* m_cityLabel; - QLabel* m_timezoneLabel; + QLabel* m_regionLabel; + QLabel* m_zoneLabel; + QLabel* m_localeLabel; + QPushButton* m_localeChangeButton; + + QString m_selectedLocale; + + QStringList m_localeGenLines; bool m_blockTzWidgetSet; };