Ticket #98: sorting_and_warnings3.diff

File sorting_and_warnings3.diff, 10.7 KB (added by mfgalizi@…, 16 years ago)

ARGH -- No more submitting past my bed time (this ones for keeps)

  • mythcontrols/mythcontrols/mythcontrols.cpp

     
    4848#include "mythcontrols.h"
    4949#include "keygrabber.h"
    5050
    51 /**
    52  * @class ConflictResolver
    53  * @brief A MythDialog that notifies the user of conflicts.
    54  */
    55 class ConflictResolver : public MythPopupBox
    56 {
    5751
    58 public:
    59     ConflictResolver(MythMainWindow *window, ActionID *conflict)
    60         : MythPopupBox(window, "conflictresolver")
    61     {
    62         QString warning = "The key you have chosen is already bound to "
    63             + conflict->action() + " in the " + conflict->context()
    64             + " context; please rebind it before binding this key.";
    65        
    66         addLabel("Action Conflict", Large, false);
    67         addLabel(warning, Small, true);
    68     }
    6952
    70 
    71     ConflictResolver(MythMainWindow *window)
    72         : MythPopupBox(window,"conflictresolver")
    73     {
    74 
    75         QString warning;
    76         warning = "This action is manditory and needs at least one key bound ";
    77         warning += "to it.  Instead, try rebinding with another key.";
    78            
    79         addLabel("Manditory Action", Large, false);
    80         addLabel(warning, Small, true);
    81     }
    82 };
    83 
    84 
    8553/* comments in header */
    8654MythControls::MythControls (MythMainWindow *parent, const char *name)
    8755    :MythThemedDialog(parent, "controls", "controls-", name)
     
    392360    context_tree = new GenericTree(hostname, 0, false);
    393361    QStringList context_names = key_bindings->getContexts();
    394362
     363    /* Alphabetic order, except... */
     364    context_names.sort();
     365
     366    /* jump points go first*/
     367    if (context_names.contains(JUMP_CONTEXT))
     368    {
     369        context_names.remove(JUMP_CONTEXT);
     370        context_names.insert(context_names.begin(), 1, JUMP_CONTEXT);
     371    }
     372
     373    /* followed by global */
     374    if (context_names.contains(GLOBAL_CONTEXT))
     375    {
     376        context_names.remove(GLOBAL_CONTEXT);
     377        context_names.insert(++(context_names.begin()), 1, GLOBAL_CONTEXT);
     378    }
     379
    395380    for (size_t i = 0; i < context_names.size(); i++) {
    396381
    397382        GenericTree *context_node = new GenericTree(context_names[i], i, true);
     
    400385        context_tree->addNode(context_node);
    401386
    402387        QStringList action_names = key_bindings->getActions(context_names[i]);
     388        action_names.sort();
    403389
    404390        /* add all actions to the context */
    405391        for (size_t j = 0; j < action_names.size(); j++)
     
    412398
    413399
    414400
     401/* comments in header */
    415402void MythControls::killPopup()
    416403{
    417404    if (this->popup == NULL) return;
     
    461448    QStringList keys = key_bindings->getActionKeys(context, action);
    462449    if (b < keys.count())
    463450    {
     451        cerr << "DELETING" << endl;
    464452        if (!key_bindings->removeActionKey(context, action, keys[b]))
    465453        {
    466             this->popup = new ConflictResolver(gContext->GetMainWindow());
    467             this->popup->ExecPopup(this, SLOT(killPopup()));
     454          /* create the popup */
     455          popup = new MythPopupBox(gContext->GetMainWindow(),
     456                                   "conflictresolver");
     457
     458          QString warning = "This action is manditory and needs at least one "
     459            "key bound to it.  Instead, try rebinding with another key.";
     460           
     461          popup->addLabel("Manditory Action", MythPopupBox::Large, false);
     462          popup->addLabel(warning, MythPopupBox::Small, true);
     463
     464          /*this->popup = new ConflictResolver(gContext->GetMainWindow());*/
     465          this->popup->ExecPopup(this, SLOT(killPopup()));
    468466        }
    469467        else refreshKeyInformation();
    470468    }
     
    472470
    473471
    474472
     473/* method description in header */
     474bool MythControls::resolveConflict(ActionID *conflict, int level)
     475{
     476    MythMainWindow *window = gContext->GetMainWindow();
     477
     478    /* prevent a fatal binding */
     479    if (level == KeyBindings::Error)
     480    {
     481        this->popup = new MythPopupBox(window, "conflictresolver");
     482        QString warning;
     483        warning = "This action is manditory and needs at least one key "
     484            "bound to it.  Instead, try rebinding with another key.";
     485           
     486        popup->addLabel("Manditory Action", MythPopupBox::Large, false);
     487        popup->addLabel(warning, MythPopupBox::Small, true);
     488
     489        this->popup->ExecPopup();
     490        return false;
     491    }
     492    else
     493    {
     494        /* warn the user that this could conflict */
     495        QString message = "This kebinding may conflict with ";
     496        message += conflict->action() + " in the " + conflict->context();
     497        message += " context.  Do you want to bind it anyways?";
     498
     499        if (MythPopupBox::show2ButtonPopup(window, "Conflict Warning",
     500                                           message,"Bind Key","Cancel",0))
     501            return false;
     502    }
     503
     504    return true;
     505}
     506
     507
     508
     509/* method description in header */
    475510void MythControls::addKeyToAction(void)
    476511{
    477512    size_t b = focusedButton();
     
    483518    /* having got the key, kill the key grabber */
    484519    killPopup();
    485520
     521    /* dont bother if its the same key */
     522    if (keys[b] == newkey) return;
     523
     524    bool bind = true;
     525    int level;
     526
     527    /* get the potential conflict */
     528    if ((conflict = key_bindings->conflicts(context, newkey, level)))
     529        bind = resolveConflict(conflict, level);
     530
     531    delete conflict;
     532
     533    /* dont bind */
     534    if (!bind) return;
     535
     536    /* */
    486537    if (b < keys.count())
    487     {
    488         /* dont replace with the same key */
    489         if (keys[b] != newkey) {
    490             if ((conflict = key_bindings->conflicts(context, newkey)))
    491             {
    492                 this->popup = new ConflictResolver(gContext->GetMainWindow(),
    493                                                    conflict);
    494                 this->popup->ExecPopup(this, SLOT(killPopup()));
    495             }
    496             else key_bindings->replaceActionKey(context,action,newkey,keys[b]);
    497         }
    498     }
    499     else {
    500         if ((conflict = key_bindings->conflicts(context, newkey)))
    501         {
    502             this->popup = new ConflictResolver(gContext->GetMainWindow(),
    503                                                conflict);
    504             this->popup->ExecPopup(this, SLOT(killPopup()));
    505         }
    506         else key_bindings->addActionKey(context, action, newkey);
    507     }
     538        key_bindings->replaceActionKey(context,action,newkey,keys[b]);
     539    else
     540        key_bindings->addActionKey(context, action, newkey);
    508541
    509     /* delete the conflict and hide the popup*/
    510     if (conflict) {
    511         delete conflict;
    512         killPopup();
    513     }
    514 
    515542    refreshKeyInformation();
    516543}
    517544
  • mythcontrols/mythcontrols/keybindings.cpp

     
    4949
    5050
    5151ActionID * KeyBindings::conflicts(const QString & context_name,
    52                                   const QString & key) const
     52                                  const QString & key, int &level) const
    5353{
    5454    const ActionList &ids = actionset.getActions(key);
    5555
     
    6060    /* check the contexts of the other bindings */
    6161    for (size_t i = 0; i < ids.count(); i++)
    6262    {
    63         if (ids[i].context() == JUMP_CONTEXT) return new ActionID(ids[i]);
    64         else if (ids[i].context() == context_name) return new ActionID(ids[i]);
     63        /* jump points, then global, then the same context */
     64        if (ids[i].context() == JUMP_CONTEXT) {
     65            level = KeyBindings::Error;
     66            return new ActionID(ids[i]);
     67        }
     68        else if (ids[i].context() == context_name) {
     69            level = KeyBindings::Error;
     70            return new ActionID(ids[i]);
     71        }
     72        else if (ids[i].context()==GLOBAL_CONTEXT) {
     73            level = KeyBindings::Warning;
     74            return new ActionID(ids[i]);
     75        }
    6576    }
    6677
    6778    /* no conflicts */
     
    7081
    7182
    7283
     84/* method description in header */
     85bool KeyBindings::removeActionKey(const QString & context_name,
     86                     const QString & action_name,
     87                     const QString & key) {
     88
     89    ActionID id(context_name, action_name);
     90
     91    /* dont remove the last manditory binding */
     92    if (getManditoryBindings().contains(id)&&(actionset.getKeys(id).count()<2))
     93        return false;
     94    else
     95        return this->actionset.remove(id,key);
     96}
     97
     98
     99
     100/* method description in header */
    73101void KeyBindings::commitAction(const ActionID & id)
    74102{
    75103
  • mythcontrols/mythcontrols/mythcontrols.h

     
    125125     */
    126126    size_t focusedButton(void) const;
    127127
     128    /**
     129     * @brief Resolve a potential conflict.
     130     * @return true if the conflict should be bound, otherwise, false
     131     * is returned.
     132     */
     133    bool resolveConflict(ActionID *conflict, int level);
     134
    128135 private slots:
    129136
    130137     /**
  • mythcontrols/mythcontrols/keybindings.h

     
    2929#include "actionid.h"
    3030#include "actionset.h"
    3131
    32 
    3332/**
    3433 * @class KeyBindings.
    3534 * @brief Information about the current keybindings.
     
    4342 public:
    4443
    4544  /**
     45   * @brief Levels of conflict
     46   * @li None: Does not conflict
     47   * @li Potential: May conflict.
     48   * @li Fatal: Frontend will become inoperable.
     49   */
     50  enum ConflictLevels { Warning, Error};
     51
     52  /**
    4653   * @brief Create a new KeyBindings instance.
    4754   * @param hostname The host for which to create the key bindings.
    4855   */
     
    111118   * @brief Determine if adding a key would cause a conflict.
    112119   * @param context_name The name of the context.
    113120   * @param key The key to add.
     121   * @param level The level of conflict.  Check this if the return
     122   * value is not NULL
    114123   * @return true if adding the key would cause a conflict.
    115124   *
    116125   * Conflicts occur if:
    117126   * @li the key is a jump point, but is bound elsewhere
    118127   * @li the key is already bound to a jumppoint.
     128   * @li the key is bound to something in the global context.
    119129   * @li the key is bound to something else in the specified context
     130   *
     131   * If the method does not return NULL, check the value given to
     132   * level.  Warnings can be ignored (at the users disgression), but
     133   * errors should be prevented no matter what.  If they dont like it,
     134   * they can learn SQL.
    120135   */
    121136  ActionID * conflicts(const QString & context_name,
    122                        const QString & key) const;
     137                       const QString & key, int &level) const;
    123138
    124139  /**
    125140   * @brief Replace a key in an action.
     
    152167   */
    153168  bool removeActionKey(const QString & context_name,
    154169                       const QString & action_name,
    155                        const QString & key) {
    156       return this->actionset.remove(ActionID(context_name, action_name),key);
    157   }
     170                       const QString & key);
    158171
    159172  /**
    160173   * @brief Set the manditory bindings to their defaults.
  • mythcontrols/mythcontrols/mythcontrols.pro

     
    11include ( ../../settings.pro )
    22
    33TEMPLATE = lib
    4 CONFIG += plugin thread warn_on debug
     4CONFIG += plugin thread
    55TARGET = mythcontrols
    66target.path = $${PREFIX}/lib/mythtv/plugins
    77INSTALLS += target