MythTV  0.26-pre
keybindings.cpp
Go to the documentation of this file.
00001 /* -*- myth -*- */
00029 // MythTV headers
00030 #include "mythdb.h"
00031 #include "mythmainwindow.h"
00032 
00033 // MythControls headers
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     // trying to bind a jumppoint to an already bound key
00186     if ((context_name == ActionSet::kJumpContext) && (ids.count() > 0))
00187         return new ActionID(ids[0]);
00188 
00189     // check the contexts of the other bindings
00190     for (int i = 0; i < ids.count(); i++)
00191     {
00192         // jump points, then global, then the same context
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; // no conflicts
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     // Don't remove the last mandatory binding
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         // commit either a jumppoint or an action
00334         if (id.GetContext() == ActionSet::kJumpContext)
00335             CommitJumppoint(id);
00336         else
00337             CommitAction(id);
00338 
00339         // tell the action set that the action is no longer modified
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; // none are empty...
00454 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends