New keyboard viewmodule, based on the one from Manjaro's minst.

This commit is contained in:
Teo Mrnjavac 2014-07-04 15:33:59 +02:00
parent ee485f9735
commit 7a99214ddb
14 changed files with 1256 additions and 0 deletions

View File

@ -0,0 +1,17 @@
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
calamares_add_plugin( keyboard
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
CONFIG_FILE module.conf
SOURCES
KeyboardViewStep.cpp
KeyboardPage.cpp
keyboardwidget/keyboardglobal.cpp
keyboardwidget/keyboardpreview.cpp
UI
KeyboardPage.ui
LINK_LIBRARIES
calamaresui
SHARED_LIB
)

View File

@ -0,0 +1,232 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Portions from the Manjaro Installation Framework
* by Roland Singer <roland@manjaro.org>
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* 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 "KeyboardPage.h"
#include "ui_KeyboardPage.h"
#include "keyboardwidget/keyboardpreview.h"
#include <QComboBox>
#include <QProcess>
#include <QPushButton>
KeyboardPage::KeyboardPage( QWidget* parent )
: QWidget()
, ui( new Ui::Page_Keyboard )
, m_keyboardPreview( new KeyBoardPreview( this ) )
{
ui->setupUi( this );
// Keyboard Preview
ui->KBPreviewLayout->addWidget( m_keyboardPreview );
// Connect signals and slots
connect( ui->listLayout, &QListWidget::currentItemChanged,
this, &KeyboardPage::onListLayoutCurrentItemChanged );
connect( ui->listVariant, &QListWidget::currentItemChanged,
this, &KeyboardPage::onListVariantCurrentItemChanged );
connect( ui->buttonRestore, &QPushButton::clicked,
[this]
{
ui->comboBoxModel->setCurrentIndex( m_defaultIndex );
});
connect( ui->comboBoxModel,
static_cast< void ( QComboBox::* )( const QString& ) >( &QComboBox::currentIndexChanged ),
[this]( const QString& text )
{
QString model = m_models.value( text, "pc105" );
// Set Xorg keyboard model
QProcess::execute( QString( "setxkbmap -model \"%1\"" )
.arg( model ).toUtf8() );
});
}
KeyboardPage::~KeyboardPage()
{
delete ui;
}
void
KeyboardPage::init()
{
//### Detect current keyboard layout and variant
QString currentLayout;
QProcess process;
process.start( "setxkbmap", QStringList() << "-print" );
if ( process.waitForFinished() )
{
QStringList list = QString( process.readAll() )
.split( "\n", QString::SkipEmptyParts );
foreach( QString line, list )
{
line = line.trimmed();
if ( !line.startsWith( "xkb_symbols" ) )
continue;
line = line.remove( "}" )
.remove( "{" )
.remove( ";" );
line = line.mid( line.indexOf( "\"" ) + 1 );
QStringList split = line.split( "+", QString::SkipEmptyParts );
if ( split.size() >= 2 )
{
currentLayout = split.at( 1 );
if ( currentLayout.contains( "(" ) )
currentLayout = currentLayout
.mid( 0, currentLayout.indexOf( "(" ) )
.trimmed();
}
}
}
//### Models
m_models = KeyboardGlobal::getKeyboardModels();
QMapIterator< QString, QString > mi( m_models );
ui->comboBoxModel->blockSignals( true );
while ( mi.hasNext() )
{
mi.next();
if ( mi.value() == "pc105" )
m_defaultIndex = ui->comboBoxModel->count();
ui->comboBoxModel->addItem( mi.key() );
}
ui->comboBoxModel->blockSignals( false );
// Set to default value pc105
ui->comboBoxModel->setCurrentIndex( m_defaultIndex );
//### Layouts and Variants
// Block signals
ui->listLayout->blockSignals( true );
QMap< QString, KeyboardGlobal::KeyboardInfo > layouts =
KeyboardGlobal::getKeyboardLayouts();
QMapIterator< QString, KeyboardGlobal::KeyboardInfo > li( layouts );
LayoutItem* currentLayoutItem = nullptr;
while ( li.hasNext() )
{
li.next();
LayoutItem* item = new LayoutItem();
KeyboardGlobal::KeyboardInfo info = li.value();
item->setText( info.description );
item->data = li.key();
item->info = info;
ui->listLayout->addItem( item );
// Find current layout index
if ( li.key() == currentLayout )
currentLayoutItem = item;
}
ui->listLayout->sortItems();
// Unblock signals
ui->listLayout->blockSignals( false );
// Set current layout
if ( currentLayoutItem )
ui->listLayout->setCurrentItem( currentLayoutItem );
else if ( ui->listLayout->count() > 0 )
ui->listLayout->setCurrentRow( 0 );
}
void
KeyboardPage::onListLayoutCurrentItemChanged( QListWidgetItem* current, QListWidgetItem* previous )
{
LayoutItem *item = dynamic_cast< LayoutItem* >( current );
if ( !item )
return;
// Block signals
ui->listVariant->blockSignals( true );
QMap< QString, QString > variants = item->info.variants;
QMapIterator< QString, QString > li( variants );
LayoutItem* defaultItem = nullptr;
ui->listVariant->clear();
while ( li.hasNext() )
{
li.next();
item = new LayoutItem();
item->setText( li.key() );
item->data = li.value();
ui->listVariant->addItem( item );
if ( li.value() == "" )
defaultItem = item;
}
// Unblock signals
ui->listVariant->blockSignals( false );
// Set to default value
if ( defaultItem )
ui->listVariant->setCurrentItem( defaultItem );
}
void
KeyboardPage::onListVariantCurrentItemChanged( QListWidgetItem* current, QListWidgetItem* previous )
{
LayoutItem* layoutItem = dynamic_cast< LayoutItem* >( ui->listLayout->currentItem() );
LayoutItem* variantItem = dynamic_cast< LayoutItem* >( current );
if ( !layoutItem || !variantItem )
return;
QString layout = layoutItem->data;
QString variant = variantItem->data;
m_keyboardPreview->setLayout( layout );
m_keyboardPreview->setVariant( variant );
//emit checkReady();
// Set Xorg keyboard layout
QProcess::execute( QString( "setxkbmap -layout \"%1\" -variant \"%2\"" )
.arg( layout, variant ).toUtf8() );
}

