Changeset View
Changeset View
Standalone View
Standalone View
kcms/input/kcm/libinput/libinput_config.cpp
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * Copyright 2018 Roman Gilg <subdiff@gmail.com> | ||||
3 | * | ||||
4 | * This program is free software; you can redistribute it and/or modify | ||||
5 | * it under the terms of the GNU General Public License as published by | ||||
6 | * the Free Software Foundation; either version 2 of the License, or | ||||
7 | * (at your option) any later version. | ||||
8 | * | ||||
9 | * This program is distributed in the hope that it will be useful, | ||||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
12 | * GNU General Public License for more details. | ||||
13 | * | ||||
14 | * You should have received a copy of the GNU General Public License | ||||
15 | * along with this program; if not, write to the Free Software | ||||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
17 | */ | ||||
18 | | ||||
19 | #include "libinput_config.h" | ||||
20 | #include "../configcontainer.h" | ||||
21 | | ||||
22 | #include <KAboutData> | ||||
23 | #include <KLocalizedString> | ||||
24 | #include <kdeclarative/kdeclarative.h> | ||||
25 | #include <KMessageWidget> | ||||
26 | | ||||
27 | #include <QQuickItem> | ||||
28 | #include <QQuickWidget> | ||||
29 | #include <QQmlContext> | ||||
30 | #include <QVBoxLayout> | ||||
31 | #include <QQmlProperty> | ||||
32 | #include <QMetaObject> | ||||
33 | | ||||
34 | #include "inputbackend.h" | ||||
35 | | ||||
36 | static QVariant getDeviceList(InputBackend *backend) | ||||
37 | { | ||||
38 | return QVariant::fromValue(backend->getDevices().toList()); | ||||
39 | } | ||||
40 | | ||||
41 | LibinputConfig::LibinputConfig(ConfigContainer *parent, InputBackend *backend) | ||||
42 | : ConfigPlugin(parent) | ||||
43 | { | ||||
44 | m_backend = backend; | ||||
45 | | ||||
46 | KAboutData* data = new KAboutData(QStringLiteral("kcmmouse"), | ||||
47 | i18n("Pointer device KCM"), | ||||
48 | QStringLiteral("1.0"), | ||||
49 | i18n("System Settings module for managing mice and trackballs."), | ||||
50 | KAboutLicense::GPL_V2, | ||||
51 | i18n("Copyright 2018 Roman Gilg"), | ||||
52 | QString()); | ||||
53 | | ||||
54 | data->addAuthor(i18n("Roman Gilg"), | ||||
55 | i18n("Developer"), | ||||
56 | QStringLiteral("subdiff@gmail.com")); | ||||
57 | | ||||
58 | m_parent->setAboutData(data); | ||||
59 | | ||||
60 | m_initError = !m_backend->errorString().isNull(); | ||||
61 | | ||||
62 | m_view = new QQuickWidget(this); | ||||
63 | | ||||
64 | m_errorMessage = new KMessageWidget(this); | ||||
65 | m_errorMessage->setCloseButtonVisible(false); | ||||
66 | m_errorMessage->setWordWrap(true); | ||||
67 | m_errorMessage->setVisible(false); | ||||
68 | | ||||
69 | QVBoxLayout *layout = new QVBoxLayout(parent); | ||||
70 | | ||||
71 | layout->addWidget(m_errorMessage); | ||||
72 | layout->addWidget(m_view); | ||||
73 | parent->setLayout(layout); | ||||
74 | | ||||
75 | m_view->setResizeMode(QQuickWidget::SizeRootObjectToView); | ||||
76 | m_view->setClearColor(Qt::transparent); | ||||
77 | m_view->setAttribute(Qt::WA_AlwaysStackOnTop); | ||||
78 | | ||||
79 | m_view->rootContext()->setContextProperty("backend", m_backend); | ||||
80 | m_view->rootContext()->setContextProperty("deviceModel", getDeviceList(m_backend)); | ||||
81 | | ||||
82 | KDeclarative::KDeclarative kdeclarative; | ||||
83 | kdeclarative.setDeclarativeEngine(m_view->engine()); | ||||
84 | kdeclarative.setupBindings(); | ||||
85 | m_view->setSource(QUrl("qrc:/libinput/main.qml")); | ||||
86 | | ||||
87 | if (m_initError) { | ||||
88 | m_errorMessage->setMessageType(KMessageWidget::Error); | ||||
89 | m_errorMessage->setText(m_backend->errorString()); | ||||
90 | QMetaObject::invokeMethod(m_errorMessage, "animatedShow", | ||||
91 | Qt::QueuedConnection); | ||||
92 | } else { | ||||
93 | connect(m_backend, SIGNAL(deviceAdded(bool)), this, SLOT(onDeviceAdded(bool))); | ||||
94 | connect(m_backend, SIGNAL(deviceRemoved(int)), this, SLOT(onDeviceRemoved(int))); | ||||
95 | connect(m_view->rootObject(), SIGNAL(changeSignal()), this, SLOT(onChange())); | ||||
96 | } | ||||
97 | | ||||
98 | m_view->show(); | ||||
99 | } | ||||
100 | | ||||
101 | QSize LibinputConfig::sizeHint() const | ||||
102 | { | ||||
103 | return QQmlProperty::read(m_view->rootObject(), "sizeHint").toSize(); | ||||
104 | } | ||||
105 | | ||||
106 | QSize LibinputConfig::minimumSizeHint() const | ||||
107 | { | ||||
108 | return QQmlProperty::read(m_view->rootObject(), "minimumSizeHint").toSize(); | ||||
109 | } | ||||
110 | | ||||
111 | void LibinputConfig::load() | ||||
112 | { | ||||
113 | // in case of critical init error in backend, don't try | ||||
114 | if (m_initError) { | ||||
115 | return; | ||||
116 | } | ||||
117 | | ||||
118 | if (!m_backend->getConfig()) { | ||||
119 | m_errorMessage->setMessageType(KMessageWidget::Error); | ||||
120 | m_errorMessage->setText(i18n("Error while loading values. See logs for more informations. Please restart this configuration module.")); | ||||
121 | m_errorMessage->animatedShow(); | ||||
122 | } else { | ||||
123 | if (!m_backend->deviceCount()) { | ||||
124 | m_errorMessage->setMessageType(KMessageWidget::Information); | ||||
125 | m_errorMessage->setText(i18n("No pointer device found. Connect now.")); | ||||
126 | m_errorMessage->animatedShow(); | ||||
127 | } | ||||
128 | } | ||||
129 | QMetaObject::invokeMethod(m_view->rootObject(), "syncValuesFromBackend"); | ||||
130 | } | ||||
131 | | ||||
132 | void LibinputConfig::save() | ||||
133 | { | ||||
134 | if (!m_backend->applyConfig()) { | ||||
135 | m_errorMessage->setMessageType(KMessageWidget::Error); | ||||
136 | m_errorMessage->setText(i18n("Not able to save all changes. See logs for more informations. Please restart this configuration module and try again.")); | ||||
137 | m_errorMessage->animatedShow(); | ||||
138 | } else { | ||||
139 | hideErrorMessage(); | ||||
140 | } | ||||
141 | // load newly written values | ||||
142 | load(); | ||||
143 | // in case of error, config still in changed state | ||||
144 | emit m_parent->changed(m_backend->isChangedConfig()); | ||||
145 | } | ||||
146 | | ||||
147 | void LibinputConfig::defaults() | ||||
148 | { | ||||
149 | // in case of critical init error in backend, don't try | ||||
150 | if (m_initError) { | ||||
151 | return; | ||||
152 | } | ||||
153 | | ||||
154 | if (!m_backend->getDefaultConfig()) { | ||||
155 | m_errorMessage->setMessageType(KMessageWidget::Error); | ||||
156 | m_errorMessage->setText(i18n("Error while loading default values. Failed to set some options to their default values.")); | ||||
157 | m_errorMessage->animatedShow(); | ||||
158 | } | ||||
159 | QMetaObject::invokeMethod(m_view->rootObject(), "syncValuesFromBackend"); | ||||
160 | emit m_parent->changed(m_backend->isChangedConfig()); | ||||
161 | } | ||||
162 | | ||||
163 | void LibinputConfig::onChange() | ||||
164 | { | ||||
165 | if (!m_backend->deviceCount()) { | ||||
166 | return; | ||||
167 | } | ||||
168 | hideErrorMessage(); | ||||
169 | emit m_parent->changed(m_backend->isChangedConfig()); | ||||
170 | } | ||||
171 | | ||||
172 | void LibinputConfig::onDeviceAdded(bool success) | ||||
173 | { | ||||
174 | QQuickItem *rootObj = m_view->rootObject(); | ||||
175 | | ||||
176 | if (!success) { | ||||
177 | m_errorMessage->setMessageType(KMessageWidget::Error); | ||||
178 | m_errorMessage->setText(i18n("Error while adding newly connected device. Please reconnect it and restart this configuration module.")); | ||||
179 | } | ||||
180 | | ||||
181 | int activeIndex; | ||||
182 | if (m_backend->deviceCount() == 1) { | ||||
183 | // if no pointer device was connected previously, show the new device and hide the no-device-message | ||||
184 | activeIndex = 0; | ||||
185 | hideErrorMessage(); | ||||
186 | } else { | ||||
187 | activeIndex = QQmlProperty::read(rootObj, "deviceIndex").toInt(); | ||||
188 | } | ||||
189 | m_view->rootContext()->setContextProperty("deviceModel", getDeviceList(m_backend)); | ||||
190 | QMetaObject::invokeMethod(rootObj, "resetModel", Q_ARG(QVariant, activeIndex)); | ||||
191 | QMetaObject::invokeMethod(rootObj, "syncValuesFromBackend"); | ||||
192 | } | ||||
193 | | ||||
194 | void LibinputConfig::onDeviceRemoved(int index) | ||||
195 | { | ||||
196 | QQuickItem *rootObj = m_view->rootObject(); | ||||
197 | | ||||
198 | int activeIndex = QQmlProperty::read(rootObj, "deviceIndex").toInt(); | ||||
199 | if (activeIndex == index) { | ||||
200 | m_errorMessage->setMessageType(KMessageWidget::Information); | ||||
201 | if (m_backend->deviceCount()) { | ||||
202 | m_errorMessage->setText(i18n("Pointer device disconnected. Closed its setting dialog.")); | ||||
203 | } else { | ||||
204 | m_errorMessage->setText(i18n("Pointer device disconnected. No other devices found.")); | ||||
205 | } | ||||
206 | m_errorMessage->animatedShow(); | ||||
207 | activeIndex = 0; | ||||
208 | } else { | ||||
209 | if (index < activeIndex) { | ||||
210 | activeIndex--; | ||||
211 | } | ||||
212 | } | ||||
213 | m_view->rootContext()->setContextProperty("deviceModel", getDeviceList(m_backend)); | ||||
214 | QMetaObject::invokeMethod(m_view->rootObject(), "resetModel", Q_ARG(QVariant, activeIndex)); | ||||
215 | QMetaObject::invokeMethod(rootObj, "syncValuesFromBackend"); | ||||
216 | | ||||
217 | emit m_parent->changed(m_backend->isChangedConfig()); | ||||
218 | } | ||||
219 | | ||||
220 | void LibinputConfig::hideErrorMessage() | ||||
221 | { | ||||
222 | if (m_errorMessage->isVisible()) { | ||||
223 | m_errorMessage->animatedHide(); | ||||
224 | } | ||||
225 | } |