From 4c33e9a16a5b2c400f0f151bbfdf98ca4d6d9875 Mon Sep 17 00:00:00 2001 From: Philip Date: Sat, 17 Jun 2017 15:36:09 +0200 Subject: [PATCH] Keyboard: guess at layout based on locale Split locale into _ and go looking for keyboard layouts that match. Do that in reverse, so look for country first. - known weakness is el_CY [should get layout gr] because CY and el don't name any keyboard layout. - known weakness are Hausa, Igbo .. which are ha_NG and ig_NG. They select keyboard layout ng, which is labeled 'English [Nigeria]'; they ought to select ng[hausa] and ng[igbo], which are the right variant keyboard layouts to use. - similar selecting a locale in Canada [en_CA, fr_CA, iu_CA ...] will select keyboard layout ca, which is for French-speaking Canada. Locale en_CA should select keyboard en -- e.g. en[us]. But iu_CA [Inuktituk] needs layout ca[ike]. --- src/modules/keyboard/KeyboardLayoutModel.cpp | 5 +- src/modules/keyboard/KeyboardPage.cpp | 49 +++++++++++++++++++ src/modules/keyboard/KeyboardPage.h | 3 ++ .../keyboard/keyboardwidget/keyboardglobal.h | 8 ++- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/modules/keyboard/KeyboardLayoutModel.cpp b/src/modules/keyboard/KeyboardLayoutModel.cpp index 9f045043e..63989819c 100644 --- a/src/modules/keyboard/KeyboardLayoutModel.cpp +++ b/src/modules/keyboard/KeyboardLayoutModel.cpp @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2016, Teo Mrnjavac + * Copyright 2017, Adriaan de Groot * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,9 +60,9 @@ KeyboardLayoutModel::data( const QModelIndex& index, int role ) const void KeyboardLayoutModel::init() { - QMap< QString, KeyboardGlobal::KeyboardInfo > layouts = + KeyboardGlobal::LayoutsMap layouts = KeyboardGlobal::getKeyboardLayouts(); - for ( QMap< QString, KeyboardGlobal::KeyboardInfo >::const_iterator it = layouts.constBegin(); + for ( KeyboardGlobal::LayoutsMap::const_iterator it = layouts.constBegin(); it != layouts.constEnd(); ++it ) { m_layouts.append( qMakePair( it.key(), it.value() ) ); diff --git a/src/modules/keyboard/KeyboardPage.cpp b/src/modules/keyboard/KeyboardPage.cpp index 117530a88..770c7c6b1 100644 --- a/src/modules/keyboard/KeyboardPage.cpp +++ b/src/modules/keyboard/KeyboardPage.cpp @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014-2016, Teo Mrnjavac + * Copyright 2017, Adriaan de Groot * * Portions from the Manjaro Installation Framework * by Roland Singer @@ -221,10 +222,58 @@ KeyboardPage::createJobs( const QString& xOrgConfFileName, } +void +KeyboardPage::guessLayout( const QStringList& langParts ) +{ + const KeyboardLayoutModel* klm = dynamic_cast< KeyboardLayoutModel* >( ui->listLayout->model() ); + bool foundCountryPart = false; + for ( auto countryPart = langParts.rbegin(); !foundCountryPart && countryPart != langParts.rend(); ++countryPart) + { + cDebug() << " .. looking for locale part" << *countryPart; + for ( int i = 0; i < klm->rowCount(); ++i ) + { + QModelIndex idx = klm->index( i ); + if ( idx.isValid() && + ( idx.data( KeyboardLayoutModel::KeyboardLayoutKeyRole ).toString().compare( *countryPart, Qt::CaseInsensitive ) == 0 ) ) + { + cDebug() << " .. matched" << idx.data( KeyboardLayoutModel::KeyboardLayoutKeyRole ).toString(); + ui->listLayout->setCurrentIndex( idx ); + foundCountryPart = true; + break; + } + } + } +} + + void KeyboardPage::onActivate() { ui->listLayout->setFocus(); + + // Try to preselect a layout, depending on language and locale + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + QString lang = gs->value( "localeConf" ).toMap().value( "LANG" ).toString(); + + cDebug() << "Got locale language" << lang; + if ( !lang.isEmpty() ) + { + // Chop off .codeset and @modifier + int index = lang.indexOf('.'); + if ( index >= 0 ) + lang.truncate( index ); + index = lang.indexOf('@'); + if ( index >= 0 ) + lang.truncate( index ); + + lang.replace( '-', '_' ); // Normalize separators + const auto langParts = lang.split( '_' , QString::SkipEmptyParts ); + + QString country = QLocale::countryToString( QLocale( lang ).country() ); + cDebug() << " .. extracted country" << country << "::" << langParts; + + guessLayout( langParts ); + } } diff --git a/src/modules/keyboard/KeyboardPage.h b/src/modules/keyboard/KeyboardPage.h index c60d62b2b..6f828f446 100644 --- a/src/modules/keyboard/KeyboardPage.h +++ b/src/modules/keyboard/KeyboardPage.h @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014-2016, Teo Mrnjavac + * Copyright 2017, Adriaan de Groot * * Portions from the Manjaro Installation Framework * by Roland Singer @@ -70,6 +71,8 @@ private: KeyboardGlobal::KeyboardInfo info; }; + /// Guess a layout based on the split-apart locale + void guessLayout( const QStringList& langParts ); void updateVariants( const QPersistentModelIndex& currentItem, QString currentVariant = QString() ); diff --git a/src/modules/keyboard/keyboardwidget/keyboardglobal.h b/src/modules/keyboard/keyboardwidget/keyboardglobal.h index 8710fdaa2..965e0828f 100644 --- a/src/modules/keyboard/keyboardwidget/keyboardglobal.h +++ b/src/modules/keyboard/keyboardwidget/keyboardglobal.h @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014, Teo Mrnjavac + * Copyright 2017, Adriaan de Groot * * Originally from the Manjaro Installation Framework * by Roland Singer @@ -44,12 +45,15 @@ public: QMap< QString, QString > variants; }; - static QMap< QString, KeyboardInfo > getKeyboardLayouts(); + using LayoutsMap = QMap< QString, KeyboardInfo >; + + static LayoutsMap getKeyboardLayouts(); static QMap< QString, QString > getKeyboardModels(); + private: static QMap< QString, QString > parseKeyboardModels(QString filepath); - static QMap< QString, KeyboardInfo > parseKeyboardLayouts(QString filepath); + static LayoutsMap parseKeyboardLayouts(QString filepath); }; #endif // KEYBOARDGLOBAL_H