View File

@ -0,0 +1,66 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Portions from the Manjaro Installation Framework
* by Roland Singer <roland@manjaro.org>
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* 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 KEYBOARDPAGE_H
#define KEYBOARDPAGE_H
#include "keyboardwidget/keyboardglobal.h"
#include <QListWidgetItem>
#include <QWidget>
namespace Ui
{
class Page_Keyboard;
}
class KeyBoardPreview;
class KeyboardPage : public QWidget
{
Q_OBJECT
public:
explicit KeyboardPage( QWidget* parent = nullptr );
virtual ~KeyboardPage();
void init();
protected slots:
void onListLayoutCurrentItemChanged( QListWidgetItem* current,
QListWidgetItem* previous );
void onListVariantCurrentItemChanged( QListWidgetItem* current,
QListWidgetItem* previous );
private:
class LayoutItem : public QListWidgetItem {
public:
QString data;
KeyboardGlobal::KeyboardInfo info;
};
Ui::Page_Keyboard *ui;
KeyBoardPreview* m_keyboardPreview;
int m_defaultIndex;
QMap< QString, QString > m_models;
};
#endif // KEYBOARDPAGE_H

View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Page_Keyboard</class>
<widget class="QWidget" name="Page_Keyboard">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>830</width>
<height>573</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>9</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="KBPreviewLayout"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Keyboard Model:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxModel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonRestore">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/images/restore.png</normaloff>:/images/restore.png</iconset>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>9</number>
</property>
<item>
<widget class="QListWidget" name="listLayout"/>
</item>
<item>
<widget class="QListWidget" name="listVariant"/>
</item>
</layout>
</item>
<item>
<widget class="QLineEdit" name="LE_TestKeyboard">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="inputMask">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Type here to test your keyboard</string>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>comboBoxModel</tabstop>
<tabstop>listLayout</tabstop>
<tabstop>listVariant</tabstop>
<tabstop>LE_TestKeyboard</tabstop>
<tabstop>buttonRestore</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,87 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@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 "KeyboardViewStep.h"
#include "KeyboardPage.h"
KeyboardViewStep::KeyboardViewStep( QObject* parent )
: Calamares::ViewStep( parent )
, m_widget( new KeyboardPage() )
, m_nextEnabled( false )
{
m_widget->init();
m_nextEnabled = true;
emit nextStatusChanged( m_nextEnabled );
}
KeyboardViewStep::~KeyboardViewStep()
{
if ( m_widget && m_widget->parent() == nullptr )
m_widget->deleteLater();
}
QString
KeyboardViewStep::prettyName() const
{
return tr( "Keyboard" );
}
QWidget*
KeyboardViewStep::widget()
{
return m_widget;
}
void
KeyboardViewStep::next()
{
//TODO: actually save those settings somewhere
emit done();
}
void
KeyboardViewStep::back()
{}
bool
KeyboardViewStep::isNextEnabled() const
{
return m_nextEnabled;
}
bool
KeyboardViewStep::isAtBeginning() const
{
return true;
}
bool
KeyboardViewStep::isAtEnd() const
{
return true;
}

View File

@ -0,0 +1,57 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@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 KEYBOARDVIEWSTEP_H
#define KEYBOARDVIEWSTEP_H
#include <QObject>
#include "viewpages/ViewStep.h"
#include "PluginDllMacro.h"
class KeyboardPage;
class PLUGINDLLEXPORT KeyboardViewStep : public Calamares::ViewStep
{
Q_OBJECT
Q_PLUGIN_METADATA( IID "calamares.ViewModule/1.0" )
Q_INTERFACES( Calamares::ViewStep )
public:
explicit KeyboardViewStep( QObject* parent = nullptr );
virtual ~KeyboardViewStep();
QString prettyName() const override;
QWidget* widget() override;
void next() override;
void back() override;
bool isNextEnabled() const override;
bool isAtBeginning() const override;
bool isAtEnd() const override;
private:
KeyboardPage* m_widget;
bool m_nextEnabled;
};
#endif // KEYBOARDVIEWSTEP_H

View File

@ -0,0 +1,5 @@
Keyboard layout configuration viewmodule
---
Requires ckbcomp script.
* Debian package console-setup or
* Manjaro package keyboardctl https://github.com/manjaro/packages-core/tree/master/keyboardctl

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

View File

@ -0,0 +1,171 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Originally from the Manjaro Installation Framework
* by Roland Singer <roland@manjaro.org>
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* 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 "keyboardglobal.h"
//###
//### Public methods
//###
QMap<QString, KeyboardGlobal::KeyboardInfo> KeyboardGlobal::getKeyboardLayouts() {
return parseKeyboardLayouts(XKB_FILE);
}
QMap<QString, QString> KeyboardGlobal::getKeyboardModels() {
return parseKeyboardModels(XKB_FILE);
}
//###
//### Private methods
//###
//### Source by Georg Grabler <ggrabler@gmail.com> ###//
QMap<QString, QString> KeyboardGlobal::parseKeyboardModels(QString filepath)
{
QMap<QString, QString> models;
QFile fh(filepath);
fh.open(QIODevice::ReadOnly);
if (!fh.isOpen()) {
qDebug() << "X11 Keyboard model definitions not found!";
return models;
}
bool modelsFound = false;
// read the file until the end or until we break the loop
while (!fh.atEnd()) {
QByteArray line = fh.readLine();
// check if we start with the model section in the file
if (!modelsFound && line.startsWith("! model"))
modelsFound = true;
else if (modelsFound && line.startsWith ("!"))
break;
else if (!modelsFound)
continue;
// here we are in the model section, otherwhise we would continue or break
QRegExp rx;
rx.setPattern("^\\s+(\\S+)\\s+(\\w.*)\n$");
// insert into the model map
if (rx.indexIn(line) != -1) {
QString modelDesc = rx.cap(2);
QString model = rx.cap(1);
if (model == "pc105")
modelDesc += " - " + QObject::tr("Default Keyboard Model");
models.insert(modelDesc, model);
}
}
return models;
}
QMap< QString, KeyboardGlobal::KeyboardInfo > KeyboardGlobal::parseKeyboardLayouts(QString filepath)
{
QMap< QString, KeyboardInfo > layouts;
//### Get Layouts ###//
QFile fh(filepath);
fh.open(QIODevice::ReadOnly);
if (!fh.isOpen()) {
qDebug() << "X11 Keyboard layout definitions not found!";
return layouts;
}
bool layoutsFound = false;
// read the file until the end or we break the loop
while (!fh.atEnd()) {
QByteArray line = fh.readLine();
// find the layout section otherwhise continue. If the layout section is at it's end, break the loop
if (!layoutsFound && line.startsWith("! layout"))
layoutsFound = true;
else if (layoutsFound && line.startsWith ("!"))
break;
else if (!layoutsFound)
continue;
QRegExp rx;
rx.setPattern("^\\s+(\\S+)\\s+(\\w.*)\n$");
// insert into the layout map
if (rx.indexIn(line) != -1) {
KeyboardInfo info;
info.description = rx.cap(2);
info.variants.insert(QObject::tr("Default"), "");
layouts.insert(rx.cap(1), info);
}
}
fh.reset();
//### Get Variants ###//
bool variantsFound = false;
// read the file until the end or until we break
while (!fh.atEnd()) {
QByteArray line = fh.readLine();
// continue until we found the variant section. If found, read until the next section is found
if (!variantsFound && line.startsWith("! variant")) {
variantsFound = true;
continue;
} else if (variantsFound && line.startsWith ("!"))
break;
else if (!variantsFound)
continue;
QRegExp rx;
rx.setPattern("^\\s+(\\S+)\\s+(\\S+): (\\w.*)\n$");
// insert into the variants multimap, if the pattern matches
if (rx.indexIn(line) != -1) {
if (layouts.find(rx.cap(2)) != layouts.end()) {
// in this case we found an entry in the multimap, and add the values to the multimap
layouts.find(rx.cap(2)).value().variants.insert(rx.cap(3), rx.cap(1));
} else {
// create a new map in the multimap - the value was not found.
KeyboardInfo info;
info.description = rx.cap(2);
info.variants.insert(QObject::tr("Default"), "");
info.variants.insert(rx.cap(3), rx.cap(1));
layouts.insert(rx.cap(2), info);
}
}
}
return layouts;
}

