diff --git a/src/KeyMap.cpp b/src/KeyMap.cpp index 966b4e235e..c6d355c237 100644 --- a/src/KeyMap.cpp +++ b/src/KeyMap.cpp @@ -85,12 +85,11 @@ size_t KeyMap::unbind(string const & seq, FuncRequest const & func) } -bool KeyMap::hasBinding(KeySequence const & seq, FuncRequest const & func, - unsigned int r) +FuncRequest KeyMap::getBinding(KeySequence const & seq, unsigned int r) { KeySymbol code = seq.sequence[r]; if (!code.isOK()) - return false; + return FuncRequest::unknown; KeyModifier const mod1 = seq.modifiers[r].first; KeyModifier const mod2 = seq.modifiers[r].second; @@ -102,12 +101,12 @@ bool KeyMap::hasBinding(KeySequence const & seq, FuncRequest const & func, && mod1 == it->mod.first && mod2 == it->mod.second) { if (r + 1 == seq.length()) - return it->func == func; + return it->func; else if (it->table.get()) - return it->table->hasBinding(seq, func, r + 1); + return it->table->getBinding(seq, r + 1); } } - return false; + return FuncRequest::unknown; } diff --git a/src/KeyMap.h b/src/KeyMap.h index b4f4cd1331..cc7c155959 100644 --- a/src/KeyMap.h +++ b/src/KeyMap.h @@ -56,9 +56,11 @@ public: unsigned int r = 0); - /// if a keybinding has been defined. - bool hasBinding(KeySequence const & seq, FuncRequest const & func, - unsigned int r = 0); + /// returns the function bound to this key sequence, or + /// FuncRequest::unknown if no binding exists for it. + /// @param r an internal recursion counter + // FIXME Surely there's a better way to do that? + FuncRequest getBinding(KeySequence const & seq, unsigned int r = 0); /// clear all bindings void clear(); diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp index d10a73982b..37637a1eff 100644 --- a/src/frontends/qt4/GuiPrefs.cpp +++ b/src/frontends/qt4/GuiPrefs.cpp @@ -2404,6 +2404,15 @@ void PrefShortcuts::on_searchLE_textEdited() } +docstring makeCmdString(FuncRequest const & f) +{ + docstring actionStr = from_ascii(lyxaction.getActionName(f.action)); + if (!f.argument().empty()) + actionStr += " " + f.argument(); + return actionStr; +} + + void PrefShortcuts::shortcut_okPB_pressed() { QString const new_lfun = shortcut_->lfunLE->text(); @@ -2422,10 +2431,29 @@ void PrefShortcuts::shortcut_okPB_pressed() return; } - // if both lfun and shortcut is valid - if (user_bind_.hasBinding(k, func) || system_bind_.hasBinding(k, func)) { + // check to see if there's been any change + FuncRequest oldBinding = system_bind_.getBinding(k); + if (oldBinding.action == LFUN_UNKNOWN_ACTION) + oldBinding = user_bind_.getBinding(k); + if (oldBinding == func) { + docstring const actionStr = makeCmdString(func); Alert::error(_("Failed to create shortcut"), - _("Shortcut is already defined")); + bformat(_("Shortcut `%1$s' is already bound to:\n%2$s"), + k.print(KeySequence::ForGui), actionStr)); + return; + } + + // make sure this key isn't already bound---and, if so, not unbound + FuncCode const unbind = user_unbind_.getBinding(k).action; + if (oldBinding.action != LFUN_UNKNOWN_ACTION && unbind == LFUN_UNKNOWN_ACTION) + { + // FIXME Perhaps we should offer to over-write the old shortcut? + // If so, we'll need to remove it from our list, etc. + docstring const actionStr = makeCmdString(oldBinding); + Alert::error(_("Failed to create shortcut"), + bformat(_("Shortcut `%1$s' is already bound to:\n%2$s\n" + "You need to remove that binding before creating a new one."), + k.print(KeySequence::ForGui), actionStr)); return; }