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 for (const auto & action : std::as_const(actions))
121 {
122 QString context = action.GetContext();
123 if (!contexts.contains(context))
124 contexts.push_back(context);
125 }
126
127 return contexts;
128}
129
136QString KeyBindings::GetActionDescription(const QString &context_name,
137 const QString &action_name) const
138{
139 ActionID id(context_name, action_name);
140 return m_actionSet.GetDescription(id);
141}
142
152bool KeyBindings::AddActionKey(const QString &context_name,
153 const QString &action_name,
154 const QString &key)
155{
156 return m_actionSet.Add(ActionID(context_name, action_name), key);
157}
158
180 const QString &context_name, const QString &key, int &level) const
181{
182 const ActionList ids = m_actionSet.GetActions(key);
183
184 // trying to bind a jumppoint to an already bound key
185 if ((context_name == ActionSet::kJumpContext) && (ids.count() > 0))
186 return new ActionID(ids[0]);
187
188 // check the contexts of the other bindings
189 for (int i = 0; i < ids.count(); i++)
190 {
191 // jump points, then global, then the same context
192 if (ids[i].GetContext() == ActionSet::kJumpContext)
193 {
195 return new ActionID(ids[i]);
196 }
197 if (ids[i].GetContext() == context_name)
198 {
200 return new ActionID(ids[i]);
201 }
202 if (ids[i].GetContext() == ActionSet::kGlobalContext)
203 {
205 return new ActionID(ids[i]);
206 }
207 }
208
209 return nullptr; // no conflicts
210}
211
222void KeyBindings::ReplaceActionKey(const QString &context_name,
223 const QString &action_name,
224 const QString &newkey,
225 const QString &oldkey)
226{
227 m_actionSet.Replace(ActionID(context_name, action_name), newkey, oldkey);
228}
229
242bool KeyBindings::RemoveActionKey(const QString &context_name,
243 const QString &action_name,
244 const QString &key)
245{
246 ActionID id(context_name, action_name);
247
248 // Don't remove the last mandatory binding
249 if (m_mandatoryBindings.contains(id) &&
250 (m_actionSet.GetKeys(id).count() < 2))
251 {
252 return false;
253 }
254
255 return m_actionSet.Remove(id, key);
256}
257
258
263{
265 query.prepare(
266 "UPDATE keybindings "
267 "SET keylist = :KEYLIST "
268 "WHERE hostname = :HOSTNAME AND "
269 " action = :ACTION AND "
270 " context = :CONTEXT");
271
272 QString keys = m_actionSet.GetKeyString(id);
273 query.bindValue(":KEYLIST", keys);
274 query.bindValue(":HOSTNAME", m_hostname);
275 query.bindValue(":CONTEXT", id.GetContext());
276 query.bindValue(":ACTION", id.GetAction());
277
278 if (!query.exec() || !query.isActive())
279 {
280 MythDB::DBError("KeyBindings::CommitAction", query);
281 return;
282 }
283
284 GetMythMainWindow()->ClearKey(id.GetContext(), id.GetAction());
285 GetMythMainWindow()->BindKey(id.GetContext(), id.GetAction(), keys);
286}
287
294{
296 query.prepare(
297 "UPDATE jumppoints "
298 "SET keylist = :KEYLIST "
299 "WHERE hostname = :HOSTNAME AND"
300 " destination = :DESTINATION");
301
302 QString keys = m_actionSet.GetKeyString(id);
303 query.bindValue(":KEYLIST", keys);
304 query.bindValue(":HOSTNAME", m_hostname);
305 query.bindValue(":DESTINATION", id.GetAction());
306
307 if (!query.exec() || !query.isActive())
308 {
309 MythDB::DBError("KeyBindings::CommitJumppoint", query);
310 return;
311 }
312
313 GetMythMainWindow()->ClearJump(id.GetAction());
314 GetMythMainWindow()->BindJump(id.GetAction(), keys);
315}
316
325{
327
328 while (!modified.empty())
329 {
330 ActionID id = modified.front();
331
332 // commit either a jumppoint or an action
333 if (id.GetContext() == ActionSet::kJumpContext)
334 CommitJumppoint(id);
335 else
336 CommitAction(id);
337
338 // tell the action set that the action is no longer modified
339 m_actionSet.SetModifiedFlag(id, false);
340
341 modified.pop_front();
342 }
343}
344
351{
352 if (m_filter == JustModifiers)
353 return;
354
356 query.prepare(
357 "SELECT destination, description, keylist "
358 "FROM jumppoints "
359 "WHERE hostname = :HOSTNAME "
360 "ORDER BY destination");
361 query.bindValue(":HOSTNAME", m_hostname);
362
363 if (!query.exec() || !query.isActive())
364 {
365 MythDB::DBError("KeyBindings::LoadJumppoint", query);
366 return;
367 }
368
369 while (query.next())
370 {
371 ActionID id(ActionSet::kJumpContext, query.value(0).toString());
372
373 if (query.value(1).toString().isEmpty())
374 {
375 m_actionSet.AddAction(id, query.value(0).toString(),
376 query.value(2).toString());
377 }
378 else
379 {
380 m_actionSet.AddAction(id, query.value(1).toString(),
381 query.value(2).toString());
382 }
383 }
384}
385
393{
395 query.prepare(
396 "SELECT context, action, description, keylist "
397 "FROM keybindings "
398 "WHERE hostname = :HOSTNAME "
399 "ORDER BY context, action");
400 query.bindValue(":HOSTNAME", m_hostname);
401
402 if (!query.exec() || !query.isActive())
403 {
404 MythDB::DBError("KeyBindings::LoadContexts", query);
405 return;
406 }
407
408 static QStringList kModifierContexts = { "Long Press" };
409 while (query.next())
410 {
411 QString context = query.value(0).toString();
412 bool modifier = kModifierContexts.contains(context);
413 bool allow = m_filter == AllBindings;
414 if (m_filter == JustModifiers)
415 allow = modifier;
416 else if (m_filter == NoModifiers)
417 allow = !modifier;
418 if (allow)
419 {
420 ActionID id(context, query.value(1).toString());
421 m_actionSet.AddAction(id, query.value(2).toString(),
422 query.value(3).toString());
423 }
424 }
425}
426
431{
432 if (!m_mandatoryBindings.empty())
433 return;
434
436 m_defaultKeys.append("Down");
437
439 m_defaultKeys.append("Up");
440
442 m_defaultKeys.append("Left");
443
445 m_defaultKeys.append("Right");
446
448 m_defaultKeys.append("Esc");
449
451 m_defaultKeys.append("Return, Enter, Space");
452}
453
458{
459 const ActionList &manlist = m_mandatoryBindings;
460 for (int i = 0; i < manlist.count(); i++)
461 {
462 if (m_actionSet.GetKeys(manlist[i]).isEmpty())
463 return false;
464 }
465
466 return true; // none are empty...
467}
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:128
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837
QVariant value(int i) const
Definition: mythdbcon.h:204
bool isActive(void) const
Definition: mythdbcon.h:215
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
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:90
Main header for keybinding classes.
MythMainWindow * GetMythMainWindow(void)
string hostname
Definition: caa.py:17
STL namespace.