00001
00029
00030 #include <qdeepcopy.h>
00031
00032
00033 #include <mythtv/mythcontext.h>
00034 #include <mythtv/mythdialogs.h>
00035 #include <mythtv/mythdbcon.h>
00036
00037
00038 #include "keybindings.h"
00039
00044 KeyBindings::KeyBindings(const QString &hostname)
00045 : m_hostname(QDeepCopy<QString>(hostname))
00046 {
00047 LoadMandatoryBindings();
00048 LoadContexts();
00049 LoadJumppoints();
00050 }
00051
00053 QStringList KeyBindings::GetKeys(void) const
00054 {
00055 return m_actionSet.GetAllKeys();
00056 }
00057
00062 QStringList KeyBindings::GetContexts(void) const
00063 {
00064 QStringList ctxts =
00065 QDeepCopy<QStringList>(m_actionSet.GetContextStrings());
00066 ctxts.sort();
00067 return ctxts;
00068 }
00069
00077 QStringList KeyBindings::GetActions(const QString &context) const
00078 {
00079 return QDeepCopy<QStringList>(m_actionSet.GetActionStrings(context));
00080 }
00081
00089 void KeyBindings::GetKeyActions(const QString &key, ActionList &list) const
00090 {
00091 list = m_actionSet.GetActions(key);
00092 }
00093
00100 QStringList KeyBindings::GetActionKeys(const QString &context_name,
00101 const QString &action_name) const
00102 {
00103 return QDeepCopy<QStringList>
00104 (m_actionSet.GetKeys(ActionID(context_name, action_name)));
00105 }
00106
00112 QStringList KeyBindings::GetContextKeys(const QString &context) const
00113 {
00114 return m_actionSet.GetContextKeys(context);
00115 }
00116
00121 QStringList KeyBindings::GetKeyContexts(const QString &key) const
00122 {
00123 ActionList actions = m_actionSet.GetActions(key);
00124 QStringList contexts;
00125
00126 for (size_t i = 0; i < actions.size(); i++)
00127 {
00128 QString context = actions[i].GetContext();
00129 if (!contexts.contains(context))
00130 contexts.push_back(context);
00131 }
00132
00133 return contexts;
00134 }
00135
00142 QString KeyBindings::GetActionDescription(const QString &context_name,
00143 const QString &action_name) const
00144 {
00145 ActionID id(context_name, action_name);
00146 return QDeepCopy<QString>(m_actionSet.GetDescription(id));
00147 }
00148
00158 bool KeyBindings::AddActionKey(const QString &context_name,
00159 const QString &action_name,
00160 const QString &key)
00161 {
00162 return m_actionSet.Add(ActionID(context_name, action_name), key);
00163 }
00164
00185 ActionID *KeyBindings::GetConflict(
00186 const QString &context_name, const QString &key, int &level) const
00187 {
00188 const ActionList &ids = m_actionSet.GetActions(key);
00189
00190
00191 if ((context_name == ActionSet::kJumpContext) && (ids.count() > 0))
00192 return new ActionID(ids[0]);
00193
00194
00195 for (uint i = 0; i < ids.count(); i++)
00196 {
00197
00198 if (ids[i].GetContext() == ActionSet::kJumpContext)
00199 {
00200 level = KeyBindings::kKeyBindingError;
00201 return new ActionID(ids[i]);
00202 }
00203 else if (ids[i].GetContext() == context_name)
00204 {
00205 level = KeyBindings::kKeyBindingError;
00206 return new ActionID(ids[i]);
00207 }
00208 else if (ids[i].GetContext() == ActionSet::kGlobalContext)
00209 {
00210 level = KeyBindings::kKeyBindingWarning;
00211 return new ActionID(ids[i]);
00212 }
00213 }
00214
00215 return NULL;
00216 }
00217
00229 void KeyBindings::ReplaceActionKey(const QString &context_name,
00230 const QString &action_name,
00231 const QString &newkey,
00232 const QString &oldkey)
00233 {
00234 m_actionSet.Replace(ActionID(context_name, action_name), newkey, oldkey);
00235 }
00236
00249 bool KeyBindings::RemoveActionKey(const QString &context_name,
00250 const QString &action_name,
00251 const QString &key)
00252 {
00253 ActionID id(context_name, action_name);
00254
00255
00256 if (m_mandatoryBindings.contains(id) &&
00257 (m_actionSet.GetKeys(id).count() < 2))
00258 {
00259 return false;
00260 }
00261
00262 return m_actionSet.Remove(id, key);
00263 }
00264
00265
00269 void KeyBindings::CommitAction(const ActionID &id)
00270 {
00271 MSqlQuery query(MSqlQuery::InitCon());
00272 query.prepare(
00273 "UPDATE keybindings "
00274 "SET keylist = :KEYLIST "
00275 "WHERE hostname = :HOSTNAME AND "
00276 " action = :ACTION AND "
00277 " context = :CONTEXT");
00278
00279 QString keys = m_actionSet.GetKeyString(id);
00280 query.bindValue(":KEYLIST", keys);
00281 query.bindValue(":HOSTNAME", m_hostname);
00282 query.bindValue(":CONTEXT", id.GetContext());
00283 query.bindValue(":ACTION", id.GetAction());
00284
00285 if (!query.exec() || !query.isActive())
00286 {
00287 MythContext::DBError("KeyBindings::CommitAction", query);
00288 return;
00289 }
00290
00291 gContext->GetMainWindow()->ClearKey(id.GetContext(), id.GetAction());
00292 gContext->GetMainWindow()->BindKey(id.GetContext(), id.GetAction(), keys);
00293 }
00294
00300 void KeyBindings::CommitJumppoint(const ActionID &id)
00301 {
00302 MSqlQuery query(MSqlQuery::InitCon());
00303 query.prepare(
00304 "UPDATE jumppoints "
00305 "SET keylist = :KEYLIST "
00306 "WHERE hostname = :HOSTNAME AND"
00307 " destination = :DESTINATION");
00308
00309 QString keys = m_actionSet.GetKeyString(id);
00310 query.bindValue(":KEYLIST", keys);
00311 query.bindValue(":HOSTNAME", m_hostname);
00312 query.bindValue(":DESTINATION", id.GetAction());
00313
00314 if (!query.exec() || !query.isActive())
00315 {
00316 MythContext::DBError("KeyBindings::CommitJumppoint", query);
00317 return;
00318 }
00319
00320 gContext->GetMainWindow()->ClearJump(id.GetAction());
00321 gContext->GetMainWindow()->BindJump(id.GetAction(), keys);
00322 }
00323
00331 void KeyBindings::CommitChanges(void)
00332 {
00333 ActionList modified = m_actionSet.GetModified();
00334
00335 while (modified.size() > 0)
00336 {
00337 ActionID id = modified.front();
00338
00339
00340 if (id.GetContext() == ActionSet::kJumpContext)
00341 CommitJumppoint(id);
00342 else
00343 CommitAction(id);
00344
00345
00346 m_actionSet.SetModifiedFlag(id, false);
00347
00348 modified.pop_front();
00349 }
00350 }
00351
00357 void KeyBindings::LoadJumppoints(void)
00358 {
00359 MSqlQuery query(MSqlQuery::InitCon());
00360 query.prepare(
00361 "SELECT destination, description, keylist "
00362 "FROM jumppoints "
00363 "WHERE hostname = :HOSTNAME "
00364 "ORDER BY destination");
00365 query.bindValue(":HOSTNAME", m_hostname);
00366
00367 if (!query.exec() || !query.isActive())
00368 {
00369 MythContext::DBError("KeyBindings::LoadJumppoint", query);
00370 return;
00371 }
00372
00373 while (query.next())
00374 {
00375 ActionID id(ActionSet::kJumpContext, query.value(0).toString());
00376
00377 if (query.value(1).toString().isEmpty())
00378 {
00379 m_actionSet.AddAction(id, query.value(0).toString(),
00380 query.value(2).toString());
00381 }
00382 else
00383 {
00384 m_actionSet.AddAction(id, query.value(1).toString(),
00385 query.value(2).toString());
00386 }
00387 }
00388 }
00389
00396 void KeyBindings::LoadContexts(void)
00397 {
00398 MSqlQuery query(MSqlQuery::InitCon());
00399 query.prepare(
00400 "SELECT context, action, description, keylist "
00401 "FROM keybindings "
00402 "WHERE hostname = :HOSTNAME "
00403 "ORDER BY context, action");
00404 query.bindValue(":HOSTNAME", m_hostname);
00405
00406 if (!query.exec() || !query.isActive())
00407 {
00408 MythContext::DBError("KeyBindings::LoadContexts", query);
00409 return;
00410 }
00411
00412 while (query.next())
00413 {
00414 ActionID id(query.value(0).toString(), query.value(1).toString());
00415 m_actionSet.AddAction(id, query.value(2).toString(),
00416 query.value(3).toString());
00417 }
00418 }
00419
00423 void KeyBindings::LoadMandatoryBindings(void)
00424 {
00425 if (!m_mandatoryBindings.empty())
00426 return;
00427
00428 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "DOWN"));
00429 m_defaultKeys.append("Down");
00430
00431 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "UP"));
00432 m_defaultKeys.append("Up");
00433
00434 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "LEFT"));
00435 m_defaultKeys.append("Left");
00436
00437 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "RIGHT"));
00438 m_defaultKeys.append("Right");
00439
00440 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "ESCAPE"));
00441 m_defaultKeys.append("Esc");
00442
00443 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "SELECT"));
00444 m_defaultKeys.append("Return, Enter, Space");
00445 }
00446
00450 bool KeyBindings::HasMandatoryBindings(void) const
00451 {
00452 const ActionList &manlist = m_mandatoryBindings;
00453 for (uint i = 0; i < manlist.count(); i++)
00454 {
00455 if (m_actionSet.GetKeys(manlist[i]).isEmpty())
00456 return false;
00457 }
00458
00459 return true;
00460 }