00001
00029
00030 #include "mythdb.h"
00031 #include "mythmainwindow.h"
00032
00033
00034 #include "keybindings.h"
00035
00040 KeyBindings::KeyBindings(const QString &hostname)
00041 : m_hostname(hostname)
00042 {
00043 m_hostname.detach();
00044 LoadMandatoryBindings();
00045 LoadContexts();
00046 LoadJumppoints();
00047 }
00048
00050 QStringList KeyBindings::GetKeys(void) const
00051 {
00052 return m_actionSet.GetAllKeys();
00053 }
00054
00059 QStringList KeyBindings::GetContexts(void) const
00060 {
00061 QStringList ctxts = m_actionSet.GetContextStrings();
00062 ctxts.sort();
00063 return ctxts;
00064 }
00065
00073 QStringList KeyBindings::GetActions(const QString &context) const
00074 {
00075 return m_actionSet.GetActionStrings(context);
00076 }
00077
00085 void KeyBindings::GetKeyActions(const QString &key, ActionList &list) const
00086 {
00087 list = m_actionSet.GetActions(key);
00088 }
00089
00096 QStringList KeyBindings::GetActionKeys(const QString &context_name,
00097 const QString &action_name) const
00098 {
00099 return m_actionSet.GetKeys(ActionID(context_name, action_name));
00100 }
00101
00107 QStringList KeyBindings::GetContextKeys(const QString &context) const
00108 {
00109 return m_actionSet.GetContextKeys(context);
00110 }
00111
00116 QStringList KeyBindings::GetKeyContexts(const QString &key) const
00117 {
00118 ActionList actions = m_actionSet.GetActions(key);
00119 QStringList contexts;
00120
00121 for (int i = 0; i < actions.size(); i++)
00122 {
00123 QString context = actions[i].GetContext();
00124 if (!contexts.contains(context))
00125 contexts.push_back(context);
00126 }
00127
00128 return contexts;
00129 }
00130
00137 QString KeyBindings::GetActionDescription(const QString &context_name,
00138 const QString &action_name) const
00139 {
00140 ActionID id(context_name, action_name);
00141 return m_actionSet.GetDescription(id);
00142 }
00143
00153 bool KeyBindings::AddActionKey(const QString &context_name,
00154 const QString &action_name,
00155 const QString &key)
00156 {
00157 return m_actionSet.Add(ActionID(context_name, action_name), key);
00158 }
00159
00180 ActionID *KeyBindings::GetConflict(
00181 const QString &context_name, const QString &key, int &level) const
00182 {
00183 const ActionList ids = m_actionSet.GetActions(key);
00184
00185
00186 if ((context_name == ActionSet::kJumpContext) && (ids.count() > 0))
00187 return new ActionID(ids[0]);
00188
00189
00190 for (int i = 0; i < ids.count(); i++)
00191 {
00192
00193 if (ids[i].GetContext() == ActionSet::kJumpContext)
00194 {
00195 level = KeyBindings::kKeyBindingError;
00196 return new ActionID(ids[i]);
00197 }
00198 else if (ids[i].GetContext() == context_name)
00199 {
00200 level = KeyBindings::kKeyBindingError;
00201 return new ActionID(ids[i]);
00202 }
00203 else if (ids[i].GetContext() == ActionSet::kGlobalContext)
00204 {
00205 level = KeyBindings::kKeyBindingWarning;
00206 return new ActionID(ids[i]);
00207 }
00208 }
00209
00210 return NULL;
00211 }
00212
00223 void KeyBindings::ReplaceActionKey(const QString &context_name,
00224 const QString &action_name,
00225 const QString &newkey,
00226 const QString &oldkey)
00227 {
00228 m_actionSet.Replace(ActionID(context_name, action_name), newkey, oldkey);
00229 }
00230
00243 bool KeyBindings::RemoveActionKey(const QString &context_name,
00244 const QString &action_name,
00245 const QString &key)
00246 {
00247 ActionID id(context_name, action_name);
00248
00249
00250 if (m_mandatoryBindings.contains(id) &&
00251 (m_actionSet.GetKeys(id).count() < 2))
00252 {
00253 return false;
00254 }
00255
00256 return m_actionSet.Remove(id, key);
00257 }
00258
00259
00263 void KeyBindings::CommitAction(const ActionID &id)
00264 {
00265 MSqlQuery query(MSqlQuery::InitCon());
00266 query.prepare(
00267 "UPDATE keybindings "
00268 "SET keylist = :KEYLIST "
00269 "WHERE hostname = :HOSTNAME AND "
00270 " action = :ACTION AND "
00271 " context = :CONTEXT");
00272
00273 QString keys = m_actionSet.GetKeyString(id);
00274 query.bindValue(":KEYLIST", keys);
00275 query.bindValue(":HOSTNAME", m_hostname);
00276 query.bindValue(":CONTEXT", id.GetContext());
00277 query.bindValue(":ACTION", id.GetAction());
00278
00279 if (!query.exec() || !query.isActive())
00280 {
00281 MythDB::DBError("KeyBindings::CommitAction", query);
00282 return;
00283 }
00284
00285 GetMythMainWindow()->ClearKey(id.GetContext(), id.GetAction());
00286 GetMythMainWindow()->BindKey(id.GetContext(), id.GetAction(), keys);
00287 }
00288
00294 void KeyBindings::CommitJumppoint(const ActionID &id)
00295 {
00296 MSqlQuery query(MSqlQuery::InitCon());
00297 query.prepare(
00298 "UPDATE jumppoints "
00299 "SET keylist = :KEYLIST "
00300 "WHERE hostname = :HOSTNAME AND"
00301 " destination = :DESTINATION");
00302
00303 QString keys = m_actionSet.GetKeyString(id);
00304 query.bindValue(":KEYLIST", keys);
00305 query.bindValue(":HOSTNAME", m_hostname);
00306 query.bindValue(":DESTINATION", id.GetAction());
00307
00308 if (!query.exec() || !query.isActive())
00309 {
00310 MythDB::DBError("KeyBindings::CommitJumppoint", query);
00311 return;
00312 }
00313
00314 GetMythMainWindow()->ClearJump(id.GetAction());
00315 GetMythMainWindow()->BindJump(id.GetAction(), keys);
00316 }
00317
00325 void KeyBindings::CommitChanges(void)
00326 {
00327 ActionList modified = m_actionSet.GetModified();
00328
00329 while (modified.size() > 0)
00330 {
00331 ActionID id = modified.front();
00332
00333
00334 if (id.GetContext() == ActionSet::kJumpContext)
00335 CommitJumppoint(id);
00336 else
00337 CommitAction(id);
00338
00339
00340 m_actionSet.SetModifiedFlag(id, false);
00341
00342 modified.pop_front();
00343 }
00344 }
00345
00351 void KeyBindings::LoadJumppoints(void)
00352 {
00353 MSqlQuery query(MSqlQuery::InitCon());
00354 query.prepare(
00355 "SELECT destination, description, keylist "
00356 "FROM jumppoints "
00357 "WHERE hostname = :HOSTNAME "
00358 "ORDER BY destination");
00359 query.bindValue(":HOSTNAME", m_hostname);
00360
00361 if (!query.exec() || !query.isActive())
00362 {
00363 MythDB::DBError("KeyBindings::LoadJumppoint", query);
00364 return;
00365 }
00366
00367 while (query.next())
00368 {
00369 ActionID id(ActionSet::kJumpContext, query.value(0).toString());
00370
00371 if (query.value(1).toString().isEmpty())
00372 {
00373 m_actionSet.AddAction(id, query.value(0).toString(),
00374 query.value(2).toString());
00375 }
00376 else
00377 {
00378 m_actionSet.AddAction(id, query.value(1).toString(),
00379 query.value(2).toString());
00380 }
00381 }
00382 }
00383
00390 void KeyBindings::LoadContexts(void)
00391 {
00392 MSqlQuery query(MSqlQuery::InitCon());
00393 query.prepare(
00394 "SELECT context, action, description, keylist "
00395 "FROM keybindings "
00396 "WHERE hostname = :HOSTNAME "
00397 "ORDER BY context, action");
00398 query.bindValue(":HOSTNAME", m_hostname);
00399
00400 if (!query.exec() || !query.isActive())
00401 {
00402 MythDB::DBError("KeyBindings::LoadContexts", query);
00403 return;
00404 }
00405
00406 while (query.next())
00407 {
00408 ActionID id(query.value(0).toString(), query.value(1).toString());
00409 m_actionSet.AddAction(id, query.value(2).toString(),
00410 query.value(3).toString());
00411 }
00412 }
00413
00417 void KeyBindings::LoadMandatoryBindings(void)
00418 {
00419 if (!m_mandatoryBindings.empty())
00420 return;
00421
00422 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "DOWN"));
00423 m_defaultKeys.append("Down");
00424
00425 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "UP"));
00426 m_defaultKeys.append("Up");
00427
00428 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "LEFT"));
00429 m_defaultKeys.append("Left");
00430
00431 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "RIGHT"));
00432 m_defaultKeys.append("Right");
00433
00434 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "ESCAPE"));
00435 m_defaultKeys.append("Esc");
00436
00437 m_mandatoryBindings.append(ActionID(ActionSet::kGlobalContext, "SELECT"));
00438 m_defaultKeys.append("Return, Enter, Space");
00439 }
00440
00444 bool KeyBindings::HasMandatoryBindings(void) const
00445 {
00446 const ActionList &manlist = m_mandatoryBindings;
00447 for (int i = 0; i < manlist.count(); i++)
00448 {
00449 if (m_actionSet.GetKeys(manlist[i]).isEmpty())
00450 return false;
00451 }
00452
00453 return true;
00454 }