ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
kbbind.cpp
Go to the documentation of this file.
1 #include <QDateTime>
2 #include <QUrl>
3 #include "ckbsettings.h"
4 #include "kbbind.h"
5 #include "kbmode.h"
6 #include "kb.h"
7 #include "qdebug.h"
8 
9 QHash<QString, QString> KbBind::_globalRemap;
10 quint64 KbBind::globalRemapTime = 0;
11 
12 KbBind::KbBind(KbMode* modeParent, Kb* parentBoard, const KeyMap& keyMap) :
13  QObject(modeParent), _devParent(parentBoard), lastGlobalRemapTime(globalRemapTime), _map(keyMap),
14  _winLock(false), _needsUpdate(true), _needsSave(true) {
15 }
16 
24 KbBind::KbBind(KbMode* modeParent, Kb* parentBoard, const KeyMap& keyMap, const KbBind& other) :
25  QObject(modeParent), _devParent(parentBoard), lastGlobalRemapTime(globalRemapTime), _bind(other._bind),
26  _winLock(false), _needsUpdate(true), _needsSave(true) {
27  map(keyMap);
28 
30  QHash<QString, KeyAction*> newBind;
31  foreach(QString key, _bind.keys()) {
32  KeyAction* act = _bind.value(key);
33  if(act) {
34  newBind[key] = new KeyAction(act->value(), this);
35  }
36  }
37 
39  _bind.clear();
40  foreach(QString key, newBind.keys()) {
41  KeyAction* act = newBind.value(key);
42  if(act) {
44  _bind[key] = new KeyAction(act->value(), this);
45  }
46  }
47  newBind.clear(); // here we *must not* delete the KeyActions, because they are referenced by _bind now
48 }
49 
51  return modeParent()->perf();
52 }
53 
55  return modeParent()->light();
56 }
57 
58 void KbBind::load(CkbSettings& settings){
59  _needsSave = false;
60  SGroup group(settings, "Binding");
61  KeyMap currentMap = _map;
62  _map = KeyMap::fromName(settings.value("KeyMap").toString());
63  // Load key settings
64  bool useReal = settings.value("UseRealNames").toBool();
65  _bind.clear();
66  {
67  SGroup group(settings, "Keys");
68  foreach(QString key, settings.childKeys()){
69  QString name = key.toLower();
70  if(!useReal)
71  name = _map.fromStorage(name);
72  QString bind = settings.value(key).toString();
73  _bind[name] = new KeyAction(bind, this);
74  }
75  }
76  _winLock = settings.value("WinLock").toBool();
77  emit didLoad();
78  map(currentMap);
79 }
80 
81 void KbBind::save(CkbSettings& settings){
82  _needsSave = false;
83  SGroup group(settings, "Binding");
84  settings.setValue("KeyMap", _map.name());
85  // Save key settings
86  settings.setValue("UseRealNames", true);
87  {
88  SGroup group(settings, "Keys");
89  foreach(QString key, _bind.keys()){
90  KeyAction* act = _bind.value(key);
91  if(act && act->value() != KeyAction::defaultAction(key, devParent()->model()))
92  settings.setValue(key, act->value());
93  }
94  }
95  settings.setValue("WinLock", _winLock);
96 }
97 
98 QString KbBind::globalRemap(const QString& key){
99  if(!_globalRemap.contains(key))
100  return key;
101  return _globalRemap.value(key);
102 }
103 
104 void KbBind::setGlobalRemap(const QHash<QString, QString> keyToActual){
105  _globalRemap.clear();
106  // Ignore any keys with the standard binding
107  QHashIterator<QString, QString> i(keyToActual);
108  while(i.hasNext()){
109  i.next();
110  if(i.key() != i.value())
111  _globalRemap[i.key()] = i.value();
112  }
113  globalRemapTime = QDateTime::currentMSecsSinceEpoch();
114 }
115 
117  _globalRemap.clear();
118  CkbSettings settings("Program/GlobalRemap");
119  foreach(const QString& key, settings.childKeys())
120  _globalRemap[key] = settings.value(key).toString();
121  globalRemapTime = QDateTime::currentMSecsSinceEpoch();
122 }
123 
125  CkbSettings settings("Program/GlobalRemap", true);
126  QHashIterator<QString, QString> i(_globalRemap);
127  while(i.hasNext()){
128  i.next();
129  settings.setValue(i.key(), i.value());
130  }
131 }
132 
133 void KbBind::map(const KeyMap& map){
134  _map = map;
135  _needsUpdate = true;
136  _needsSave = true;
137  emit layoutChanged();
138 }
139 
140 KeyAction* KbBind::bindAction(const QString& key) {
141  if(!_bind.contains(key)) return _bind[key] = new KeyAction(KeyAction::defaultAction(key, devParent()->model()), this);
142  return _bind[key];
143 }
144 
145 QString KbBind::action(const QString& key){
146  QString rKey = globalRemap(key);
147  return bindAction(rKey)->value();
148 }
149 
150 QString KbBind::defaultAction(const QString& key, KeyMap::Model model){
151  QString rKey = globalRemap(key);
152  return KeyAction::defaultAction(rKey, model);
153 }
154 
155 QString KbBind::defaultAction(const QString& key){
156  return defaultAction(key, devParent()->model());
157 }
158 
159 QString KbBind::friendlyName(const QString& key){
160  const Key& pos = _map[globalRemap(key)];
161  if(!pos)
162  return "(Unknown)";
163  return pos.friendlyName();
164 }
165 
166 QString KbBind::friendlyActionName(const QString& key){
167  QString act = action(key);
168  return KeyAction(act).friendlyName(_map);
169 }
170 
171 void KbBind::resetAction(const QString &key){
172  QString rKey = globalRemap(key);
173  // Clean up existing action (if any)
174  KeyAction* action = _bind.value(rKey);
175  delete action;
176  _bind.remove(rKey);
177  _needsUpdate = true;
178  _needsSave = true;
179 }
180 
181 void KbBind::noAction(const QString& key){
182  resetAction(key);
183  QString rKey = globalRemap(key);
184  if(!_map.key(rKey))
185  return;
186  _bind[rKey] = new KeyAction(this);
187 }
188 
189 void KbBind::setAction(const QString& key, const QString& action){
190  resetAction(key);
191  QString rKey = globalRemap(key);
192  if(!_map.key(rKey))
193  return;
194  _bind[rKey] = new KeyAction(action, this);
195 }
196 
197 void KbBind::update(QFile& cmd, bool force){
199  return;
201  emit updated();
202  _needsUpdate = false;
203  // Reset all keys and enable notifications for all
204  cmd.write("rebind all notify all");
205  // Make sure modifier keys are included as they may be remapped globally
206  QHash<QString, KeyAction*> bind(_bind);
207  if(!_bind.contains("caps")) bind["caps"] = 0;
208  if(!_bind.contains("lshift")) bind["lshift"] = 0;
209  if(!_bind.contains("rshift")) bind["rshift"] = 0;
210  if(!_bind.contains("lctrl")) bind["lctrl"] = 0;
211  if(!_bind.contains("rctrl")) bind["rctrl"] = 0;
212  if(!_bind.contains("lwin")) bind["lwin"] = 0;
213  if(!_bind.contains("rwin")) bind["rwin"] = 0;
214  if(!_bind.contains("lalt")) bind["lalt"] = 0;
215  if(!_bind.contains("ralt")) bind["ralt"] = 0;
216  if(!_bind.contains("fn")) bind["fn"] = 0;
217  QHashIterator<QString, KeyAction*> i(bind);
218 
219  // Initialize String buffer for macro Key definitions (G-keys)
220  // "macro clear" is neccessary, if an older definition is unbound.
221  QString macros = "\nmacro clear\n";
222 
223  // Write out rebound keys and collect infos for macro definitions
224  while(i.hasNext()){
225  i.next();
226  QString key = i.key();
227  KeyAction* act = i.value();
228  if(_globalRemap.contains(key))
229  act = bindAction(_globalRemap.value(key));
230  if(!act)
231  continue;
232  QString value = act->driverName();
233  if(value.isEmpty()){
234  // If the key is unbound or is a special action, unbind it
235  cmd.write(" unbind ");
236  cmd.write(key.toLatin1());
237  // if a macro definiton for the key is given,
238  // add the converted string to key-buffer "macro"
239  if (act->isValidMacro()) {
240  if (act->macroContent().length() > 0) {
241  macros.append("macro " + key.toLatin1() + ":" + act->macroContent().toLatin1() + "\n");
242  }
243  }
244  } else {
245  // Otherwise, write the binding
246  cmd.write(" bind ");
247  cmd.write(key.toLatin1());
248  cmd.write(":");
249  cmd.write(value.toLatin1());
250  }
251  }
252  // If win lock is enabled, unbind windows keys
253  if(_winLock)
254  cmd.write(" unbind lwin rwin");
255 
256  // At last, send Macro definitions if available.
257  // If no definitions are made, clear macro will be sent only to reset all macros,
258  cmd.write(macros.toLatin1());
259  lastCmd = &cmd;
260 }
261 
267  return devParent()->getMacroNumber();
268 }
269 
275  return devParent()->getMacroPath();
276 }
277 
285  if (getMacroNumber() > 0 && lastCmd) {
286  if (start) {
287  lastCmd->write (QString("\nnotifyon %1\n@%1 notify all:on\n").arg(getMacroNumber()).toLatin1());
288  } else {
289  lastCmd->write (QString("\n@%1 notify all:off\nnotifyoff %1\n").arg(getMacroNumber()).toLatin1());
290  }
291  lastCmd->flush();
292  } else qDebug() << QString("No cmd or valid handle for notification found, macroNumber = %1, lastCmd = %2")
293  .arg(getMacroNumber()).arg(lastCmd? "set" : "unset");
294 }
295 
296 void KbBind::keyEvent(const QString& key, bool down){
297  QString rKey = globalRemap(key);
298  KeyAction* act = bindAction(rKey);
299  if(act)
300  act->keyEvent(this, down);
301 }
void load(CkbSettings &settings)
Definition: kbbind.cpp:58
void setValue(const QString &key, const QVariant &value)
QStringList childKeys() const
QString getMacroPath()
getMacroPath returns the macroPath (e.g. /dev/input/ckb1/notify), which we have saved in the construc...
Definition: kb.h:106
KbBind(KbMode *modeParent, Kb *devParent, const KeyMap &keyMap)
Definition: kbbind.cpp:12
bool _winLock
Definition: kbbind.h:134
static QString globalRemap(const QString &key)
Definition: kbbind.cpp:98
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
cmd
Definition: command.h:7
KbPerf * perf()
Definition: kbbind.cpp:50
Kb * devParent() const
Definition: kbbind.h:115
int getMacroNumber()
For usage with macro definions, these two params must only be readable. So there are no setters...
Definition: kb.h:97
QString friendlyName(bool os=true) const
Definition: keymap.h:23
QString value() const
Definition: keyaction.h:19
static void setGlobalRemap(const QHash< QString, QString > keyToActual)
Definition: kbbind.cpp:104
const KeyMap & map()
Definition: kbbind.h:41
bool isValidMacro() const
isValidMacro checks whether a keyAction contains a valid macro. This is done easily: If the macro act...
Definition: keyaction.h:55
KbLight * light()
Definition: kbmode.h:60
void didLoad()
Definition: moc_kbbind.cpp:155
KeyMap _map
Definition: kbbind.h:130
bool _needsSave
Definition: kbbind.h:136
Key key(const QString &name) const
Definition: keymap.h:141
friend class KeyAction
Definition: kbbind.h:137
QString fromStorage(const QString &storage)
Definition: keymap.h:151
Definition: keymap.h:49
QString friendlyActionName(const QString &key)
Definition: kbbind.cpp:166
QString friendlyName(const QString &key)
Definition: kbbind.cpp:159
void resetAction(const QString &key)
Definition: kbbind.cpp:171
KbLight * light()
Definition: kbbind.cpp:54
Definition: kbmode.h:36
QString action(const QString &key)
Definition: kbbind.cpp:145
void save(CkbSettings &settings)
Definition: kbbind.cpp:81
Definition: kbperf.h:15
Definition: kb.h:11
QString defaultAction(const QString &key)
Definition: kbbind.cpp:155
Definition: kbbind.h:20
void update(QFile &cmd, bool force=false)
Definition: kbbind.cpp:197
void keyEvent(const QString &key, bool down)
Definition: kbbind.cpp:296
Model
Definition: keymap.h:51
QString getMacroPath()
KbBind::getMacroPath.
Definition: kbbind.cpp:274
void handleNotificationChannel(bool start)
handleNotificationChannel sends commands to ckb-daemon for (de-) activating the notify channel...
Definition: kbbind.cpp:284
QString driverName() const
Definition: keyaction.cpp:239
static QHash< QString, QString > _globalRemap
Definition: kbbind.h:120
void noAction(const QString &key)
Definition: kbbind.cpp:181
Definition: keymap.h:8
Definition: keymap.h:49
static void saveGlobalRemap()
Definition: kbbind.cpp:124
QHash< QString, KeyAction * > _bind
Definition: kbbind.h:132
QString name() const
Definition: keymap.h:131
quint64 lastGlobalRemapTime
Definition: kbbind.h:122
QFile * lastCmd
lastCmd is a cache-hack. Because the QFile ist opened in Kb, and we need it in the macro processing f...
Definition: kbbind.h:128
void setAction(const QString &key, const QString &action)
Definition: kbbind.cpp:189
static quint64 globalRemapTime
Definition: kbbind.h:121
static KeyMap fromName(const QString &name)
Definition: keymap.cpp:835
int getMacroNumber()
KbBind::getMacroNumber.
Definition: kbbind.cpp:266
QString macroContent() const
macroContent returns the macro key definition only (the second part of the macro action).
Definition: keyaction.h:86
void updated()
Definition: moc_kbbind.cpp:167
bool _needsUpdate
Definition: kbbind.h:135
static QString defaultAction(const QString &key, KeyMap::Model model)
Definition: keyaction.cpp:44
void layoutChanged()
Definition: moc_kbbind.cpp:161
KbMode * modeParent() const
Definition: kbbind.h:116
KbPerf * perf()
Definition: kbmode.h:62
KeyAction * bindAction(const QString &key)
Definition: kbbind.cpp:140
void keyEvent(KbBind *bind, bool down)
Definition: keyaction.cpp:245
static void loadGlobalRemap()
Definition: kbbind.cpp:116