MythTV master
keybindings.cpp
Go to the documentation of this file.
1/* -*- myth -*- */
28// MythTV headers
29#include "libmythbase/mythdb.h"
31
32// MythControls headers
33#include "keybindings.h"
34
40 : m_hostname(std::move(hostname)),
41 m_filter(Filters)
42{
46}
47
49QStringList KeyBindings::GetKeys(void) const
50{
51 return m_actionSet.GetAllKeys();
52}
53
58QStringList KeyBindings::GetContexts(void) const
59{
60 QStringList ctxts = m_actionSet.GetContextStrings();
61 ctxts.sort();
62 return ctxts;
63}
64
72QStringList KeyBindings::GetActions(const QString &context) const
73{
74 return m_actionSet.GetActionStrings(context);
75}
76
84void KeyBindings::GetKeyActions(const QString &key, ActionList &list) const
85{
86 list = m_actionSet.GetActions(key);
87}
88
95QStringList KeyBindings::GetActionKeys(const QString &context_name,
96 const QString &action_name) const
97{
98 return m_actionSet.GetKeys(ActionID(context_name, action_name));
99}
100
106QStringList KeyBindings::GetContextKeys(const QString &context) const
107{
108 return m_actionSet.GetContextKeys(context);
109}
110
115QStringList KeyBindings::GetKeyContexts(const QString &key) const
116{
117 ActionList actions = m_actionSet.GetActions(key);
118 QStringList contexts;
119
120 contexts.reserve(actions.size());
121 for (const auto & action : std::as_const(actions))
122 {
123 QString context = action.GetContext();
124 if (!contexts.contains(context))
125 contexts.push_back(context);
126 }
127
128 return contexts;
129}
130
137QString KeyBindings::GetActionDescription(const QString &context_name,
138 const QString &action_name) const
139{
140 ActionID id(context_name, action_name);
141 return m_actionSet.GetDescription(id);
142}
143
153bool KeyBindings::AddActionKey(const QString &context_name,
154 const QString &action_name,
155 const QString &key)
156{
157 return m_actionSet.Add(ActionID(context_name, action_name), key);
158}
159
181 const QString &context_name, const QString &key, int &level) const
182{
183 const ActionList ids = m_actionSet.GetActions(key);
184
185 // trying to bind a jumppoint to an already bound key
186 if ((context_name == ActionSet::kJumpContext) && (ids.count() > 0))
187 return new ActionID(ids[0]);
188
189 // check the contexts of the other bindings
190 for (int i = 0; i < ids.count(); i++)
191 {
192 // jump points, then global, then the same context
193 if (ids[i].GetContext() == ActionSet::kJumpContext)
194 {
196 return new ActionID(ids[i]);
197 }
198 if (ids[i].GetContext() == context_name)
199 {
201 return new ActionID(ids[i]);
202 }
203 if (ids[i].GetContext() == ActionSet::kGlobalContext)
204 {
206 return new ActionID(ids[i]);
207 }
208 }
209
210 return nullptr; // no conflicts
211}
212
223void KeyBindings::ReplaceActionKey(const QString &context_name,
224 const QString &action_name,
225 const QString &newkey,
226 const QString &oldkey)
227{
228 m_actionSet.Replace(ActionID(context_name, action_name), newkey, oldkey);
229}
230
243bool KeyBindings::RemoveActionKey(const QString &context_name,
244 const QString &action_name,
245 const QString &key)
246{
247 ActionID id(context_name, action_name);
248
249 // Don't remove the last mandatory binding
250 if (m_mandatoryBindings.contains(id) &&
251 (m_actionSet.GetKeys(id).count() < 2))
252 {
253 return false;
254 }
255
256 return m_actionSet.Remove(id, key);
257}
258
259
264{
266 query.prepare(
267 "UPDATE keybindings "
268 "SET keylist = :KEYLIST "
269 "WHERE hostname = :HOSTNAME AND "
270 " action = :ACTION AND "
271 " context = :CONTEXT");
272
273 QString keys = m_actionSet.GetKeyString(id);
274 query.bindValue(":KEYLIST", keys);
275 query.bindValue(":HOSTNAME", m_hostname);
276 query.bindValue(":CONTEXT", id.GetContext());
277 query.bindValue(":ACTION", id.GetAction());
278
279 if (!query.exec() || !query.isActive())
280 {
281 MythDB::DBError("KeyBindings::CommitAction", query);
282 return;
283 }
284
285 GetMythMainWindow()->ClearKey(id.GetContext(), id.GetAction());
286 GetMythMainWindow()->BindKey(id.GetContext(), id.GetAction(), keys);
287}
288
295{
297 query.prepare(
298 "UPDATE jumppoints "
299 "SET keylist = :KEYLIST "
300 "WHERE hostname = :HOSTNAME AND"
301 " destination = :DESTINATION");
302
303 QString keys = m_actionSet.GetKeyString(id);
304 query.bindValue(":KEYLIST", keys);
305 query.bindValue(":HOSTNAME", m_hostname);
306 query.bindValue(":DESTINATION", id.GetAction());
307
308 if (!query.exec() || !query.isActive())
309 {
310 MythDB::DBError("KeyBindings::CommitJumppoint", query);
311 return;
312 }
313
314 GetMythMainWindow()->ClearJump(id.GetAction());
315 GetMythMainWindow()->BindJump(id.GetAction(), keys);
316}
317
326{
328
329 while (!modified.empty())
330 {
331 ActionID id = modified.front();
332
333 // commit either a jumppoint or an action
334 if (id.GetContext() == ActionSet::kJumpContext)
335 CommitJumppoint(id);
336 else
337 CommitAction(id);
338
339 // tell the action set that the action is no longer modified
340 m_actionSet.SetModifiedFlag(id, false);
341
342 modified.pop_front();
343 }
344}
345
352{
353 if (m_filter == JustModifiers)
354 return;
355
357 query.prepare(
358 "SELECT destination, description, keylist "
359 "FROM jumppoints "
360 "WHERE hostname = :HOSTNAME "
361 "ORDER BY destination");
362 query.bindValue(":HOSTNAME", m_hostname);
363
364 if (!query.exec() || !query.isActive())
365 {
366 MythDB::DBError("KeyBindings::LoadJumppoint", query);
367 return;
368 }
369
370 while (query.next())
371 {
372 ActionID id(ActionSet::kJumpContext, query.value(0).toString());
373
374 if (query.value(1).toString().isEmpty())
375 {
376 m_actionSet.AddAction(id, query.value(0).toString(),
377 query.value(2).toString());
378 }
379 else
380 {
381 m_actionSet.AddAction(id, query.value(1).toString(),
382 query.value(2).toString());
383 }
384 }
385}
386
394{
396 query.prepare(
397 "SELECT context, action, description, keylist "
398 "FROM keybindings "
399 "WHERE hostname = :HOSTNAME "
400 "ORDER BY context, action");
401 query.bindValue(":HOSTNAME", m_hostname);
402
403 if (!query.exec() || !query.isActive())
404 {
405 MythDB::DBError("KeyBindings::LoadContexts", query);
406 return;
407 }
408
409 static QStringList kModifierContexts = { "Long Press" };
410 while (query.next())
411 {
412 QString context = query.value(0).toString();
413 bool modifier = kModifierContexts.contains(context);
414 bool allow = m_filter == AllBindings;
415 if (m_filter == JustModifiers)
416 allow = modifier;
417 else if (m_filter == NoModifiers)
418 allow = !modifier;
419 if (allow)
420 {
421 ActionID id(context, query.value(1).toString());
422 m_actionSet.AddAction(id, query.value(2).toString(),
423 query.value(3).toString());
424 }
425 }
426}
427
432{
433 if (!m_mandatoryBindings.empty())
434 return;
435
437 m_defaultKeys.append("Down");
438
440 m_defaultKeys.append("Up");
441
443 m_defaultKeys.append("Left");
444
446 m_defaultKeys.append("Right");
447
449 m_defaultKeys.append("Esc");
450
452 m_defaultKeys.append("Return, Enter, Space");
453}
454
459{
460 const ActionList &manlist = m_mandatoryBindings;
461 for (int i = 0; i < manlist.count(); i++)
462 {
463 if (m_actionSet.GetKeys(manlist[i]).isEmpty())
464 return false;
465 }
466
467 return true; // none are empty...
468}
QList< ActionID > ActionList
Definition: action.h:115
A class that uniquely identifies an action.
Definition: action.h:85
static const QString kJumpContext
The statically assigned context for jump point actions.
Definition: actionset.h:80
bool Remove(const ActionID &id, const QString &key)
Remove a key from an action identifier.
Definition: actionset.cpp:91
bool Replace(const ActionID &id, const QString &newkey, const QString &oldkey)
Replace a specific key in a specific action.
Definition: actionset.cpp:122
QStringList GetContextStrings(void) const
Returns a list of all contexts in the action set.
Definition: actionset.cpp:162
QString GetKeyString(const ActionID &id) const
Returns a string containing all the keys in bound to an action by its identifier.
Definition: actionset.cpp:224
bool Add(const ActionID &id, const QString &key)
Add a binding.
Definition: actionset.cpp:59
QStringList GetKeys(const ActionID &id) const
Get the keys bound to an action by its identifier.
Definition: actionset.cpp:240
bool AddAction(const ActionID &id, const QString &description, const QString &keys)
Add an action.
Definition: actionset.cpp:200
ActionList GetModified(void) const
Returns the appropriate container of modified actions.
Definition: actionset.h:68
QStringList GetActionStrings(const QString &context_name) const
Returns a list of all action in the action set.
Definition: actionset.cpp:175
QStringList GetAllKeys(void) const
Get all keys (from every context) to which an action is bound.
Definition: actionset.cpp:269
QStringList GetContextKeys(const QString &context_name) const
Definition: actionset.cpp:254
static const QString kGlobalContext
The name of global actions.
Definition: actionset.h:82
bool SetModifiedFlag(const ActionID &id, bool modified)
Mark an action as modified or unmodified by its identifier.
Definition: actionset.cpp:145
QString GetDescription(const ActionID &id) const
Returns the description of an action by its identifier.
Definition: actionset.cpp:284
ActionList GetActions(const QString &key) const
Returns the actions bound to the specified key.
Definition: actionset.h:65
QStringList GetKeys(void) const
Returns a list of all keys bound to an action.
Definition: keybindings.cpp:49
ActionList m_mandatoryBindings
Definition: keybindings.h:90
bool AddActionKey(const QString &context_name, const QString &action_name, const QString &key)
Add a key to an action.
QString GetActionDescription(const QString &context_name, const QString &action_name) const
Get an action's description.
KeyBindings(QString hostname, Filter Filters=AllBindings)
Create a new KeyBindings instance.
Definition: keybindings.cpp:39
QStringList m_defaultKeys
Definition: keybindings.h:91
void LoadJumppoints(void)
Load the jumppoints from the database.
QStringList GetActionKeys(const QString &context_name, const QString &action_name) const
Get an action's keys.
Definition: keybindings.cpp:95
void LoadMandatoryBindings(void)
Load the mandatory bindings.
QStringList GetContexts(void) const
Returns a list of the context names.
Definition: keybindings.cpp:58
@ kKeyBindingError
Definition: keybindings.h:47
@ kKeyBindingWarning
Definition: keybindings.h:47
QStringList GetKeyContexts(const QString &key) const
Get the context names in which a key is bound.
bool RemoveActionKey(const QString &context_name, const QString &action_name, const QString &key)
Unbind a key from an action.
bool HasMandatoryBindings(void) const
Returns true iff all mandatory bindings are satisfied.
QStringList GetActions(const QString &context) const
Get a list of the actions in a context.
Definition: keybindings.cpp:72
QStringList GetContextKeys(const QString &context) const
Get the keys within a context.
ActionID * GetConflict(const QString &context_name, const QString &key, int &level) const
Determine if adding a key would cause a conflict.
void LoadContexts(void)
Load the keybindings from the database.
ActionSet m_actionSet
Definition: keybindings.h:92
void ReplaceActionKey(const QString &context_name, const QString &action_name, const QString &newkey, const QString &oldkey)
Replace a key in an action.
void CommitAction(const ActionID &id)
Commit an action to the database, and reload its keybindings.
void GetKeyActions(const QString &key, ActionList &list) const
Get a list of the actions in a context.
Definition: keybindings.cpp:84
void CommitJumppoint(const ActionID &id)
Commit a jumppoint to the database.
void CommitChanges(void)
Commit all changes made to the keybindings.
QString m_hostname
Definition: keybindings.h:89
Filter m_filter
Definition: keybindings.h:93
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:129
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:839
QVariant value(int i) const
Definition: mythdbcon.h:205
bool isActive(void) const
Definition: mythdbcon.h:216
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:620
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:890
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:814
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:552
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:225
void BindJump(const QString &Destination, const QString &Key)
void ClearKey(const QString &Context, const QString &Action)
void ClearJump(const QString &Destination)
void BindKey(const QString &Context, const QString &Action, const QString &Key)
static bool modified(uint64_t sig)
Definition: eitcache.cpp:91
Main header for keybinding classes.
MythMainWindow * GetMythMainWindow(void)
string hostname
Definition: caa.py:17