diff --git a/src/modules/keyboard/CMakeLists.txt b/src/modules/keyboard/CMakeLists.txt index e9037bc03..32e9a0592 100644 --- a/src/modules/keyboard/CMakeLists.txt +++ b/src/modules/keyboard/CMakeLists.txt @@ -7,6 +7,7 @@ calamares_add_plugin( keyboard TYPE viewmodule EXPORT_MACRO PLUGINDLLEXPORT_PRO SOURCES + Config.cpp KeyboardViewStep.cpp KeyboardPage.cpp KeyboardLayoutModel.cpp diff --git a/src/modules/keyboard/Config.cpp b/src/modules/keyboard/Config.cpp index 11a20bbb7..7f7eb7b27 100644 --- a/src/modules/keyboard/Config.cpp +++ b/src/modules/keyboard/Config.cpp @@ -18,170 +18,28 @@ #include "utils/Logger.h" #include "utils/Retranslator.h" #include "utils/String.h" +#include "utils/Variant.h" #include #include #include -KeyboardModelsModel::KeyboardModelsModel( QObject* parent ) - : QAbstractListModel( parent ) +/* Returns stringlist with suitable setxkbmap command-line arguments + * to set the given @p model. + */ +static inline QStringList +xkbmap_model_args( const QString& model ) { - detectModels(); + QStringList r { "-model", model }; + return r; } -void -KeyboardModelsModel::detectModels() -{ - beginResetModel(); - const auto models = KeyboardGlobal::getKeyboardModels(); - auto index = -1; - for ( const auto& key : models.keys() ) - { - index++; - m_list << QMap< QString, QString > { { "label", key }, { "key", models[ key ] } }; - if ( models[ key ] == "pc105" ) - { - this->setCurrentIndex( index ); - } - } - endResetModel(); -} - -void -KeyboardModelsModel::refresh() -{ - m_list.clear(); - setCurrentIndex( -1 ); - detectModels(); -} - -QVariant -KeyboardModelsModel::data( const QModelIndex& index, int role ) const -{ - if ( !index.isValid() ) - { - return QVariant(); - } - const auto item = m_list.at( index.row() ); - return role == Qt::DisplayRole ? item[ "label" ] : item[ "key" ]; -} - -int -KeyboardModelsModel::rowCount( const QModelIndex& ) const -{ - return m_list.count(); -} - -QHash< int, QByteArray > -KeyboardModelsModel::roleNames() const -{ - return { { Qt::DisplayRole, "label" }, { Qt::UserRole, "key" } }; -} - -int -KeyboardModelsModel::currentIndex() const -{ - return m_currentIndex; -} - -const QMap< QString, QString > -KeyboardModelsModel::item( const int& index ) const -{ - if ( index >= m_list.count() || index < 0 ) - { - return QMap< QString, QString >(); - } - - return m_list.at( index ); -} - -const QMap< QString, QString > -KeyboardVariantsModel::item( const int& index ) const -{ - if ( index >= m_list.count() || index < 0 ) - { - return QMap< QString, QString >(); - } - - return m_list.at( index ); -} - -void -KeyboardModelsModel::setCurrentIndex( const int& index ) -{ - if ( index >= m_list.count() || index < 0 ) - { - return; - } - - m_currentIndex = index; - emit currentIndexChanged( m_currentIndex ); -} - -KeyboardVariantsModel::KeyboardVariantsModel( QObject* parent ) - : QAbstractListModel( parent ) -{ -} - -int -KeyboardVariantsModel::currentIndex() const -{ - return m_currentIndex; -} - -void -KeyboardVariantsModel::setCurrentIndex( const int& index ) -{ - if ( index >= m_list.count() || index < 0 ) - { - return; - } - - m_currentIndex = index; - emit currentIndexChanged( m_currentIndex ); -} - -QVariant -KeyboardVariantsModel::data( const QModelIndex& index, int role ) const -{ - if ( !index.isValid() ) - { - return QVariant(); - } - const auto item = m_list.at( index.row() ); - return role == Qt::DisplayRole ? item[ "label" ] : item[ "key" ]; -} - -int -KeyboardVariantsModel::rowCount( const QModelIndex& ) const -{ - return m_list.count(); -} - -QHash< int, QByteArray > -KeyboardVariantsModel::roleNames() const -{ - return { { Qt::DisplayRole, "label" }, { Qt::UserRole, "key" } }; -} - -void -KeyboardVariantsModel::setVariants( QMap< QString, QString > variants ) -{ - m_list.clear(); - beginResetModel(); - for ( const auto& key : variants.keys() ) - { - const auto item = QMap< QString, QString > { { "label", key }, { "key", variants[ key ] } }; - m_list << item; - } - endResetModel(); -} /* Returns stringlist with suitable setxkbmap command-line arguments * to set the given @p layout and @p variant. */ static inline QStringList -xkbmap_args( const QString& layout, const QString& variant ) +xkbmap_layout_args( const QString& layout, const QString& variant ) { QStringList r { "-layout", layout }; if ( !variant.isEmpty() ) @@ -203,7 +61,7 @@ Config::Config( QObject* parent ) connect( m_keyboardModelsModel, &KeyboardModelsModel::currentIndexChanged, [&]( int index ) { m_selectedModel = m_keyboardModelsModel->item( index ).value( "key", "pc105" ); // Set Xorg keyboard model - QProcess::execute( "setxkbmap", QStringList { "-model", m_selectedModel } ); + QProcess::execute( "setxkbmap", xkbmap_model_args( m_selectedModel ) ); emit prettyStatusChanged(); } ); @@ -224,7 +82,7 @@ Config::Config( QObject* parent ) } connect( &m_setxkbmapTimer, &QTimer::timeout, this, [=] { - QProcess::execute( "setxkbmap", xkbmap_args( m_selectedLayout, m_selectedVariant ) ); + QProcess::execute( "setxkbmap", xkbmap_layout_args( m_selectedLayout, m_selectedVariant ) ); cDebug() << "xkbmap selection changed to: " << m_selectedLayout << '-' << m_selectedVariant; m_setxkbmapTimer.disconnect( this ); } ); @@ -281,18 +139,25 @@ Config::init() { const QStringList list = QString( process.readAll() ).split( "\n", SplitSkipEmptyParts ); - for ( QString line : list ) + // A typical line looks like + // xkb_symbols { include "pc+latin+ru:2+inet(evdev)+group(alt_shift_toggle)+ctrl(swapcaps)" }; + for ( const auto& line : list ) { - line = line.trimmed(); - if ( !line.startsWith( "xkb_symbols" ) ) + if ( !line.trimmed().startsWith( "xkb_symbols" ) ) { continue; } - line = line.remove( "}" ).remove( "{" ).remove( ";" ); - line = line.mid( line.indexOf( "\"" ) + 1 ); + int firstQuote = line.indexOf('"'); + int lastQuote = line.lastIndexOf('"'); - QStringList split = line.split( "+", SplitSkipEmptyParts ); + if (firstQuote < 0 || lastQuote < 0 || lastQuote <= firstQuote) + { + continue; + } + + QStringList split = line.mid(firstQuote+1, lastQuote-firstQuote).split( "+", SplitSkipEmptyParts ); + cDebug() << split; if ( split.size() >= 2 ) { currentLayout = split.at( 1 ); @@ -350,16 +215,16 @@ Config::prettyStatus() const } Calamares::JobList -Config::createJobs( const QString& xOrgConfFileName, const QString& convertedKeymapPath, bool writeEtcDefaultKeyboard ) +Config::createJobs() { QList< Calamares::job_ptr > list; Calamares::Job* j = new SetKeyboardLayoutJob( m_selectedModel, m_selectedLayout, m_selectedVariant, - xOrgConfFileName, - convertedKeymapPath, - writeEtcDefaultKeyboard ); + m_xOrgConfFileName, + m_convertedKeymapPath, + m_writeEtcDefaultKeyboard ); list.append( Calamares::job_ptr( j ) ); return list; @@ -529,3 +394,41 @@ Config::updateVariants( const QPersistentModelIndex& currentItem, QString curren } } } + +void +Config::setConfigurationMap( const QVariantMap& configurationMap ) +{ + using namespace CalamaresUtils; + + if ( configurationMap.contains( "xOrgConfFileName" ) + && configurationMap.value( "xOrgConfFileName" ).type() == QVariant::String + && !getString( configurationMap, "xOrgConfFileName" ).isEmpty() ) + { + m_xOrgConfFileName = getString( configurationMap, "xOrgConfFileName" ); + } + else + { + m_xOrgConfFileName = "00-keyboard.conf"; + } + + if ( configurationMap.contains( "convertedKeymapPath" ) + && configurationMap.value( "convertedKeymapPath" ).type() == QVariant::String + && !getString( configurationMap, "convertedKeymapPath" ).isEmpty() ) + { + m_convertedKeymapPath = getString( configurationMap, "convertedKeymapPath" ); + } + else + { + m_convertedKeymapPath = QString(); + } + + if ( configurationMap.contains( "writeEtcDefaultKeyboard" ) + && configurationMap.value( "writeEtcDefaultKeyboard" ).type() == QVariant::Bool ) + { + m_writeEtcDefaultKeyboard = getBool( configurationMap, "writeEtcDefaultKeyboard", true ); + } + else + { + m_writeEtcDefaultKeyboard = true; + } +} diff --git a/src/modules/keyboard/Config.h b/src/modules/keyboard/Config.h index 44a893faa..9a3a3a013 100644 --- a/src/modules/keyboard/Config.h +++ b/src/modules/keyboard/Config.h @@ -20,63 +20,6 @@ #include #include -class KeyboardModelsModel : public QAbstractListModel -{ - Q_OBJECT - Q_PROPERTY( int currentIndex WRITE setCurrentIndex READ currentIndex NOTIFY currentIndexChanged ) - -public: - explicit KeyboardModelsModel( QObject* parent = nullptr ); - int rowCount( const QModelIndex& = QModelIndex() ) const override; - QVariant data( const QModelIndex& index, int role ) const override; - - void setCurrentIndex( const int& index ); - int currentIndex() const; - const QMap< QString, QString > item( const int& index ) const; - -public slots: - void refresh(); - -protected: - QHash< int, QByteArray > roleNames() const override; - -private: - int m_currentIndex = -1; - QVector< QMap< QString, QString > > m_list; - void detectModels(); - -signals: - void currentIndexChanged( int index ); -}; - -class KeyboardVariantsModel : public QAbstractListModel -{ - Q_OBJECT - Q_PROPERTY( int currentIndex WRITE setCurrentIndex READ currentIndex NOTIFY currentIndexChanged ) - -public: - explicit KeyboardVariantsModel( QObject* parent = nullptr ); - void setVariants( QMap< QString, QString > variants ); - - int rowCount( const QModelIndex& = QModelIndex() ) const override; - QVariant data( const QModelIndex& index, int role ) const override; - - void setCurrentIndex( const int& index ); - int currentIndex() const; - - const QMap< QString, QString > item( const int& index ) const; - -protected: - QHash< int, QByteArray > roleNames() const override; - -private: - int m_currentIndex = -1; - QVector< QMap< QString, QString > > m_list; - -signals: - void currentIndexChanged( int index ); -}; - class Config : public QObject { Q_OBJECT @@ -90,13 +33,14 @@ public: void init(); - Calamares::JobList - createJobs( const QString& xOrgConfFileName, const QString& convertedKeymapPath, bool writeEtcDefaultKeyboard ); + Calamares::JobList createJobs(); QString prettyStatus() const; void onActivate(); void finalize(); + void setConfigurationMap( const QVariantMap& configurationMap ); + private: void guessLayout( const QStringList& langParts ); void updateVariants( const QPersistentModelIndex& currentItem, QString currentVariant = QString() ); @@ -110,6 +54,12 @@ private: QString m_selectedVariant; QTimer m_setxkbmapTimer; + // From configuration + QString m_xOrgConfFileName; + QString m_convertedKeymapPath; + bool m_writeEtcDefaultKeyboard = true; + + protected: KeyboardModelsModel* keyboardModels() const; KeyboardLayoutModel* keyboardLayouts() const; diff --git a/src/modules/keyboard/KeyboardLayoutModel.cpp b/src/modules/keyboard/KeyboardLayoutModel.cpp index 5b92678f6..2a4ffa4d6 100644 --- a/src/modules/keyboard/KeyboardLayoutModel.cpp +++ b/src/modules/keyboard/KeyboardLayoutModel.cpp @@ -99,3 +99,158 @@ KeyboardLayoutModel::currentIndex() const { return m_currentIndex; } + +KeyboardModelsModel::KeyboardModelsModel( QObject* parent ) + : QAbstractListModel( parent ) +{ + detectModels(); +} + +void +KeyboardModelsModel::detectModels() +{ + beginResetModel(); + const auto models = KeyboardGlobal::getKeyboardModels(); + auto index = -1; + for ( const auto& key : models.keys() ) + { + index++; + m_list << QMap< QString, QString > { { "label", key }, { "key", models[ key ] } }; + if ( models[ key ] == "pc105" ) + { + this->setCurrentIndex( index ); + } + } + endResetModel(); +} + +void +KeyboardModelsModel::refresh() +{ + m_list.clear(); + setCurrentIndex( -1 ); + detectModels(); +} + +QVariant +KeyboardModelsModel::data( const QModelIndex& index, int role ) const +{ + if ( !index.isValid() ) + { + return QVariant(); + } + const auto item = m_list.at( index.row() ); + return role == Qt::DisplayRole ? item[ "label" ] : item[ "key" ]; +} + +int +KeyboardModelsModel::rowCount( const QModelIndex& ) const +{ + return m_list.count(); +} + +QHash< int, QByteArray > +KeyboardModelsModel::roleNames() const +{ + return { { Qt::DisplayRole, "label" }, { Qt::UserRole, "key" } }; +} + +int +KeyboardModelsModel::currentIndex() const +{ + return m_currentIndex; +} + +const QMap< QString, QString > +KeyboardModelsModel::item( const int& index ) const +{ + if ( index >= m_list.count() || index < 0 ) + { + return QMap< QString, QString >(); + } + + return m_list.at( index ); +} + +const QMap< QString, QString > +KeyboardVariantsModel::item( const int& index ) const +{ + if ( index >= m_list.count() || index < 0 ) + { + return QMap< QString, QString >(); + } + + return m_list.at( index ); +} + +void +KeyboardModelsModel::setCurrentIndex( const int& index ) +{ + if ( index >= m_list.count() || index < 0 ) + { + return; + } + + m_currentIndex = index; + emit currentIndexChanged( m_currentIndex ); +} + +KeyboardVariantsModel::KeyboardVariantsModel( QObject* parent ) + : QAbstractListModel( parent ) +{ +} + +int +KeyboardVariantsModel::currentIndex() const +{ + return m_currentIndex; +} + +void +KeyboardVariantsModel::setCurrentIndex( const int& index ) +{ + if ( index >= m_list.count() || index < 0 ) + { + return; + } + + m_currentIndex = index; + emit currentIndexChanged( m_currentIndex ); +} + +QVariant +KeyboardVariantsModel::data( const QModelIndex& index, int role ) const +{ + if ( !index.isValid() ) + { + return QVariant(); + } + const auto item = m_list.at( index.row() ); + return role == Qt::DisplayRole ? item[ "label" ] : item[ "key" ]; +} + +int +KeyboardVariantsModel::rowCount( const QModelIndex& ) const +{ + return m_list.count(); +} + +QHash< int, QByteArray > +KeyboardVariantsModel::roleNames() const +{ + return { { Qt::DisplayRole, "label" }, { Qt::UserRole, "key" } }; +} + +void +KeyboardVariantsModel::setVariants( QMap< QString, QString > variants ) +{ + m_list.clear(); + beginResetModel(); + for ( const auto& key : variants.keys() ) + { + const auto item = QMap< QString, QString > { { "label", key }, { "key", variants[ key ] } }; + m_list << item; + } + endResetModel(); +} + diff --git a/src/modules/keyboard/KeyboardLayoutModel.h b/src/modules/keyboard/KeyboardLayoutModel.h index f4699c9f8..0fd662263 100644 --- a/src/modules/keyboard/KeyboardLayoutModel.h +++ b/src/modules/keyboard/KeyboardLayoutModel.h @@ -51,4 +51,61 @@ signals: void currentIndexChanged( int index ); }; +class KeyboardModelsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY( int currentIndex WRITE setCurrentIndex READ currentIndex NOTIFY currentIndexChanged ) + +public: + explicit KeyboardModelsModel( QObject* parent = nullptr ); + int rowCount( const QModelIndex& = QModelIndex() ) const override; + QVariant data( const QModelIndex& index, int role ) const override; + + void setCurrentIndex( const int& index ); + int currentIndex() const; + const QMap< QString, QString > item( const int& index ) const; + +public slots: + void refresh(); + +protected: + QHash< int, QByteArray > roleNames() const override; + +private: + int m_currentIndex = -1; + QVector< QMap< QString, QString > > m_list; + void detectModels(); + +signals: + void currentIndexChanged( int index ); +}; + +class KeyboardVariantsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY( int currentIndex WRITE setCurrentIndex READ currentIndex NOTIFY currentIndexChanged ) + +public: + explicit KeyboardVariantsModel( QObject* parent = nullptr ); + void setVariants( QMap< QString, QString > variants ); + + int rowCount( const QModelIndex& = QModelIndex() ) const override; + QVariant data( const QModelIndex& index, int role ) const override; + + void setCurrentIndex( const int& index ); + int currentIndex() const; + + const QMap< QString, QString > item( const int& index ) const; + +protected: + QHash< int, QByteArray > roleNames() const override; + +private: + int m_currentIndex = -1; + QVector< QMap< QString, QString > > m_list; + +signals: + void currentIndexChanged( int index ); +}; + #endif // KEYBOARDLAYOUTMODEL_H diff --git a/src/modules/keyboard/KeyboardViewStep.cpp b/src/modules/keyboard/KeyboardViewStep.cpp index 55402fd14..03159268e 100644 --- a/src/modules/keyboard/KeyboardViewStep.cpp +++ b/src/modules/keyboard/KeyboardViewStep.cpp @@ -9,20 +9,19 @@ #include "KeyboardViewStep.h" +#include "Config.h" #include "KeyboardPage.h" #include "GlobalStorage.h" #include "JobQueue.h" -#include "utils/Variant.h" - CALAMARES_PLUGIN_FACTORY_DEFINITION( KeyboardViewStepFactory, registerPlugin< KeyboardViewStep >(); ) KeyboardViewStep::KeyboardViewStep( QObject* parent ) : Calamares::ViewStep( parent ) + , m_config( new Config(this) ) , m_widget( new KeyboardPage() ) , m_nextEnabled( false ) - , m_writeEtcDefaultKeyboard( true ) { m_widget->init(); m_nextEnabled = true; @@ -91,7 +90,7 @@ KeyboardViewStep::isAtEnd() const QList< Calamares::job_ptr > KeyboardViewStep::jobs() const { - return m_jobs; + return m_config->createJobs(); } @@ -106,7 +105,6 @@ void KeyboardViewStep::onLeave() { m_widget->finalize(); - m_jobs = m_widget->createJobs( m_xOrgConfFileName, m_convertedKeymapPath, m_writeEtcDefaultKeyboard ); m_prettyStatus = m_widget->prettyStatus(); } @@ -114,37 +112,5 @@ KeyboardViewStep::onLeave() void KeyboardViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { - using namespace CalamaresUtils; - - if ( configurationMap.contains( "xOrgConfFileName" ) - && configurationMap.value( "xOrgConfFileName" ).type() == QVariant::String - && !getString( configurationMap, "xOrgConfFileName" ).isEmpty() ) - { - m_xOrgConfFileName = getString( configurationMap, "xOrgConfFileName" ); - } - else - { - m_xOrgConfFileName = "00-keyboard.conf"; - } - - if ( configurationMap.contains( "convertedKeymapPath" ) - && configurationMap.value( "convertedKeymapPath" ).type() == QVariant::String - && !getString( configurationMap, "convertedKeymapPath" ).isEmpty() ) - { - m_convertedKeymapPath = getString( configurationMap, "convertedKeymapPath" ); - } - else - { - m_convertedKeymapPath = QString(); - } - - if ( configurationMap.contains( "writeEtcDefaultKeyboard" ) - && configurationMap.value( "writeEtcDefaultKeyboard" ).type() == QVariant::Bool ) - { - m_writeEtcDefaultKeyboard = getBool( configurationMap, "writeEtcDefaultKeyboard", true ); - } - else - { - m_writeEtcDefaultKeyboard = true; - } + m_config->setConfigurationMap(configurationMap); } diff --git a/src/modules/keyboard/KeyboardViewStep.h b/src/modules/keyboard/KeyboardViewStep.h index aa9a1d335..5cf2c6fd9 100644 --- a/src/modules/keyboard/KeyboardViewStep.h +++ b/src/modules/keyboard/KeyboardViewStep.h @@ -17,6 +17,7 @@ #include +class Config; class KeyboardPage; class PLUGINDLLEXPORT KeyboardViewStep : public Calamares::ViewStep @@ -46,15 +47,10 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; private: + Config* m_config; KeyboardPage* m_widget; bool m_nextEnabled; QString m_prettyStatus; - - QString m_xOrgConfFileName; - QString m_convertedKeymapPath; - bool m_writeEtcDefaultKeyboard; - - Calamares::JobList m_jobs; }; CALAMARES_PLUGIN_FACTORY_DECLARATION( KeyboardViewStepFactory ) diff --git a/src/modules/keyboardq/KeyboardQmlViewStep.cpp b/src/modules/keyboardq/KeyboardQmlViewStep.cpp index d42ab5269..08b72b3f4 100644 --- a/src/modules/keyboardq/KeyboardQmlViewStep.cpp +++ b/src/modules/keyboardq/KeyboardQmlViewStep.cpp @@ -79,7 +79,7 @@ void KeyboardQmlViewStep::onLeave() { m_config->finalize(); - m_jobs = m_config->createJobs( m_xOrgConfFileName, m_convertedKeymapPath, m_writeEtcDefaultKeyboard ); + // m_jobs = m_config->createJobs( m_xOrgConfFileName, m_convertedKeymapPath, m_writeEtcDefaultKeyboard ); m_prettyStatus = m_config->prettyStatus(); }