View File

@ -0,0 +1,55 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Originally from the Manjaro Installation Framework
* by Roland Singer <roland@manjaro.org>
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* 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 KEYBOARDGLOBAL_H
#define KEYBOARDGLOBAL_H
#include <QString>
#include <QFile>
#include <QTextStream>
#include <QDir>
#include <QStringList>
#include <QList>
#include <QHash>
#include <QMap>
#include <QRegExp>
#include <QDebug>
#define XKB_FILE "/usr/share/X11/xkb/rules/base.lst"
class KeyboardGlobal
{
public:
struct KeyboardInfo {
QString description;
QMap< QString, QString > variants;
};
static QMap< QString, KeyboardInfo > getKeyboardLayouts();
static QMap< QString, QString > getKeyboardModels();
private:
static QMap< QString, QString > parseKeyboardModels(QString filepath);
static QMap< QString, KeyboardInfo > parseKeyboardLayouts(QString filepath);
};
#endif // KEYBOARDGLOBAL_H

View File

@ -0,0 +1,327 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Portions from the Manjaro Installation Framework
* by Roland Singer <roland@manjaro.org>
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* 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 "keyboardpreview.h"
KeyBoardPreview::KeyBoardPreview(QWidget *parent) :
QWidget(parent)
{
setMinimumSize(700, 190);
layout = "us";
// We must set up the font size in pixels to fit the keys
lowerFont = QFont("Helvetica", 10, QFont::DemiBold);
lowerFont.setPixelSize(16);
upperFont = QFont("Helvetica", 8);
upperFont.setPixelSize(13);
// Setup keyboard types
kbList[KB_104].kb_extended_return = false;
kbList[KB_104].keys.append(QList<int>() << 0x29 << 0x2 << 0x3 << 0x4 << 0x5 << 0x6 << 0x7 << 0x8 << 0x9 << 0xa << 0xb << 0xc << 0xd);
kbList[KB_104].keys.append(QList<int>() << 0x10 << 0x11 << 0x12 << 0x13 << 0x14 << 0x15 << 0x16 << 0x17 << 0x18 << 0x19 << 0x1a << 0x1b << 0x2b);
kbList[KB_104].keys.append(QList<int>() << 0x1e << 0x1f << 0x20 << 0x21 << 0x22 << 0x23 << 0x24 << 0x25 << 0x26 << 0x27 << 0x28);
kbList[KB_104].keys.append(QList<int>() << 0x2c << 0x2d << 0x2e << 0x2f << 0x30 << 0x31 << 0x32 << 0x33 << 0x34 << 0x35);
kbList[KB_105].kb_extended_return = true;
kbList[KB_105].keys.append(QList<int>() << 0x29 << 0x2 << 0x3 << 0x4 << 0x5 << 0x6 << 0x7 << 0x8 << 0x9 << 0xa << 0xb << 0xc << 0xd);
kbList[KB_105].keys.append(QList<int>() << 0x10 << 0x11 << 0x12 << 0x13 << 0x14 << 0x15 << 0x16 << 0x17 << 0x18 << 0x19 << 0x1a << 0x1b);
kbList[KB_105].keys.append(QList<int>() << 0x1e << 0x1f << 0x20 << 0x21 << 0x22 << 0x23 << 0x24 << 0x25 << 0x26 << 0x27 << 0x28 << 0x2b);
kbList[KB_105].keys.append(QList<int>() << 0x54 << 0x2c << 0x2d << 0x2e << 0x2f << 0x30 << 0x31 << 0x32 << 0x33 << 0x34 << 0x35);
kbList[KB_106].kb_extended_return = true;
kbList[KB_106].keys.append(QList<int>() << 0x29 << 0x2 << 0x3 << 0x4 << 0x5 << 0x6 << 0x7 << 0x8 << 0x9 << 0xa << 0xb << 0xc << 0xd << 0xe);
kbList[KB_106].keys.append(QList<int>() << 0x10 << 0x11 << 0x12 << 0x13 << 0x14 << 0x15 << 0x16 << 0x17 << 0x18 << 0x19 << 0x1a << 0x1b);
kbList[KB_106].keys.append(QList<int>() << 0x1e << 0x1f << 0x20 << 0x21 << 0x22 << 0x23 << 0x24 << 0x25 << 0x26 << 0x27 << 0x28 << 0x29);
kbList[KB_106].keys.append(QList<int>() << 0x2c << 0x2d << 0x2e << 0x2f << 0x30 << 0x31 << 0x32 << 0x33 << 0x34 << 0x35 << 0x36);
kb = &kbList[KB_104];
}
void KeyBoardPreview::setLayout(QString layout) {
this->layout = layout;
}
void KeyBoardPreview::setVariant(QString variant) {
this->variant = variant;
if (!loadCodes())
return;
loadInfo();
repaint();
}
//###
//### Private
//###
void KeyBoardPreview::loadInfo() {
// kb_104
if (layout == "us" || layout == "th")
kb = &kbList[KB_104];
// kb_106
else if (layout == "jp")
kb = &kbList[KB_106];
// most keyboards are 105 key so default to that
else
kb = &kbList[KB_105];
}
bool KeyBoardPreview::loadCodes() {
if (layout.isEmpty())
return false;
QStringList param;
param << "-model" << "pc106" << "-layout" << layout << "-compact";
if (!variant.isEmpty())
param << "-variant" << variant;
QProcess process;
process.setEnvironment(QStringList() << "LANG=C" << "LC_MESSAGES=C");
process.start("ckbcomp", param);
if (!process.waitForStarted())
return false;
if (!process.waitForFinished())
return false;
// Clear codes
codes.clear();
QStringList list = QString(process.readAll()).split("\n", QString::SkipEmptyParts);
foreach(QString line, list) {
if (!line.startsWith("keycode") || !line.contains('='))
continue;
QStringList split = line.split('=').at(1).trimmed().split(' ');
if (split.size() < 4)
continue;
Code code;
code.plain = fromUnicodeString(split.at(0));
code.shift = fromUnicodeString(split.at(1));
code.ctrl = fromUnicodeString(split.at(2));
code.alt = fromUnicodeString(split.at(3));
if (code.ctrl == code.plain)
code.ctrl = "";
if (code.alt == code.plain)
code.alt = "";
codes.append(code);
}
return true;
}
QString KeyBoardPreview::fromUnicodeString(QString raw) {
if (raw.startsWith("U+"))
return QChar(raw.mid(2).toInt(0, 16));
else if (raw.startsWith("+U"))
return QChar(raw.mid(3).toInt(0, 16));
return "";
}
QString KeyBoardPreview::regular_text(int index) {
if (index < 0 || index >= codes.size())
return "";
return codes.at(index - 1).plain;
}
QString KeyBoardPreview::shift_text(int index) {
if (index < 0 || index >= codes.size())
return "";
return codes.at(index - 1).shift;
}
QString KeyBoardPreview::ctrl_text(int index) {
if (index < 0 || index >= codes.size())
return "";
return codes.at(index - 1).ctrl;
}
QString KeyBoardPreview::alt_text(int index) {
if (index < 0 || index >= codes.size())
return "";
return codes.at(index - 1).alt;
}
void KeyBoardPreview::resizeEvent(QResizeEvent *) {
space = 6;
usable_width = width()-6;
key_w = (usable_width - 14 * space)/15;
setMaximumHeight(key_w*4 + space*5);
}
void KeyBoardPreview::paintEvent(QPaintEvent * event) {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.setBrush(QColor(0xd6, 0xd6, 0xd6));
p.drawRect(rect());
QPen pen;
pen.setWidth(1);
pen.setColor(QColor(0x58, 0x58, 0x58));
p.setPen(pen);
p.setBrush(QColor(0x58, 0x58, 0x58));
p.setBackgroundMode(Qt::TransparentMode);
int rx = 3;
int x=6;
int y=6;
int first_key_w = 0;
int remaining_x[] = {0,0,0,0};
int remaining_widths[] = {0,0,0,0};
for (int i = 0; i < 4; i++) {
if (first_key_w > 0) {
first_key_w = first_key_w*1.375;
if (kb == &kbList[KB_105] && i == 3)
first_key_w = key_w * 1.275;
p.drawRoundedRect(QRectF(6, y, first_key_w, key_w), rx, rx);
x = 6 + first_key_w + space;
}
else {
first_key_w = key_w;
}
bool last_end = (i==1 && ! kb->kb_extended_return);
int rw=usable_width-x;
int ii=0;
foreach (int k, kb->keys.at(i)) {
QRectF rect = QRectF(x, y, key_w, key_w);
if (ii == kb->keys.at(i).size()-1 && last_end)
rect.setWidth(rw);
p.drawRoundedRect(rect, rx, rx);
rect.adjust(5, 1, 0, 0);
p.setPen(QColor(0x9e, 0xde, 0x00));
p.setFont(upperFont);
p.drawText(rect, Qt::AlignLeft | Qt::AlignTop, shift_text(k));
rect.setBottom(rect.bottom() - 2.5);
p.setPen(QColor(0xff, 0xff, 0xff));
p.setFont(lowerFont);
p.drawText(rect, Qt::AlignLeft | Qt::AlignBottom, regular_text(k));
rw = rw - space - key_w;
x = x + space + key_w;
ii = ii+1;
p.setPen(pen);
}
remaining_x[i] = x;
remaining_widths[i] = rw;
if (i != 1 && i != 2)
p.drawRoundedRect(QRectF(x, y, rw, key_w), rx, rx);
x=.5;
y = y + space + key_w;
}
if (kb->kb_extended_return) {
rx=rx*2;
int x1 = remaining_x[1];
int y1 = 6 + key_w*1 + space*1;
int w1 = remaining_widths[1];
int x2 = remaining_x[2];
int y2 = 6 + key_w*2 + space*2;
// this is some serious crap... but it has to be so
// maybe one day keyboards won't look like this...
// one can only hope
QPainterPath pp;
pp.moveTo(x1, y1+rx);
pp.arcTo(x1, y1, rx, rx, 180, -90);
pp.lineTo(x1+w1-rx, y1);
pp.arcTo(x1+w1-rx, y1, rx, rx, 90, -90);
pp.lineTo(x1+w1, y2+key_w-rx);
pp.arcTo(x1+w1-rx, y2+key_w-rx, rx, rx, 0, -90);
pp.lineTo(x2+rx, y2+key_w);
pp.arcTo(x2, y2+key_w-rx, rx, rx, -90, -90);
pp.lineTo(x2, y1+key_w);
pp.lineTo(x1+rx, y1+key_w);
pp.arcTo(x1, y1+key_w-rx, rx, rx, -90, -90);
pp.closeSubpath();
p.drawPath(pp);
}
else {
x= remaining_x[2];
y = 6 + key_w*2 + space*2;
p.drawRoundedRect(QRectF(x, y, remaining_widths[2], key_w), rx, rx);
}
QWidget::paintEvent(event);
}

View File

@ -0,0 +1,80 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Portions from the Manjaro Installation Framework
* by Roland Singer <roland@manjaro.org>
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* 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 KEYBOARDPREVIEW_H
#define KEYBOARDPREVIEW_H
#include <QWidget>
#include <QRectF>
#include <QFont>
#include <QPainter>
#include <QPen>
#include <QPainterPath>
#include <QColor>
#include <QPixmap>
#include <QProcess>
#include <QString>
#include <QStringList>
class KeyBoardPreview : public QWidget
{
Q_OBJECT
public:
explicit KeyBoardPreview(QWidget *parent = 0);
void setLayout(QString layout);
void setVariant(QString variant);
private:
enum KB_TYPE { KB_104, KB_105, KB_106 };
struct KB {
bool kb_extended_return;
QList<QList<int> > keys;
};
struct Code {
QString plain, shift, ctrl, alt;
};
QString layout, variant;
QFont lowerFont, upperFont;
KB *kb, kbList[3];
QList<Code> codes;
int space, usable_width, key_w;
void loadInfo();
bool loadCodes();
QString regular_text(int index);
QString shift_text(int index);
QString ctrl_text(int index);
QString alt_text(int index);
QString fromUnicodeString(QString raw);
protected:
void paintEvent(QPaintEvent * event);
void resizeEvent(QResizeEvent * event);
};
#endif // KEYBOARDPREVIEW_H

View File

@ -0,0 +1,8 @@
# Module metadata file for keyboard viewmodule
# Syntax is YAML 1.2
---
type: "view"
name: "keyboard"
interface: "qtplugin"
requires: []
load: "libcalamares_viewmodule_keyboard.so"

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>images/restore.png</file>
</qresource>
</RCC>