Changeset View
Changeset View
Standalone View
Standalone View
kcms/keyboard/layoutmodel/layout_list_models.cpp
- This file was added.
1 | #include "layout_list_models.h" | ||||
---|---|---|---|---|---|
2 | | ||||
3 | #include <KConfigGroup> | ||||
4 | #include <KProcess> | ||||
5 | #include <KSharedConfig> | ||||
6 | #include <QDBusArgument> | ||||
7 | #include <QDebug> | ||||
8 | | ||||
9 | #include "layout_list_concat_proxy_model.h" | ||||
10 | #include "layout_list_filter_disabled_proxy_model.h" | ||||
11 | #include "layout_list_filter_duplicates_proxy_model.h" | ||||
12 | #include "layout_list_filter_source_proxy_model.h" | ||||
13 | #include "layout_list_model_fcitx.h" | ||||
14 | #include "layout_list_model_selected.h" | ||||
15 | #include "layout_list_model_xkb.h" | ||||
16 | #include "layout_list_sort_by_priority_proxy_model.h" | ||||
17 | #include "layout_list_sort_filter_proxy_model.h" | ||||
18 | #include "layout_list_xkb_expand_proxy_model.h" | ||||
19 | #include "layout_list_current_proxy_model.h" | ||||
20 | #include "input_sources.h" | ||||
21 | | ||||
22 | LayoutListModels::LayoutListModels(QObject* parent) | ||||
23 | : QObject(parent) | ||||
24 | , m_kdedIface(new QDBusInterface("org.kde.keyboard", "/Layouts", "org.kde.KeyboardLayouts")) | ||||
25 | , m_fcitxIface(new QDBusInterface("org.fcitx.Fcitx", "/inputmethod", "org.freedesktop.DBus.Properties")) | ||||
26 | { | ||||
27 | // Setup models | ||||
28 | auto xkbModel = new LayoutListModelXkb(this); | ||||
29 | auto expanded_xkb = new LayoutListXkbExpandProxyModel(this); | ||||
30 | expanded_xkb->setSourceModel(xkbModel); | ||||
31 | | ||||
32 | auto fcitxModel = new LayoutListModelFcitx(this); | ||||
33 | m_selected = new LayoutListModelSelected(this); | ||||
34 | | ||||
35 | auto concat = new LayoutListConcatProxyModel(this); | ||||
36 | concat->addSourceModel(expanded_xkb); | ||||
37 | concat->addSourceModel(fcitxModel); | ||||
38 | concat->addSourceModel(m_selected); | ||||
39 | | ||||
40 | auto filterSourceModel = new LayoutListFilterSourceProxyModel(this); | ||||
41 | filterSourceModel->setSourceModel(concat); | ||||
42 | | ||||
43 | auto sortBySaveNameModel = new LayoutListSortFilterProxyModel(this); | ||||
44 | sortBySaveNameModel->setSourceModel(filterSourceModel); | ||||
45 | sortBySaveNameModel->setSortRole(LayoutListModelBase::Roles::SaveNameRole); | ||||
46 | sortBySaveNameModel->sort(0); | ||||
47 | sortBySaveNameModel->setDynamicSortFilter(true); | ||||
48 | | ||||
49 | auto removeDuplicatesModel = new LayoutListFilterDuplicatesProxyModel(this); | ||||
50 | m_layoutListModel = removeDuplicatesModel; | ||||
51 | removeDuplicatesModel->setSourceModel(sortBySaveNameModel); | ||||
52 | | ||||
53 | connect(removeDuplicatesModel, &LayoutListFilterDuplicatesProxyModel::itemAdded, | ||||
54 | m_selected, &LayoutListModelSelected::add); | ||||
55 | | ||||
56 | connect(removeDuplicatesModel, &LayoutListFilterDuplicatesProxyModel::itemAdded, | ||||
57 | removeDuplicatesModel, &LayoutListFilterDuplicatesProxyModel::invalidate); | ||||
58 | | ||||
59 | connect(m_selected, &LayoutListModelSelected::modelReset, | ||||
60 | removeDuplicatesModel, &LayoutListFilterDuplicatesProxyModel::updateEnabled); | ||||
61 | | ||||
62 | connect(m_selected, &LayoutListModelSelected::modelReset, | ||||
63 | removeDuplicatesModel, &LayoutListFilterDuplicatesProxyModel::missingCountChanged); | ||||
64 | | ||||
65 | // TODO: make it update without including fcitxdetector here for extensibility | ||||
66 | // TODO: make it work without updating the entire model | ||||
67 | connect(InputSources::self(), &InputSources::currentSourceChanged, | ||||
68 | removeDuplicatesModel, &LayoutListFilterDuplicatesProxyModel::invalidate); | ||||
69 | | ||||
70 | connect(InputSources::self(), &InputSources::currentSourceChanged, | ||||
71 | removeDuplicatesModel, &LayoutListFilterDuplicatesProxyModel::missingCountChanged); | ||||
72 | | ||||
73 | auto filterDisabledModel = new LayoutListFilterDisabledProxyModel(this); | ||||
74 | filterDisabledModel->setSourceModel(removeDuplicatesModel); | ||||
75 | | ||||
76 | m_configuredLayoutListModel = new LayoutListSortByPriorityProxyModel(this); | ||||
77 | m_configuredLayoutListModel->setSourceModel(filterDisabledModel); | ||||
78 | | ||||
79 | connect(m_configuredLayoutListModel, &LayoutListSortByPriorityProxyModel::enabledOrderChanged, | ||||
80 | m_selected, &LayoutListModelSelected::setOrder); | ||||
81 | | ||||
82 | connect(m_configuredLayoutListModel, &LayoutListSortByPriorityProxyModel::itemRemoved, | ||||
83 | m_selected, &LayoutListModelSelected::remove); | ||||
84 | | ||||
85 | connect(m_configuredLayoutListModel, &LayoutListSortByPriorityProxyModel::itemRemoved, | ||||
86 | removeDuplicatesModel, &LayoutListFilterDuplicatesProxyModel::invalidate); | ||||
87 | | ||||
88 | m_currentLayoutListModel = new LayoutListCurrentProxyModel(this); | ||||
89 | m_currentLayoutListModel->setSourceModel(m_configuredLayoutListModel); | ||||
90 | | ||||
91 | connect(m_kdedIface, SIGNAL(currentLayoutChanged(QString)), this, SLOT(setCurrentLayoutByName(QString))); | ||||
92 | connect(m_fcitxIface, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList)), this, SLOT(fcitxPropertyChanged(QString, QVariantMap, QStringList))); | ||||
93 | } | ||||
94 | | ||||
95 | LayoutListFilterDuplicatesProxyModel *LayoutListModels::entireLayoutListModel() const | ||||
96 | { | ||||
97 | return m_layoutListModel; | ||||
98 | } | ||||
99 | | ||||
100 | LayoutListSortByPriorityProxyModel *LayoutListModels::configuredLayoutListModel() const | ||||
101 | { | ||||
102 | return m_configuredLayoutListModel; | ||||
103 | } | ||||
104 | | ||||
105 | LayoutListCurrentProxyModel *LayoutListModels::currentLayoutListModel() const | ||||
106 | { | ||||
107 | return m_currentLayoutListModel; | ||||
108 | } | ||||
109 | | ||||
110 | int LayoutListModels::currentLayoutIndex() | ||||
111 | { | ||||
112 | return m_currentLayoutIndex; | ||||
113 | } | ||||
114 | | ||||
115 | void LayoutListModels::setCurrentLayoutIndex(int new_index) | ||||
116 | { | ||||
117 | qDebug() << new_index; | ||||
118 | | ||||
119 | if (m_currentLayoutIndex != new_index) { | ||||
120 | m_currentLayoutIndex = new_index; | ||||
121 | emit currentLayoutIndexChanged(); | ||||
122 | } | ||||
123 | } | ||||
124 | | ||||
125 | void LayoutListModels::switchLayout(int new_index) | ||||
126 | { | ||||
127 | QString name = m_currentLayoutListModel->data( | ||||
128 | m_currentLayoutListModel->index(new_index, 0), | ||||
129 | LayoutListModelBase::Roles::SaveNameRole).toString(); | ||||
130 | m_kdedIface->call("setLayout", name); | ||||
131 | } | ||||
132 | | ||||
133 | void LayoutListModels::openConfigDialog() | ||||
134 | { | ||||
135 | KProcess dialog; | ||||
136 | dialog << "kcmshell5" << "kcm_keyboard"; | ||||
137 | dialog.startDetached(); | ||||
138 | } | ||||
139 | | ||||
140 | QString LayoutListModels::currentIconName() | ||||
141 | { | ||||
142 | QDBusMessage msg = QDBusMessage::createMethodCall( | ||||
143 | "org.fcitx.Fcitx", | ||||
144 | "/StatusNotifierItem", | ||||
145 | QLatin1String("org.freedesktop.DBus.Properties"), | ||||
146 | QLatin1String("Get")); | ||||
147 | msg.setArguments(QVariantList() << "org.kde.StatusNotifierItem" << "IconName"); | ||||
148 | QDBusMessage reply = QDBusConnection::sessionBus().call(msg); | ||||
149 | QDBusVariant dbusArgs = reply.arguments().first().value<QDBusVariant>(); | ||||
150 | return dbusArgs.variant().toString(); | ||||
151 | } | ||||
152 | | ||||
153 | void LayoutListModels::setCurrentLayoutByName(const QString &saveName) | ||||
154 | { | ||||
155 | qDebug() << saveName; | ||||
156 | int count = m_currentLayoutListModel->rowCount(); | ||||
157 | for (int i = 0; i < count; ++i) { | ||||
158 | QString name = m_currentLayoutListModel->data( | ||||
159 | m_currentLayoutListModel->index(i, 0), | ||||
160 | LayoutListModelBase::Roles::SaveNameRole).toString(); | ||||
161 | if (name == saveName) { | ||||
162 | setCurrentLayoutIndex(i); | ||||
163 | return; | ||||
164 | } | ||||
165 | } | ||||
166 | qWarning() << "Cannot set layout" << saveName; | ||||
167 | } | ||||
168 | | ||||
169 | void LayoutListModels::fcitxPropertyChanged(QString const&, QVariantMap const&, QStringList const& invalidated) | ||||
170 | { | ||||
171 | qDebug() << invalidated; | ||||
172 | if (invalidated.contains("CurrentIM")) { | ||||
173 | emit currentLayoutIndexChanged(); | ||||
174 | } | ||||
175 | } | ||||
176 | | ||||
177 | void LayoutListModels::loadConfig() | ||||
178 | { | ||||
179 | KConfigGroup config( | ||||
180 | KSharedConfig::openConfig(QStringLiteral("kxkbrc"), KConfig::NoGlobals), | ||||
181 | QStringLiteral("Layout")); | ||||
182 | | ||||
183 | QString layoutsString = config.readEntry<QString>("LayoutList", ""); | ||||
184 | QList<LayoutListModelSelected::EnabledLayout> list; | ||||
185 | | ||||
186 | for (QString layout : layoutsString.split(',')) { | ||||
187 | LayoutListModelSelected::EnabledLayout l; | ||||
188 | l.saveName = layout; | ||||
189 | l.isLatinModeEnabled = false; | ||||
190 | l.latinModeLayout = ""; | ||||
191 | | ||||
192 | if (layout.startsWith("fcitx:")) { | ||||
193 | QString origName = layout.split(":")[1]; | ||||
194 | | ||||
195 | l.isLatinModeEnabled = config.readEntry<bool>(QString("Fcitx%1LatinFallBackEnabled").arg(origName), false); | ||||
196 | if (l.isLatinModeEnabled) { | ||||
197 | l.latinModeLayout = config.readEntry<QString>(QString("Fcitx%1LatinFallBack").arg(origName), "us"); | ||||
198 | } | ||||
199 | } | ||||
200 | | ||||
201 | qDebug() << l.saveName << l.isLatinModeEnabled << l.latinModeLayout; | ||||
202 | | ||||
203 | list << l; | ||||
204 | } | ||||
205 | | ||||
206 | m_selected->setEnabledLayouts(list); | ||||
207 | | ||||
208 | QDBusMessage reply = m_kdedIface->call("getCurrentLayout"); | ||||
209 | setCurrentLayoutByName(reply.arguments().first().toString()); | ||||
210 | } | ||||
211 | | ||||
212 | void LayoutListModels::saveConfig() | ||||
213 | { | ||||
214 | KConfigGroup config( | ||||
215 | KSharedConfig::openConfig(QStringLiteral("kxkbrc"), KConfig::NoGlobals), | ||||
216 | QStringLiteral("Layout")); | ||||
217 | | ||||
218 | QStringList layouts; | ||||
219 | for (LayoutListModelSelected::EnabledLayout enabledLayout : m_selected->enabledLayouts()) { | ||||
220 | layouts << enabledLayout.saveName; | ||||
221 | } | ||||
222 | config.writeEntry<QString>("LayoutList", layouts.join(",")); | ||||
223 | } |