mirror of
https://github.com/cmclark00/retro-imager.git
synced 2025-05-18 07:55:21 +01:00
Linux Embedded: add support for language/keyboard selection
This commit is contained in:
parent
2ada96e53a
commit
fe2c1c55bd
8 changed files with 421 additions and 21 deletions
|
@ -105,6 +105,7 @@ Popup {
|
|||
}
|
||||
Layout.minimumWidth: 250
|
||||
Layout.maximumHeight: 40
|
||||
enabled: !imageWriter.isEmbeddedMode()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,10 +334,10 @@ Popup {
|
|||
text: qsTr("Keyboard layout:")
|
||||
color: parent.enabled ? "black" : "grey"
|
||||
}
|
||||
TextField {
|
||||
ComboBox {
|
||||
id: fieldKeyboardLayout
|
||||
editable: true
|
||||
Layout.minimumWidth: 200
|
||||
text: "us"
|
||||
}
|
||||
CheckBox {
|
||||
id: chkSkipFirstUse
|
||||
|
@ -431,6 +432,7 @@ Popup {
|
|||
fieldTimezone.model = imageWriter.getTimezoneList()
|
||||
fieldPublicKey.text = imageWriter.getDefaultPubKey()
|
||||
fieldWifiCountry.model = imageWriter.getCountryList()
|
||||
fieldKeyboardLayout.model = imageWriter.getKeymapLayoutList()
|
||||
|
||||
if (Object.keys(settings).length) {
|
||||
comboSaveSettings.currentIndex = 1
|
||||
|
@ -495,13 +497,25 @@ Popup {
|
|||
fieldTimezone.currentIndex = tzidx
|
||||
}
|
||||
if ('keyboardLayout' in settings) {
|
||||
fieldKeyboardLayout.text = settings.keyboardLayout
|
||||
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find(settings.keyboardLayout)
|
||||
if (fieldKeyboardLayout.currentIndex == -1) {
|
||||
fieldKeyboardLayout.editText = settings.keyboardLayout
|
||||
}
|
||||
} else {
|
||||
/* Lacking an easy cross-platform to fetch keyboard layout
|
||||
from host system, just default to "gb" for people in
|
||||
UK time zone for now, and "us" for everyone else */
|
||||
if (tz == "Europe/London") {
|
||||
fieldKeyboardLayout.text = "gb"
|
||||
if (imageWriter.isEmbeddedMode())
|
||||
{
|
||||
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find(imageWriter.getCurrentKeyboard())
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lacking an easy cross-platform to fetch keyboard layout
|
||||
from host system, just default to "gb" for people in
|
||||
UK time zone for now, and "us" for everyone else */
|
||||
if (tz == "Europe/London") {
|
||||
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("gb")
|
||||
} else {
|
||||
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("us")
|
||||
}
|
||||
}
|
||||
}
|
||||
if ('skipFirstUse' in settings) {
|
||||
|
@ -662,7 +676,7 @@ Popup {
|
|||
}
|
||||
|
||||
var kbdconfig = "XKBMODEL=\"pc105\"\n"
|
||||
kbdconfig += "XKBLAYOUT=\""+fieldKeyboardLayout.text+"\"\n"
|
||||
kbdconfig += "XKBLAYOUT=\""+fieldKeyboardLayout.editText+"\"\n"
|
||||
kbdconfig += "XKBVARIANT=\"\"\n"
|
||||
kbdconfig += "XKBOPTIONS=\"\"\n"
|
||||
|
||||
|
@ -729,7 +743,7 @@ Popup {
|
|||
}
|
||||
if (chkLocale.checked) {
|
||||
settings.timezone = fieldTimezone.editText
|
||||
settings.keyboardLayout = fieldKeyboardLayout.text
|
||||
settings.keyboardLayout = fieldKeyboardLayout.editText
|
||||
if (chkSkipFirstUse.checked) {
|
||||
settings.skipFirstUse = true
|
||||
}
|
||||
|
|
187
imagewriter.cpp
187
imagewriter.cpp
|
@ -56,10 +56,14 @@
|
|||
#include <QWinTaskbarProgress>
|
||||
#endif
|
||||
|
||||
#ifdef QT_NO_WIDGETS
|
||||
#include <QtPlatformHeaders/QEglFSFunctions>
|
||||
#endif
|
||||
|
||||
ImageWriter::ImageWriter(QObject *parent)
|
||||
: QObject(parent), _repo(QUrl(QString(OSLIST_URL))), _dlnow(0), _verifynow(0),
|
||||
_engine(nullptr), _thread(nullptr), _verifyEnabled(false), _cachingEnabled(false),
|
||||
_embeddedMode(false), _online(false)
|
||||
_embeddedMode(false), _online(false), _trans(nullptr)
|
||||
{
|
||||
connect(&_polltimer, SIGNAL(timeout()), SLOT(pollProgress()));
|
||||
|
||||
|
@ -78,6 +82,9 @@ ImageWriter::ImageWriter(QObject *parent)
|
|||
_embeddedMode = true;
|
||||
connect(&_networkchecktimer, SIGNAL(timeout()), SLOT(pollNetwork()));
|
||||
_networkchecktimer.start(100);
|
||||
changeKeyboard(detectPiKeyboard());
|
||||
if (_currentKeyboard.isEmpty())
|
||||
_currentKeyboard = "us";
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -125,11 +132,41 @@ ImageWriter::ImageWriter(QObject *parent)
|
|||
}
|
||||
}
|
||||
_settings.endGroup();
|
||||
|
||||
QDir dir(":/i18n", "rpi-imager_*.qm");
|
||||
QStringList transFiles = dir.entryList();
|
||||
QLocale currentLocale;
|
||||
QStringList localeComponents = currentLocale.name().split('_');
|
||||
QString currentlangcode;
|
||||
if (!localeComponents.isEmpty())
|
||||
currentlangcode = localeComponents.first();
|
||||
|
||||
for (QString tf : transFiles)
|
||||
{
|
||||
QString langcode = tf.mid(11, tf.length()-14);
|
||||
/* FIXME: we currently lack a font with support for Chinese characters in embedded mode */
|
||||
if (isEmbeddedMode() && langcode == "zh")
|
||||
continue;
|
||||
|
||||
QLocale loc(langcode);
|
||||
/* Use "English" for "en" and not "American English" */
|
||||
QString langname = (langcode == "en" ? "English" : loc.nativeLanguageName() );
|
||||
_translations.insert(langname, langcode);
|
||||
if (langcode == currentlangcode)
|
||||
{
|
||||
_currentLang = langname;
|
||||
}
|
||||
}
|
||||
//_currentKeyboard = "us";
|
||||
}
|
||||
|
||||
ImageWriter::~ImageWriter()
|
||||
{
|
||||
|
||||
if (_trans)
|
||||
{
|
||||
QCoreApplication::removeTranslator(_trans);
|
||||
delete _trans;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWriter::setEngine(QQmlApplicationEngine *engine)
|
||||
|
@ -153,6 +190,9 @@ void ImageWriter::setSrc(const QUrl &url, quint64 downloadLen, quint64 extrLen,
|
|||
{
|
||||
QFileInfo fi(url.toLocalFile());
|
||||
_downloadLen = fi.size();
|
||||
}
|
||||
if (url.isLocalFile())
|
||||
{
|
||||
_initFormat = "auto";
|
||||
}
|
||||
}
|
||||
|
@ -775,13 +815,27 @@ QStringList ImageWriter::getCountryList()
|
|||
QFile f(":/countries.txt");
|
||||
if ( f.open(f.ReadOnly) )
|
||||
{
|
||||
countries = QString(f.readAll()).split('\n');
|
||||
countries = QString(f.readAll()).trimmed().split('\n');
|
||||
f.close();
|
||||
}
|
||||
|
||||
return countries;
|
||||
}
|
||||
|
||||
QStringList ImageWriter::getKeymapLayoutList()
|
||||
{
|
||||
QStringList keymaps;
|
||||
QFile f(":/keymap-layouts.txt");
|
||||
if ( f.open(f.ReadOnly) )
|
||||
{
|
||||
keymaps = QString(f.readAll()).trimmed().split('\n');
|
||||
f.close();
|
||||
}
|
||||
|
||||
return keymaps;
|
||||
}
|
||||
|
||||
|
||||
QString ImageWriter::getSSID()
|
||||
{
|
||||
/* Qt used to have proper bearer management that was able to provide a list of
|
||||
|
@ -1032,6 +1086,133 @@ bool ImageWriter::imageSupportsCustomization()
|
|||
return !_initFormat.isEmpty();
|
||||
}
|
||||
|
||||
QStringList ImageWriter::getTranslations()
|
||||
{
|
||||
QStringList t = _translations.keys();
|
||||
t.sort(Qt::CaseInsensitive);
|
||||
return t;
|
||||
}
|
||||
|
||||
QString ImageWriter::getCurrentLanguage()
|
||||
{
|
||||
return _currentLang;
|
||||
}
|
||||
|
||||
QString ImageWriter::getCurrentKeyboard()
|
||||
{
|
||||
return _currentKeyboard;
|
||||
}
|
||||
|
||||
void ImageWriter::changeLanguage(const QString &newLanguageName)
|
||||
{
|
||||
if (newLanguageName.isEmpty() || newLanguageName == _currentLang || !_translations.contains(newLanguageName))
|
||||
return;
|
||||
|
||||
QString langcode = _translations[newLanguageName];
|
||||
qDebug() << "Changing language to" << langcode;
|
||||
|
||||
QTranslator *trans = new QTranslator();
|
||||
if (trans->load(":/i18n/rpi-imager_"+langcode+".qm"))
|
||||
{
|
||||
replaceTranslator(trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Failed to load translation file";
|
||||
delete trans;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWriter::changeKeyboard(const QString &newKeymapLayout)
|
||||
{
|
||||
if (newKeymapLayout.isEmpty() || newKeymapLayout == _currentKeyboard)
|
||||
return;
|
||||
|
||||
#ifdef QT_NO_WIDGETS
|
||||
QString kmapfile = "/usr/share/qmaps/"+newKeymapLayout+".qmap";
|
||||
|
||||
if (QFile::exists(kmapfile))
|
||||
QEglFSFunctions::loadKeymap(kmapfile);
|
||||
#endif
|
||||
|
||||
_currentKeyboard = newKeymapLayout;
|
||||
}
|
||||
|
||||
void ImageWriter::replaceTranslator(QTranslator *trans)
|
||||
{
|
||||
if (_trans)
|
||||
{
|
||||
QCoreApplication::removeTranslator(_trans);
|
||||
delete _trans;
|
||||
}
|
||||
|
||||
_trans = trans;
|
||||
QCoreApplication::installTranslator(_trans);
|
||||
|
||||
if (_engine)
|
||||
{
|
||||
_engine->retranslate();
|
||||
}
|
||||
}
|
||||
|
||||
QString ImageWriter::detectPiKeyboard()
|
||||
{
|
||||
unsigned int typenr = 0;
|
||||
QFile f("/proc/device-tree/chosen/rpi-country-code");
|
||||
if (f.exists() && f.open(f.ReadOnly))
|
||||
{
|
||||
QByteArray d = f.readAll();
|
||||
f.close();
|
||||
|
||||
if (d.length() == 4)
|
||||
{
|
||||
typenr = d.at(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (!typenr)
|
||||
{
|
||||
QDir dir("/dev/input/by-id");
|
||||
QRegExp rx("RPI_Wired_Keyboard_([0-9]+)");
|
||||
|
||||
for (QString fn : dir.entryList(QDir::Files))
|
||||
{
|
||||
if (rx.indexIn(fn) != -1)
|
||||
{
|
||||
typenr = rx.cap(1).toUInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typenr)
|
||||
{
|
||||
QStringList kbcountries = {
|
||||
"",
|
||||
"gb",
|
||||
"fr",
|
||||
"es",
|
||||
"us",
|
||||
"de",
|
||||
"it",
|
||||
"jp",
|
||||
"pt",
|
||||
"no",
|
||||
"se",
|
||||
"dk",
|
||||
"ru",
|
||||
"tr",
|
||||
"il"
|
||||
};
|
||||
|
||||
if (typenr < kbcountries.count())
|
||||
{
|
||||
return kbcountries.at(typenr);
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
void MountUtilsLog(std::string msg) {
|
||||
Q_UNUSED(msg)
|
||||
//qDebug() << "mountutils:" << msg.c_str();
|
||||
|
|
|
@ -19,6 +19,7 @@ class QQmlApplicationEngine;
|
|||
class DownloadThread;
|
||||
class QNetworkReply;
|
||||
class QWinTaskbarButton;
|
||||
class QTranslator;
|
||||
|
||||
class ImageWriter : public QObject
|
||||
{
|
||||
|
@ -97,6 +98,7 @@ public:
|
|||
Q_INVOKABLE QString getTimezone();
|
||||
Q_INVOKABLE QStringList getTimezoneList();
|
||||
Q_INVOKABLE QStringList getCountryList();
|
||||
Q_INVOKABLE QStringList getKeymapLayoutList();
|
||||
Q_INVOKABLE QString getSSID();
|
||||
Q_INVOKABLE QString getPSK(const QString &ssid);
|
||||
|
||||
|
@ -112,6 +114,15 @@ public:
|
|||
Q_INVOKABLE QString crypt(const QByteArray &password);
|
||||
Q_INVOKABLE QString pbkdf2(const QByteArray &psk, const QByteArray &ssid);
|
||||
|
||||
Q_INVOKABLE QStringList getTranslations();
|
||||
Q_INVOKABLE QString getCurrentLanguage();
|
||||
Q_INVOKABLE QString getCurrentKeyboard();
|
||||
Q_INVOKABLE void changeLanguage(const QString &newLanguageName);
|
||||
Q_INVOKABLE void changeKeyboard(const QString &newKeymapLayout);
|
||||
|
||||
void replaceTranslator(QTranslator *trans);
|
||||
QString detectPiKeyboard();
|
||||
|
||||
signals:
|
||||
/* We are emiting signals with QVariant as parameters because QML likes it that way */
|
||||
|
||||
|
@ -143,7 +154,7 @@ protected slots:
|
|||
|
||||
protected:
|
||||
QUrl _src, _repo;
|
||||
QString _dst, _cacheFileName, _parentCategory, _osName;
|
||||
QString _dst, _cacheFileName, _parentCategory, _osName, _currentLang, _currentKeyboard;
|
||||
QByteArray _expectedHash, _cachedFileHash, _cmdline, _config, _firstrun, _cloudinit, _cloudinitNetwork, _initFormat;
|
||||
quint64 _downloadLen, _extrLen, _devLen, _dlnow, _verifynow;
|
||||
DriveListModel _drivelist;
|
||||
|
@ -153,6 +164,8 @@ protected:
|
|||
DownloadThread *_thread;
|
||||
bool _verifyEnabled, _multipleFilesInZip, _cachingEnabled, _embeddedMode, _online;
|
||||
QSettings _settings;
|
||||
QMap<QString,QString> _translations;
|
||||
QTranslator *_trans;
|
||||
#ifdef Q_OS_WIN
|
||||
QWinTaskbarButton *_taskbarButton;
|
||||
#endif
|
||||
|
|
98
keymap-layouts.txt
Normal file
98
keymap-layouts.txt
Normal file
|
@ -0,0 +1,98 @@
|
|||
af
|
||||
al
|
||||
am
|
||||
ara
|
||||
at
|
||||
au
|
||||
az
|
||||
ba
|
||||
bd
|
||||
be
|
||||
bg
|
||||
br
|
||||
brai
|
||||
bt
|
||||
bw
|
||||
by
|
||||
ca
|
||||
cd
|
||||
ch
|
||||
cm
|
||||
cn
|
||||
cz
|
||||
de
|
||||
dk
|
||||
dz
|
||||
ee
|
||||
epo
|
||||
es
|
||||
et
|
||||
fi
|
||||
fo
|
||||
fr
|
||||
gb
|
||||
ge
|
||||
gh
|
||||
gn
|
||||
gr
|
||||
hr
|
||||
hu
|
||||
id
|
||||
ie
|
||||
il
|
||||
in
|
||||
iq
|
||||
ir
|
||||
is
|
||||
it
|
||||
jp
|
||||
jv
|
||||
ke
|
||||
kg
|
||||
kh
|
||||
kr
|
||||
kz
|
||||
la
|
||||
latam
|
||||
lk
|
||||
lt
|
||||
lv
|
||||
ma
|
||||
mao
|
||||
md
|
||||
me
|
||||
mk
|
||||
ml
|
||||
mm
|
||||
mn
|
||||
mt
|
||||
mv
|
||||
my
|
||||
ng
|
||||
nl
|
||||
no
|
||||
np
|
||||
ph
|
||||
pk
|
||||
pl
|
||||
pt
|
||||
ro
|
||||
rs
|
||||
ru
|
||||
se
|
||||
si
|
||||
sk
|
||||
sn
|
||||
sy
|
||||
tg
|
||||
th
|
||||
tj
|
||||
tm
|
||||
tr
|
||||
tw
|
||||
tz
|
||||
ua
|
||||
us
|
||||
uz
|
||||
vn
|
||||
za
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include <QDBusInterface>
|
||||
|
||||
class QDBusInterface;
|
||||
|
||||
class UDisks2Api : public QObject
|
||||
{
|
||||
|
|
24
main.cpp
24
main.cpp
|
@ -20,6 +20,8 @@
|
|||
#include <QLocale>
|
||||
#include <QScreen>
|
||||
#include <QSettings>
|
||||
#include <QFont>
|
||||
#include <QFontDatabase>
|
||||
#ifndef QT_NO_WIDGETS
|
||||
#include <QtWidgets/QApplication>
|
||||
#endif
|
||||
|
@ -63,6 +65,14 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
/* Set default font */
|
||||
QStringList fontList = QFontDatabase::applicationFontFamilies(QFontDatabase::addApplicationFont(":/fonts/Roboto-Regular.ttf"));
|
||||
QGuiApplication::setFont(QFont(fontList.first(), 10));
|
||||
|
||||
QLocale::Language l = QLocale::system().language();
|
||||
if (l == QLocale::AnyLanguage || l == QLocale::C)
|
||||
QLocale::setDefault(QLocale("en"));
|
||||
#else
|
||||
QApplication app(argc, argv);
|
||||
#endif
|
||||
|
@ -73,7 +83,7 @@ int main(int argc, char *argv[])
|
|||
ImageWriter imageWriter;
|
||||
NetworkAccessManagerFactory namf;
|
||||
QQmlApplicationEngine engine;
|
||||
QTranslator translator;
|
||||
QTranslator *translator = new QTranslator;
|
||||
QString customQm;
|
||||
QSettings settings;
|
||||
|
||||
|
@ -206,13 +216,17 @@ int main(int argc, char *argv[])
|
|||
QLocale::setDefault(QLocale(langcode));
|
||||
#endif
|
||||
|
||||
if (translator.load(QLocale(), "rpi-imager", "_", QLatin1String(":/i18n")))
|
||||
QCoreApplication::installTranslator(&translator);
|
||||
if (translator->load(QLocale(), "rpi-imager", "_", QLatin1String(":/i18n")))
|
||||
imageWriter.replaceTranslator(translator);
|
||||
else
|
||||
delete translator;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (translator.load(customQm))
|
||||
QCoreApplication::installTranslator(&translator);
|
||||
if (translator->load(customQm))
|
||||
imageWriter.replaceTranslator(translator);
|
||||
else
|
||||
delete translator;
|
||||
}
|
||||
|
||||
if (!url.isEmpty())
|
||||
|
|
80
main.qml
80
main.qml
|
@ -83,7 +83,7 @@ ApplicationWindow {
|
|||
anchors.rightMargin: 50
|
||||
anchors.leftMargin: 50
|
||||
|
||||
rows: 3
|
||||
rows: 4
|
||||
columns: 3
|
||||
columnSpacing: 25
|
||||
|
||||
|
@ -259,6 +259,7 @@ ApplicationWindow {
|
|||
id: customizebutton
|
||||
source: "icons/ic_cog_40px.svg"
|
||||
visible: false
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
|
@ -267,6 +268,82 @@ ApplicationWindow {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: langbar
|
||||
Layout.columnSpan: 3
|
||||
Layout.alignment: Qt.AlignCenter | Qt.AlignBottom
|
||||
/* FIXME: shouldn't use anchors here. But Layout bottom alignment does not
|
||||
seem to be respected */
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 5
|
||||
spacing: 10
|
||||
|
||||
visible: imageWriter.isEmbeddedMode()
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: langbar
|
||||
color: "#ffffe3"
|
||||
radius: 5
|
||||
}
|
||||
|
||||
Text {
|
||||
font.pixelSize: 12
|
||||
font.family: roboto.name
|
||||
text: qsTr("Language: ")
|
||||
Layout.leftMargin: 30
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
}
|
||||
ComboBox {
|
||||
font.pixelSize: 12
|
||||
font.family: roboto.name
|
||||
model: imageWriter.getTranslations()
|
||||
Layout.preferredWidth: 200
|
||||
currentIndex: -1
|
||||
Component.onCompleted: {
|
||||
currentIndex = find(imageWriter.getCurrentLanguage())
|
||||
}
|
||||
onActivated: {
|
||||
imageWriter.changeLanguage(editText)
|
||||
}
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
}
|
||||
Text {
|
||||
font.pixelSize: 12
|
||||
font.family: roboto.name
|
||||
text: qsTr("Keyboard: ")
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
}
|
||||
ComboBox {
|
||||
enabled: imageWriter.isEmbeddedMode()
|
||||
font.pixelSize: 12
|
||||
font.family: roboto.name
|
||||
model: imageWriter.getKeymapLayoutList()
|
||||
currentIndex: -1
|
||||
Component.onCompleted: {
|
||||
currentIndex = find(imageWriter.getCurrentKeyboard())
|
||||
}
|
||||
onActivated: {
|
||||
imageWriter.changeKeyboard(editText)
|
||||
}
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
Layout.rightMargin: 30
|
||||
}
|
||||
}
|
||||
|
||||
/* Language/keyboard bar is normally only visible in embedded mode.
|
||||
To test translations also show it when shift+ctrl+L is pressed. */
|
||||
Shortcut {
|
||||
sequences: ["Shift+Ctrl+L", "Shift+Meta+L"]
|
||||
context: Qt.ApplicationShortcut
|
||||
onActivated: {
|
||||
langbar.visible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -779,6 +856,7 @@ ApplicationWindow {
|
|||
noButton: true
|
||||
title: qsTr("Warning")
|
||||
onYes: {
|
||||
langbar.visible = false
|
||||
writebutton.enabled = false
|
||||
customizebutton.visible = false
|
||||
cancelwritebutton.enabled = true
|
||||
|
|
1
qml.qrc
1
qml.qrc
|
@ -29,5 +29,6 @@
|
|||
<file>icons/ic_info_16px.png</file>
|
||||
<file>icons/ic_info_12px.png</file>
|
||||
<file>icons/ic_cog_40px.svg</file>
|
||||
<file>keymap-layouts.txt</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue