17#include <QDBusMetaType>
20#define GNOME_DESKTOP_USE_UNSTABLE_API
21#include <libgnome-desktop/gnome-xkb-info.h>
23#include "keyboardLayoutsModel.h"
25typedef QList<QMap<QString, QString>> StringMapList;
26Q_DECLARE_METATYPE(StringMapList)
28KeyboardLayoutsModel::KeyboardLayoutsModel(QObject *parent)
29 : QAbstractListModel(parent)
32 {LayoutIdRole,
"layoutId"},
33 {DisplayNameRole,
"displayName"},
34 {LanguageRole,
"language"}
37 qDBusRegisterMetaType<StringMapList>();
40 connect(
this, &KeyboardLayoutsModel::languageChanged,
this, &KeyboardLayoutsModel::updateModel);
43QString KeyboardLayoutsModel::language()
const
48void KeyboardLayoutsModel::setLanguage(
const QString &language)
50 if (m_language == language)
53 m_language = language;
54 Q_EMIT languageChanged(language);
57static bool compareLayouts(
const KeyboardLayoutInfo &layout0,
const KeyboardLayoutInfo &layout1)
59 QString name0(layout0.id);
60 QString name1(layout1.id);
63 name0 = layout0.displayName;
64 name1 = layout1.displayName;
67 name0 = layout0.language;
68 name1 = layout1.language;
72 return QString::localeAwareCompare(name0, name1) < 0;
75void KeyboardLayoutsModel::buildModel()
78 const gchar *display_name;
79 const gchar *short_name;
80 const gchar *xkb_layout;
81 const gchar *xkb_variant;
83 GnomeXkbInfo * xkbInfo(gnome_xkb_info_new());
85 sources = gnome_xkb_info_get_all_layouts(xkbInfo);
87 for (tmp = sources; tmp != NULL; tmp = tmp->next) {
88 gboolean result = gnome_xkb_info_get_layout_info(xkbInfo, (
const gchar *)tmp->data,
89 &display_name, &short_name, &xkb_layout, &xkb_variant);
91 qWarning() <<
"Skipping invalid layout";
95 KeyboardLayoutInfo layout;
96 layout.id = QString::fromUtf8((
const gchar *)tmp->data);
97 layout.language = QString::fromUtf8(short_name);
98 layout.displayName = QString::fromUtf8(display_name);
102 g_list_free(sources);
103 g_object_unref(xkbInfo);
105 std::sort(m_db.begin(), m_db.end(), compareLayouts);
108void KeyboardLayoutsModel::updateModel()
113 const QString lang = m_language.section(
"_", 0, 0);
114 const QString country = m_language.section(
"_", 1, 1).toLower();
116 Q_FOREACH(
const KeyboardLayoutInfo & info, m_db) {
117 const QString kbdCountry = info.id.section(
"+", 0, 0);
118 if (info.language == lang &&
119 (kbdCountry.startsWith(country) || kbdCountry.length() > 2)) {
120 m_layouts.append(info);
124 std::sort(m_layouts.begin(), m_layouts.end(), compareLayouts);
128int KeyboardLayoutsModel::rowCount(
const QModelIndex &parent)
const
131 return m_layouts.count();
134QVariant KeyboardLayoutsModel::data(
const QModelIndex &index,
int role)
const
136 const int row = index.row();
138 if (row >= m_layouts.count()) {
139 qWarning() << Q_FUNC_INFO <<
"index out of bounds";
143 const KeyboardLayoutInfo &layout = m_layouts.at(row);
146 case Qt::DisplayRole:
147 case DisplayNameRole:
148 return layout.displayName;
152 return layout.language;
154 qWarning() << Q_FUNC_INFO <<
"unsupported data role";
160QHash<int, QByteArray> KeyboardLayoutsModel::roleNames()
const