Ticket #2078: ui_and_logic.diff

File ui_and_logic.diff, 40.4 KB (added by mfgalizi@…, 15 years ago)

The patch (no deletion)

  • mythcontrols/actionset.h

     
    122122    QStringList getKeys(const ActionID &id) const;
    123123
    124124    /**
     125     * Get all keys that are in use.
     126     * @return A string list containing all of the keys.
     127     */
     128    QStringList * getAllKeys(void) const;
     129
     130    /**
     131     * Get the contexts, in which a key is bound.
     132     * @return A string list containing the context names.
     133     */
     134    QStringList * getKeyContexts(const QString &key) const;
     135
     136    /**
     137     * Get all of the actions that are in use.
     138     * @return A string list containing all of the actions.
     139     */
     140    QStringList *getAllActions(void) const;
     141
     142    /**
    125143     * @brief Get the description of an action.
    126144     * @param id The action identifier.
    127145     * @return The action description.
     
    209227    QMap<QString, ActionList> _keymap;
    210228    QDict<Context> _contexts;
    211229    ActionList _modified;
     230
     231    /* map from action to the contexts it belongs to */
     232    QMap<QString, QStringList> _actions;
     233
    212234};
    213235
    214236#endif /* ACTIONSET_H */
  • mythcontrols/mythcontrols.cpp

     
    5454        return key;
    5555}
    5656
    57 static const QString DisplayToKey(const QString key)
    58 {
    59     if (key.left(1) == "[" && key != "[")
    60         return "remote" + key.mid(1,key.length()-2);
    61     else
    62         return key;
    63 }
    6457
    6558/* comments in header */
    6659MythControls::MythControls (MythMainWindow *parent, bool& ui_ok)
     
    6962    /* Nullify keybindings so the deconstructor knows not to delete it */
    7063    this->key_bindings = NULL;
    7164
    72     /* delete the contents when we're done */
    73     m_contexts.setAutoDelete(true);
    74    
     65    this->view = ActionsByContext;
     66
    7567    /* load up the ui components */
    7668    if ((ui_ok = loadUI()))
    7769    {
    78         leftType = kContextList;
    79         rightType = kActionList;
    80 
    8170        /* for starters, load this host */
    82         loadHost(gContext->GetHostName());
     71        key_bindings = new KeyBindings(gContext->GetHostName());
    8372
    8473        /* update the information */
    85         refreshKeyInformation();
     74        setView(ActionsByContext, true);
     75        refreshInformation();
    8676
    8777        /* capture the signals we want */
    8878        connect(LeftList, SIGNAL(itemSelected(UIListBtnTypeItem*)),
     
    162152}
    163153
    164154
     155void MythControls::showButtons(bool shown) const
     156{
     157    for (size_t i = 0; i < Action::MAX_KEYS; i++)
     158    {
     159        shown ? ActionButtons[i]->show() : ActionButtons[i]->hide();
     160    }
     161}
    165162
     163
     164/* method description in mythcontrols.h */
     165void MythControls::blankButtons(void) const
     166{
     167        for (size_t i = 0; i < Action::MAX_KEYS; i++)
     168            ActionButtons[i]->setText("");
     169}
     170
     171/* method description in mythcontrols.h */
     172void MythControls::fillButtons(const QStringList & strings)
     173{
     174    size_t i = 0, maxstr = Action::MAX_KEYS;
     175
     176    if (strings.count() < Action::MAX_KEYS)
     177        maxstr = strings.count();
     178   
     179    /* fill existing keys */
     180    for (; i < maxstr; i++)
     181        ActionButtons[i]->setText(KeyToDisplay(strings[i]));
     182
     183    /* blank the other ones */
     184    for (; i < Action::MAX_KEYS; i++)
     185        ActionButtons[i]->setText("");
     186}
     187
    166188/* comments in header */
    167189size_t MythControls::focusedButton(void) const
    168190{
     
    172194    return Action::MAX_KEYS;
    173195}
    174196
    175 
    176197void MythControls::focusButton(int direction)
    177198{
    178     if (leftType != kContextList || rightType != kActionList)
    179         return;
    180199    if (direction == 0)
    181200    {
    182201        focused = ActionButtons[0];
     
    222241    focused = focus;
    223242    focus->SetActive(true);
    224243    focus->takeFocus();
    225     refreshKeyInformation();
     244    /*refreshKeyInformation();*/
     245    refreshInformation();
    226246}
    227247
     248/* method description in mythcontrols.h */
     249void MythControls::setView(ViewMode newview, bool force)
     250{
     251    QStringList *lstrings = NULL, *rstrings = NULL;
     252
     253    /* Dont set the view to what is already is */
     254    if ((newview == this->view) && (force == false))
     255      return;
     256
     257    focused = LeftList;
     258    LeftList->takeFocus();
     259   
     260    this->view = newview;
     261
     262    switch (newview) {
     263    case ActionsByContext:
     264        this->showButtons(true);
     265        LeftDesc->SetText(tr("Contexts"));
     266        RightDesc->SetText(tr("Actions"));
     267        lstrings = key_bindings->getContexts();
     268        rstrings = key_bindings->getActions((*lstrings)[0]);
     269        break;
     270    case ActionsByKey:
     271        this->showButtons(false);
     272        LeftDesc->SetText(tr("Keys"));
     273        RightDesc->SetText(tr("Actions"));
     274        lstrings = key_bindings->getAllKeys();
     275        rstrings = key_bindings->getKeyActions((*lstrings)[0]);
     276        break;
     277    case ContextsByKey:
     278        this->showButtons(false);
     279        LeftDesc->SetText(tr("Keys"));
     280        RightDesc->SetText(tr("Contexts"));
     281        lstrings = key_bindings->getAllKeys();
     282        rstrings = key_bindings->getContexts((*lstrings)[0]);
     283        break;
     284    }
     285
     286    /* refresh the keys on the left */
     287    if (lstrings != NULL) {
     288        refreshLeft(lstrings);
     289        delete lstrings;
     290    }
     291
     292    /* refresh the keys on the right */
     293    if (rstrings != NULL) {
     294        refreshRight(rstrings);
     295        delete rstrings;
     296    }
     297}
     298
    228299void MythControls::keyPressEvent(QKeyEvent *e)
    229300{
    230301    bool handled = false;
     
    232303    QStringList actions;
    233304    gContext->GetMainWindow()->TranslateKeyPress("Controls", e, actions);
    234305
     306   
     307
    235308    for (size_t i = 0; i < actions.size() && !handled; i++)
    236309    {
    237310        QString action = actions[i];
     
    254327        {
    255328            if (focused == LeftList)
    256329                switchListFocus(RightList, LeftList);
    257             else if (focused == RightList)
    258                 focusButton(0);
    259             else {
    260                 QString key = getCurrentKey();
    261                 if (!key.isEmpty())
    262                 {
    263                     ActionMenu popup(gContext->GetMainWindow());
    264                     int result = popup.getOption();
    265                     if (result == ActionMenu::SET) addKeyToAction();
    266                     else if (result == ActionMenu::REMOVE) deleteKey();
    267                 } else // for blank keys, no reason to ask what to do
    268                     addKeyToAction();
     330            else if (this->view == ActionsByContext) {
     331                if (focused == RightList)
     332                    focusButton(0);
     333                else {
     334                    QString key = getCurrentKey();
     335                    if (!key.isEmpty())
     336                    {
     337                        ActionMenu popup(gContext->GetMainWindow());
     338                        int result = popup.getOption();
     339                        if (result == ActionMenu::SET) addKeyToAction();
     340                        else if (result == ActionMenu::REMOVE) deleteKey();
     341                    } else // for blank keys, no reason to ask what to do
     342                        addKeyToAction();
     343                }
    269344            }
    270345        }
    271346        else if (action == "ESCAPE")
     
    331406            else if (focused == RightList)
    332407                RightList->MoveDown(UIListBtnType::MovePage);
    333408        }
    334         else if (action == "1")
    335         {
    336             if (leftType != kContextList || rightType != kActionList)
    337             {
    338                 leftType = kContextList;
    339                 rightType = kActionList;
    340                 updateLists();
    341                 if (focused != LeftList)
    342                     switchListFocus(LeftList,
    343                                     (focused == RightList) ? RightList : NULL);
    344             } else handled = false;
    345         }
    346         else if (action == "2")
    347         {
    348             if (leftType != kContextList || rightType != kKeyList)
    349             {
    350                 leftType = kContextList;
    351                 rightType = kKeyList;
    352                 updateLists();
    353                 if (focused != LeftList)
    354                     switchListFocus(LeftList,
    355                                     (focused == RightList) ? RightList : NULL);
    356             } else handled = false;
    357         }
    358         else if (action == "3")
    359         {
    360             if (leftType != kKeyList || rightType != kContextList)
    361             {
    362                 leftType = kKeyList;
    363                 rightType = kContextList;
    364                 updateLists();
    365                 if (focused != LeftList)
    366                     switchListFocus(LeftList,
    367                                     (focused == RightList) ? RightList : NULL);
    368             } else handled = false;
    369         }
     409        else if (action == "1") setView(ActionsByContext);
     410        else if (action == "2") setView(ActionsByKey);
     411        else if (action == "3") setView(ContextsByKey);
    370412        else handled = false;
    371413    }
    372414
     
    381423bool MythControls::JumpTo(QKeyEvent *e)
    382424{
    383425    UIListBtnType *list = NULL;
    384     if (focused == LeftList && leftType == kKeyList) list = LeftList;
    385     if (focused == RightList && rightType == kKeyList) list = RightList;
     426
     427    if (view != ActionsByContext) {
     428        if (focused == LeftList) list = LeftList;
     429        else list = RightList;
     430    }
     431
    386432    if (!list) return false;
    387433
    388434    QString key = e->text();
     
    429475    refreshRightList();
    430476    RightList->blockSignals(false);
    431477    RightList->refresh();
     478    description->SetText("");
    432479}
    433480
    434481void MythControls::rightSelected(UIListBtnTypeItem*)
    435482{
    436483    RightList->refresh();
    437     refreshKeyInformation();
     484    refreshInformation();
    438485}
    439486
     487void MythControls::refreshRight(QStringList * strings)
     488{
     489    RightList->blockSignals(true);
     490    RightList->Reset();
    440491
     492    /* sort the strings */
     493    strings->sort();
    441494
     495    for (size_t i = 0; i < strings->size(); i++) {
     496        UIListBtnTypeItem *item = new UIListBtnTypeItem(RightList, (*strings)[i]);
     497        item->setDrawArrow(false);
     498    }
     499
     500    RightList->blockSignals(false);
     501    RightList->refresh();
     502}
     503
    442504/* method description in header */
    443 void MythControls::refreshRightList()
     505void MythControls::refreshLeft(QStringList * strings)
    444506{
    445     RightList->Reset();
     507    LeftList->blockSignals(true);
     508    LeftList->Reset();
    446509
    447     if (LeftList->GetItemCurrent() == NULL)
    448         return;
     510    /* sort the strings */
     511    strings->sort();
    449512
    450     if (leftType == kContextList)
    451     {
    452         if (rightType == kActionList)
    453         {
    454             /* add all of the actions to the context list */
    455             QString context = LeftList->GetItemCurrent()->text();
    456             QStringList *actions = m_contexts[context];
    457             if (actions == NULL)
    458             {
    459                 VERBOSE(VB_IMPORTANT, QString("MythControls: Unable to find actions for context %1").arg(context));
    460                 return;
    461             }
    462             UIListBtnTypeItem *item;
    463             for (size_t i = 0; i < actions->size(); i++)
    464                 item = new UIListBtnTypeItem(RightList, (*actions)[i]);
    465         }
    466         else if (rightType == kKeyList)
    467         {
    468             /* add all of the actions to the context list */
    469             QString context = LeftList->GetItemCurrent()->text();
    470             BindingList *list = contextKeys[context];
    471             if (list == NULL)
    472             {
    473                 VERBOSE(VB_IMPORTANT, QString("MythControls: Unable to find keys for context %1").arg(context));
    474                 return;
    475             }
    476             UIListBtnTypeItem *item;
    477             for (BindingList::iterator it = list->begin(); it != list->end(); ++it)
    478             {
    479                 binding_t *b = *it;
    480                 item = new UIListBtnTypeItem(RightList, KeyToDisplay(b->key) + " => " + b->action);
    481             }
    482         }
    483     } else if (leftType == kKeyList && rightType == kContextList)
    484     {
    485         QString key = DisplayToKey(LeftList->GetItemCurrent()->text());
    486         BindingList *list = keyActions[key];
    487         if (list == NULL)
    488         {
    489             VERBOSE(VB_IMPORTANT, QString("MythControls: Unable to find actions for key %1").arg(key));
    490             return;
    491         }
    492         UIListBtnTypeItem *item;
    493         BindingList::iterator it = list->begin();
    494         binding_t *b = *it;
    495         for (size_t i = 0; i < contexts.size(); i++)
    496         {
    497             QString context = contexts[i];
    498             QString action = "<none>";
    499             if (b && b->context == context)
    500             {
    501                 action = b->action;
    502                 ++it;
    503                 if (it != list->end()) b = *it;
    504                 else b = NULL;
    505             }
    506             item = new UIListBtnTypeItem(RightList, context + " => " + action);
    507         }
     513    for (size_t i = 0; i < strings->size(); i++) {
     514        UIListBtnTypeItem *item = new UIListBtnTypeItem(LeftList, (*strings)[i]);
     515        item->setDrawArrow(true);
    508516    }
     517
     518    LeftList->blockSignals(false);
     519    LeftList->refresh();
    509520}
    510521
    511522
    512 /* comments in header */
    513 void MythControls::refreshKeyInformation()
     523/* method description in mythcontrols.h */
     524void MythControls::refreshRightList()
    514525{
    515     /* get the description of the current action */
    516     QString desc;
     526    QStringList *rstrings = NULL;
     527    QString lstring = LeftList->GetItemCurrent()->text();
    517528
    518     if (focused == LeftList)
    519     {
    520         /* blank all keys on the context */
    521         for (size_t i = 0; i < Action::MAX_KEYS; i++)
    522             ActionButtons[i]->setText("");
     529    /* right list, based on values from the left */
     530    switch (this->view) {
     531    case ActionsByContext:
     532        this->showButtons(true);
     533        rstrings = key_bindings->getActions(lstring);
     534        break;
     535    case ActionsByKey:
     536        this->showButtons(false);
     537        rstrings = key_bindings->getKeyActions(lstring);
     538        break;
     539    case ContextsByKey:
     540        this->showButtons(false);
     541        rstrings = key_bindings->getContexts(lstring);
     542        break;
    523543    }
    524     else if (leftType == kKeyList || rightType == kKeyList)
    525     { // Should show appropriate description
    526         QString action = getCurrentAction();
    527         QString context = getCurrentContext();
    528         /* blank all keys on the context */
    529         for (size_t i = 0; i < Action::MAX_KEYS; i++)
    530             ActionButtons[i]->setText("");
    531         if (!action.isEmpty())
    532             {
    533    
    534             desc = key_bindings->getActionDescription(context, action);
    535    
    536             BindingList *list = NULL;
    537             if (leftType == kKeyList && rightType == kContextList)
    538             {
    539                 QString key = getCurrentKey();
    540                 list = keyActions[DisplayToKey(key)];
    541             }
    542             else if (leftType == kContextList && rightType == kKeyList)
    543                 list = contextKeys[context];
    544             if (list)
    545             {
    546                 QString searchKey;
    547                 if (rightType == kContextList)
    548                     searchKey = context;
    549                 else if (rightType == kActionList)
    550                     searchKey = action;
    551                 else if (rightType == kKeyList)
    552                     searchKey = DisplayToKey(getCurrentKey());
    553                 binding_t *binding = NULL;
    554                 for (BindingList::iterator it = list->begin(); it != list->end(); ++it)
    555                 {
    556                     binding_t *b = *it;
    557                     switch (rightType)
    558                     {
    559                         case kContextList:
    560                             if (b->context == searchKey) binding = b;
    561                             break;
    562                         case kActionList:
    563                             if (b->action == searchKey) binding = b;
    564                             break;
    565                         case kKeyList:
    566                             if (b->key == searchKey) binding = b;
    567                             break;
    568                     }
    569                     if (binding) break;
    570                 }
    571    
    572                 if (binding)
    573                 {
    574                     if (desc.isEmpty() && context != binding->contextFrom)
    575                         desc = key_bindings->getActionDescription(binding->contextFrom, action);
    576                     desc += "\n" + tr("Binding comes from %1 context")
    577                             .arg(binding->contextFrom);
    578                 }
    579             }
    580         }
    581     } else {
    582         QString context = getCurrentContext();
    583         QString action = getCurrentAction();
    584         /* set the description */
    585         desc = key_bindings->getActionDescription(getCurrentContext(),
    586                                                   getCurrentAction());
    587544
    588         /* get the bindings of the current action */
    589         QStringList keys = key_bindings->getActionKeys(getCurrentContext(),
    590                                                        getCurrentAction());
     545    refreshRight(rstrings);
     546    delete rstrings;
     547}
    591548
    592         size_t i;
    593549
    594         /* fill existing keys */
    595         for (i = 0; i < keys.count(); i++)
    596             ActionButtons[i]->setText(KeyToDisplay(keys[i]));
     550void MythControls::refreshBindingInformation()
     551{
     552    QString context = LeftList->GetItemCurrent()->text();
     553    QString action = RightList->GetItemCurrent()->text();
     554    QString desc = key_bindings->getActionDescription(getCurrentContext(),
     555                                                      getCurrentAction());
    597556
    598         /* blank the other ones */
    599         for (; i < Action::MAX_KEYS; i++)
    600             ActionButtons[i]->setText("");
    601     }
     557    /* get the bindings of the current action */
     558    QStringList keys = key_bindings->getActionKeys(getCurrentContext(),
     559                                                   getCurrentAction());
    602560
    603     /* set the information */
     561    fillButtons(keys);
     562
    604563    description->SetText(desc);
    605564}
    606565
    607566
     567/* method description in mythcontrols.h */
     568void MythControls::refreshInformation()
     569{
     570    switch (this->view)
     571    {
     572    case ActionsByContext:
     573        if (focused == LeftList) {
     574            blankButtons();
     575            description->SetText("");
     576        }
     577        else refreshBindingInformation();
     578        break;
     579    case ActionsByKey:
     580        if (focused == LeftList) description->SetText("");
     581        else
     582        {
     583            QString key = LeftList->GetItemCurrent()->text();
     584            QString action = RightList->GetItemCurrent()->text();
     585            int pos = RightList->GetItemPos(RightList->GetItemCurrent());
     586            QString context = key_bindings->getContext(key, action, pos);
     587            QString desc = key_bindings->getActionDescription(context, action);
     588            desc += "\n" + tr("Binding comes from %1 context").arg(context);
     589            description->SetText(desc);
     590        }
     591        break;
     592    case ContextsByKey:
     593        if (focused == LeftList) description->SetText("");
     594        else
     595        {
     596            QString key = LeftList->GetItemCurrent()->text();
     597            QString context = RightList->GetItemCurrent()->text();
     598            QString action = key_bindings->getAction(key, context);
     599            QString desc = action + ": " + key_bindings->getActionDescription(context,
     600                                                                              action);
     601            description->SetText(desc);
     602        }
     603        break;
     604    }
     605}
    608606
    609607/* comments in header */
    610608QString MythControls::getCurrentContext(void) const
    611609{
    612     if (leftType == kContextList)
    613         return LeftList->GetItemCurrent()->text();
    614     if (focused == LeftList) return "";
    615 
    616     QString desc = RightList->GetItemCurrent()->text();
    617     int loc = desc.find(" => ");
    618     if (loc == -1) return ""; // Should not happen
    619     if (rightType == kContextList) return desc.left(loc);
    620     else return desc.mid(loc+4);
     610    if (view == ActionsByContext) return LeftList->GetItemCurrent()->text();
     611    else if ((view == ContextsByKey) && (focused == RightList))
     612        return RightList->GetItemCurrent()->text();
     613    else return "";
    621614}
    622615
    623616/* comments in header */
    624617QString MythControls::getCurrentAction(void) const
    625618{
    626     if (leftType == kActionList)
    627         return LeftList->GetItemCurrent()->text();
    628     if (focused == LeftList) return "";
    629619
    630     QString desc = RightList->GetItemCurrent()->text();
    631     if (leftType == kContextList && rightType == kActionList)
    632         return desc;
    633     int loc = desc.find(" => ");
    634     if (loc == -1) return ""; // Should not happen
    635     if (rightType == kActionList) return desc.left(loc);
    636     else
    637     {
    638         QString rv = desc.mid(loc+4);
    639         if (rv == "<none>") return "";
    640         else return rv;
    641     }
     620    if (((view == ActionsByContext) && (focused != LeftList)) ||
     621        ((view == ActionsByKey) && (focused == RightList)))
     622        return RightList->GetItemCurrent()->text();
     623    else return "";
    642624}
    643625
    644626/* comments in header */
    645627QString MythControls::getCurrentKey(void) const
    646628{
    647     if (leftType == kKeyList)
    648         return LeftList->GetItemCurrent()->text();
    649     if (focused == LeftList) return "";
    650 
    651     if (leftType == kContextList && rightType == kActionList)
     629    if (view == ActionsByContext)
    652630    {
    653631        QString context = getCurrentContext();
    654632        QString action = getCurrentAction();
     
    657635        if (b < keys.count()) return keys[b];
    658636        else return "";
    659637    }
    660 
    661     QString desc = RightList->GetItemCurrent()->text();
    662     int loc = desc.find(" => ");
    663     if (loc == -1) return ""; // Should not happen
    664     if (rightType == kKeyList) return desc.left(loc);
    665     else return desc.mid(loc+4);
     638    else return LeftList->GetItemCurrent()->text();
    666639}
    667640
    668 
    669641/* comments in header */
    670 void MythControls::loadHost(const QString & hostname) {
    671 
    672     /* create the key bindings and the tree */
    673     key_bindings = new KeyBindings(hostname);
    674     contexts = *key_bindings->getContexts();
    675 
    676     keys.clear();
    677 
    678     /* Alphabetic order, but jump and global at the top  */
    679     contexts.sort();
    680     contexts.remove(JUMP_CONTEXT);
    681     contexts.remove(GLOBAL_CONTEXT);
    682     contexts.insert(contexts.begin(), 1, GLOBAL_CONTEXT);
    683     contexts.insert(contexts.begin(), 1, JUMP_CONTEXT);
    684 
    685     QStringList *actions;
    686     for (size_t i = 0; i < contexts.size(); i++)
    687     {
    688         actions = key_bindings->getActions(contexts[i]);
    689         actions->sort();
    690         m_contexts.insert(contexts[i], actions);
    691     }
    692 
    693     refreshKeyBindings();
    694     updateLists();
    695 }
    696 
    697 
    698 
    699 /* comments in header */
    700642void MythControls::deleteKey()
    701643{
    702644    // This code needs work to support deleteKey in any mode exc. Context/Action
    703645    QString context = getCurrentContext();
    704646    QString key = getCurrentKey();
    705647    QString action = getCurrentAction();
     648
    706649    if (context.isEmpty() || key.isEmpty() || action.isEmpty())
    707650    {
    708651        InvalidBindingPopup popup(gContext->GetMainWindow());
     
    710653        return;
    711654    }
    712655
    713     BindingList *list = keyActions[key];
    714     binding_t *binding = NULL;
    715     for (BindingList::iterator it = list->begin(); it != list->end(); ++it)
     656    if (view == ActionsByContext)
    716657    {
    717         binding_t *b = *it;
    718         if (b->context == context) binding = b;
    719     }
    720     if (!binding)
    721     {
    722         InvalidBindingPopup popup(gContext->GetMainWindow());
    723         popup.getOption();
    724         return;
    725     }
    726 
    727     if (binding->contextFrom != context)
    728     {
    729         ConfirmMenu popup(gContext->GetMainWindow(), tr("Delete this key binding from context %1?").arg(binding->contextFrom));
     658        ConfirmMenu popup(gContext->GetMainWindow(), tr("Delete this key binding from context %1?").arg(context));
    730659        if (popup.getOption() != ConfirmMenu::CONFIRM) return;
    731     } else {
    732         ConfirmMenu popup(gContext->GetMainWindow(), tr("Delete this binding?"));
    733         if (popup.getOption() != ConfirmMenu::CONFIRM) return;
     660        else
     661        {
     662            key_bindings->removeActionKey(context, action, key);
     663        }
    734664    }
    735665
    736     if (!key_bindings->removeActionKey(binding->contextFrom, action, key))
    737     {
    738         InvalidBindingPopup popup(gContext->GetMainWindow());
    739         popup.getOption();
    740         return;
    741     }
    742 
    743     // refreshing everything is overkill.  I tried incrementally updating, but the
    744     // code was ugly.  Since this is quick in my experience, overkill away!
    745     refreshKeyBindings();
    746     refreshKeyInformation();
     666    refreshInformation();
    747667}
    748668
    749669/* method description in header */
     
    780700/* method description in header */
    781701void MythControls::addKeyToAction(void)
    782702{
    783     // This code needs work to support deleteKey in any mode exc. Context/Action
    784703    /* grab a key from the user */
    785704    KeyGrabPopupBox *kg = new KeyGrabPopupBox(gContext->GetMainWindow());
    786705    int result = kg->ExecPopup(kg,SLOT(cancel()));
     
    817736    else
    818737        key_bindings->addActionKey(context, action, key);
    819738
    820     refreshKeyBindings();
    821     refreshKeyInformation();
     739    refreshInformation();
    822740}
    823741
    824 
    825 
    826 void MythControls::addBindings(QDict<binding_t> &bindings,
    827                                const QString &context,
    828                                const QString &contextParent, int bindlevel)
    829 {
    830     QStringList *actions = key_bindings->getActions(context);
    831 
    832     for (size_t i = 0; i < actions->size(); i++)
    833     {
    834         QString action = (*actions)[i];
    835         QStringList keys = key_bindings->getActionKeys(context, action);
    836 
    837         for (size_t j = 0; j < keys.size(); j++)
    838         {
    839             QString key = keys[j];
    840 
    841             binding_t *b = bindings.find(key);
    842             if (!b)
    843             {
    844                 b = new(binding_t);
    845                 b->key = key;
    846                 b->action = action;
    847                 b->context = contextParent;
    848                 b->contextFrom = context;
    849                 b->bindlevel = bindlevel;
    850                 bindings.insert(key, b);
    851             }
    852             else if (b->bindlevel == bindlevel)
    853             {
    854                 b->action += ", " + action;
    855             }
    856         }
    857     }
    858 }
    859 
    860 BindingList *MythControls::getKeyBindings(const QString &context)
    861 {
    862     QStringList keys;
    863     QDict<binding_t> bindings;
    864     bindings.clear();
    865 
    866     for (size_t i = 0; i < contexts.size(); i++)
    867         addBindings(bindings, contexts[i], context, i);
    868 
    869 
    870     for (QDictIterator<binding_t> it(bindings); it.current(); ++it)
    871     {
    872         QString key = it.currentKey();
    873         keys.append(key);
    874     }
    875 
    876     sortKeyList(keys);
    877 
    878     BindingList *retval = new BindingList;
    879     retval->clear();
    880 
    881     for (QStringList::Iterator kit = keys.begin(); kit != keys.end(); ++kit)
    882     {
    883         QString key = *kit;
    884         retval->append(bindings[key]);
    885     }
    886     retval->setAutoDelete(true);
    887     return retval;
    888 }
    889 
    890 void MythControls::refreshKeyBindings()
    891 {
    892     contextKeys.clear();
    893     keyActions.clear();
    894     for (size_t i = 0; i < contexts.size(); i++)
    895     {
    896         QString context = contexts[i];
    897         BindingList *list = getKeyBindings(context);
    898         contextKeys.insert(context, list);
    899         for (BindingList::iterator it = list->begin(); it != list->end(); ++it)
    900         {
    901             binding_t *b = *it;
    902             BindingList *list = keyActions.find(b->key);
    903             if (!list)
    904             {
    905                 list = new BindingList;
    906                 list->clear();
    907                 keyActions.insert(b->key, list);
    908             }
    909             keys.append(b->key);
    910             list->append(b);
    911         }
    912     }
    913     contextKeys.setAutoDelete(true);
    914     keyActions.setAutoDelete(true);
    915 
    916     sortKeyList(keys);
    917 }
    918 
    919 void MythControls::sortKeyList(QStringList &keys)
    920 {
    921     QStringList t;
    922     t.clear();
    923 
    924     for ( QStringList::Iterator it = keys.begin(); it != keys.end(); ++it )
    925     {
    926         QString key = *it;
    927 
    928         QString keydesc = "3 ";
    929         if (key.left(6) == "remote")
    930         {
    931             keydesc = "0 ";
    932         }
    933         else if (key.length() == 1)
    934         {
    935             switch (key[0].category())
    936             {
    937                 case QChar::Letter_Uppercase:
    938                     keydesc = "2 ";
    939                     break;
    940                 case QChar::Number_DecimalDigit:
    941                     keydesc = "1 ";
    942                     break;
    943                 default:
    944                     keydesc = "5 ";
    945                     break;
    946             }
    947         }
    948         else if (key.find("+", 1) != -1)
    949             keydesc = "4 ";
    950 
    951         t.push_back(keydesc + key);
    952     }
    953     t.sort();
    954 
    955     QString prev = "";
    956 
    957     keys.clear();
    958     for (QStringList::Iterator kit = t.begin(); kit != t.end(); ++kit)
    959     {
    960         QString cur = (*kit).mid(2);
    961         if (cur != prev)
    962         {
    963             keys.append(cur);
    964             prev = cur;
    965         }
    966     }
    967 }
    968 
    969 QString MythControls::getTypeDesc(ListType type)
    970 {
    971     switch (type)
    972     {
    973         case kContextList:
    974             return tr("Contexts");
    975             break;
    976         case kKeyList:
    977             return tr("Keys");
    978             break;
    979         case kActionList:
    980             return tr("Actions");
    981             break;
    982         default:
    983             return "";
    984     }
    985 }
    986 
    987 void MythControls::updateLists()
    988 {
    989     RightList->blockSignals(true);
    990     LeftList->blockSignals(true);
    991     LeftList->Reset();
    992     if (leftType == kContextList)
    993     {
    994         UIListBtnTypeItem *item;
    995         for (size_t i = 0; i < contexts.size(); i++)
    996         {
    997             item = new UIListBtnTypeItem(LeftList, contexts[i]);
    998             item->setDrawArrow(true);
    999         }
    1000     } else if (leftType == kKeyList)
    1001     {
    1002         UIListBtnTypeItem *item;
    1003         for (size_t i = 0; i < keys.size(); i++)
    1004         {
    1005             QString key = KeyToDisplay(keys[i]);
    1006             item = new UIListBtnTypeItem(LeftList, key);
    1007             item->setDrawArrow(true);
    1008         }
    1009     }
    1010     refreshRightList();
    1011     RightList->blockSignals(false);
    1012     LeftList->blockSignals(false);
    1013     LeftList->refresh();
    1014     RightList->refresh();
    1015 
    1016     if (LeftDesc != NULL)
    1017         LeftDesc->SetText(getTypeDesc(leftType));
    1018     if (RightDesc != NULL)
    1019         RightDesc->SetText(getTypeDesc(rightType));
    1020 }
    1021 
    1022 
    1023742#endif /* MYTHCONTROLS_CPP */
    1024743
    1025744/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • mythcontrols/keybindings.cpp

     
    4848    retrieveJumppoints();
    4949}
    5050
     51QStringList * KeyBindings::getKeyActions(const QString &key) const
     52{
     53    QStringList *strings;
     54    const ActionList & al = actionset.getActions(key);
    5155
     56    if (al.size() > 0) strings = new QStringList();
     57    else return NULL;
    5258
     59    for (size_t i = 0; i < al.size(); i++)
     60    {
     61        strings->push_back(al[i].action());
     62    }
     63
     64    return strings;
     65}
     66
     67
     68QString KeyBindings::getContext(const QString & key, const QString & action,
     69                                size_t anum) const
     70{
     71    /* The cases where unknown is returned should never happen.  If
     72     * you see an unknown context, do not approach.  Call the police
     73     * immediatly. */
     74    const ActionList &al = actionset.getActions(key);
     75    int offset = al.size() - anum;
     76
     77    if (offset < 0) return "UNKNOWN";
     78    else if (al[anum].action() != action) return "UNKNOWN";
     79    if (anum < al.size()) return al[anum].context();
     80    else return "UNKNOWN";
     81}
     82
     83QString KeyBindings::getAction(const QString & key, const QString & context) const
     84{
     85    const ActionList &al = actionset.getActions(key);
     86
     87    for (size_t i = 0; i < al.size(); i++)
     88    {
     89        if (al[i].context() == context) return al[i].action();
     90    }
     91
     92    return "UNKNOWN";
     93}
     94
     95
    5396ActionID * KeyBindings::conflicts(const QString & context_name,
    5497                                  const QString & key, int &level) const
    5598{
  • mythcontrols/actionset.cpp

     
    154154    }
    155155}
    156156
     157QStringList * ActionSet::getAllKeys(void) const {
     158    return new QStringList(this->_keymap.keys());
     159}
    157160
    158161
     162QStringList * ActionSet::getAllActions(void) const {
     163    return new QStringList(this->_actions.keys());
     164}
     165
     166
     167QStringList * ActionSet::getKeyContexts(const QString &key) const
     168{
     169    QStringList *strings = NULL;
     170    const ActionList &ids = _keymap[key];
     171
     172    if (ids.size() == 0) return NULL;
     173
     174    strings = new QStringList();
     175
     176    for (size_t i = 0; i < ids.size(); i++)
     177    {
     178        if (!strings->contains(ids[i].context())) {
     179            strings->push_back(ids[i].context());
     180        }
     181    }
     182
     183    return strings;
     184}
     185
     186
    159187/* method description in header */
    160188bool ActionSet::addAction(const ActionID &id, const QString &description,
    161189                          const QString &keys)
     
    173201        /* add the action into the dict */
    174202        _contexts[id.context()]->insert(id.action(), a);
    175203
     204        /* if the action doesn't already exist, then add it */
     205        QStringList &contexts = _actions[id.action()];
     206        if (!contexts.contains(id.context()))
     207            contexts.push_back(id.context());
     208
    176209        /* get the actions keys */
    177210        const QStringList &keys = a->getKeys();
    178211        for (size_t i = 0; i < keys.count(); i++)
     
    182215            ActionList &ids = _keymap[keys[i]];
    183216
    184217            /* add this action id to the list of actions bound to this key */
    185             ids.push_back(id);
     218            if (ids.size() == 0) ids.push_back(id);
     219            else
     220            {
     221                bool added = false;
     222                ActionList::iterator it;
     223
     224                /* keep list sorted by action, then by context.  You
     225                 * must sort this stuff because multiple actions from
     226                 * different contexts can be added. Otherwise, we get
     227                 * into trouble in keybindings.cpp and
     228                 * mythcontrols.cpp when trying to delete based on
     229                 * action (displayed by key) */
     230                for (it = ids.begin(); (it != ids.end()) && (added == false); ++it)
     231                {
     232                    if ((QString::compare(id.action(), (*it).action()) < 0) ||
     233                        ((QString::compare(id.action(), (*it).action()) == 0) &&
     234                         (QString::compare(id.context(), (*it).context()) < 0))
     235                        )
     236                    {
     237                        ids.insert(it, id);
     238                        added = true;
     239                    }
     240                }
     241                if (added == false) ids.push_back(id);
     242            }
    186243        }
    187244
    188245        return true;
     
    225282}
    226283
    227284
    228 
    229285const QString & ActionSet::getDescription(const ActionID &id) const
    230286{
    231287    Context *c;
  • mythcontrols/mythcontrols.h

     
    9393   
    9494protected:
    9595
     96
     97    /** The view mode */
     98    typedef enum { ActionsByContext, ActionsByKey, ContextsByKey } ViewMode;
     99
    96100    /**
    97101     * @brief Load up UI.
    98102     * @return true if all UI elements were loaded successfully,
     
    105109    bool loadUI();
    106110
    107111    /**
     112     * Show or hide the buttons at the bottom.
     113     *
     114     * @param shown Should the buttons be shown?
     115     */
     116    void showButtons(bool shown) const;
     117
     118    /**
     119     * Blank the text in the bottom buttons.
     120     */
     121    void blankButtons(void) const;
     122
     123    /**
     124     * Fill the buttons with the strings in a string list.
     125     * @param strings The string list.
     126     */
     127    void fillButtons(const QStringList & strings);
     128
     129    /**
     130     * Set the viewing mode of the plugin.
     131     *
     132     * @param view The view mode.
     133     * @param force Force the view to be set (or reset)
     134     */
     135    void setView(ViewMode newview, bool force=false);
     136
     137    /**
    108138     * @brief The key press handler.
    109139     * @param e The key event.
    110140     */
    111141    void keyPressEvent(QKeyEvent *e);
    112142
    113143    /**
    114      * @brief Redraw the key information
    115      *
    116      * Updates the list of keys that are shown and the description of
    117      * the action.
     144     * Refresh the action description and key binding buttons.
    118145     */
    119     void refreshKeyInformation();
     146    void refreshBindingInformation();
    120147
    121148    /**
    122      * @brief Load the appropriate actions into the action list.
    123      * @param context The context, from which actions will be
    124      * displayed.
     149     * @brief Redraw the information at the bottom.
    125150     */
    126     void refreshRightList(void);
     151    void refreshInformation();
    127152
    128153    /**
     154     * Refresh the right list.
     155     * @param strings The strings to place in the right list.
     156     */
     157    void refreshRight(QStringList * strings);
     158
     159    /**
     160     * Refresh the left list.
     161     * @param string The strings to place in the left list.
     162     */
     163    void refreshLeft(QStringList * strings);
     164
     165    /**
     166     * @brief Load the appropriate information into the right list.
     167     * @param strings The strings to load into the right list.
     168     */
     169    void refreshRightList();
     170
     171    /**
    129172     * @brief Redisplay both the left and right lists and fix focus
    130173     */
    131174    void updateLists(void);
     
    183226
    184227private slots:
    185228
    186 /**
    187  * @brief Add a key to the currently selected action.
    188  */
    189 void addKeyToAction(void);
     229        /**
     230     * @brief Add a key to the currently selected action.
     231     */
     232        void addKeyToAction(void);
    190233
    191234    /**
    192235     * @brief Delete the currently active key.
     
    239282    KeyBindings *key_bindings;
    240283    LayerSet *container;
    241284
    242     QStringList contexts; ///< sorted list of contexts
    243     QStringList keys; ///< sorted list of keys
    244285
    245     QDict<QStringList> m_contexts; ///< actions for a given context
    246286    QDict<BindingList> contextKeys; ///< key bindings for a given context
    247287    QDict<BindingList> keyActions; ///< actions in each context for a given key
    248288
    249289    typedef enum { kContextList, kKeyList, kActionList } ListType;
     290
    250291    ListType leftType, rightType;
    251292
     293    ViewMode view;
     294
    252295    QString getTypeDesc(ListType type);
    253296
    254297};
  • mythcontrols/keybindings.h

     
    3030#include "actionid.h"
    3131#include "actionset.h"
    3232
     33
    3334/**
    3435 * @class KeyBindings.
    3536 * @brief Information about the current keybindings.
     
    6364    inline const QString & getHostname() const { return this->_hostname; }
    6465
    6566    /**
     67     * Determine the context belonging to the key and action
     68     *
     69     * @param action The action.
     70     * @param anum The action number (in the list of all of a keys actions).
     71     *
     72     * This method falls apart if the actionset class doesn't sort it
     73     * the actions lists in the _kemap variable.
     74     */
     75    QString getContext(const QString & key, const QString & action, size_t anum) const;
     76
     77    /**
    6678     * @brief Get a list of the context names.
    6779     * @return A list of the context names.
    68      * @note The returned list is a copy and can be modified without
    69      * side-effects.
    7080     */
    7181    inline QStringList * getContexts() const
    7282    {
     
    7484    }
    7585
    7686    /**
     87     * Get the contexts in which a key is bound.
     88     * @param key The key.
     89     * @return A string list containing the context names.
     90     */
     91    inline QStringList * getContexts(const QString & key) const
     92    {
     93        return actionset.getKeyContexts(key);
     94    }
     95
     96    /**
    7797     * @brief Get a list of the actions in a context.
    7898     * @param context The name of the context.
    7999     * @return A list of action (names) for the target context.
     
    86106    }
    87107
    88108    /**
     109     * Get the action bound to a key in a particular context.
     110     *
     111     * @param key The key.
     112     * @param context The context.
     113     * @return The action.
     114     */
     115    QString getAction(const QString & key, const QString & context) const;
     116
     117    /**
     118     * Get all bound keys.
     119     * @return A string list of the bound keys.
     120     */
     121    inline QStringList * getAllKeys() const { return actionset.getAllKeys(); }
     122
     123    /**
    89124     * @brief Get a list of the actions in a context.
    90125     * @param context The name of the context.
    91126     * @return A list of action (names) for the target context.
    92127     * @note Store this instead of calling repeatedly.  Every time you
    93128     * do, ActionSet has to iterate over all contexts and actions.
    94129     */
    95     inline void getKeyActions(const QString &key, ActionList &list) const
    96     {
    97         list = actionset.getActions(key);
    98     }
     130    QStringList * getKeyActions(const QString &key) const;
    99131
    100132    /**
    101133     * @brief Get an action's keys.
     
    187219     * @param key The key to remove.
    188220     * @return true if the key was removed, or false if it was not.
    189221     *
    190      * Unless the action is manditory there is only one key in the
     222     * Unless the action is manditory and there is only one key in the
    191223     * action, this method should return true.
    192224     */
    193225    bool removeActionKey(const QString & context_name,