Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Stedfast <jeff@xamarin.com>2012-03-31 04:01:00 +0400
committerJeffrey Stedfast <jeff@xamarin.com>2012-03-31 04:01:00 +0400
commitf2ea3136862aa4712e6a4c56e71281aa7cba186f (patch)
tree89e961168f1fe3e1adf51be31aad335f3eecf6a4
parent03b759a57317b15749138de4cb050d0233da1b1a (diff)
[Ide] Warn user when he/she enters bad keybinding combo
Also revert KeyboardShortcut back into a struct to save space (soptimization ftw) and fixed Mac keybinding menu strings to upper-case the character keys.
-rw-r--r--main/src/addins/MacPlatform/MacMainMenu.cs2
-rw-r--r--main/src/core/Mono.Texteditor/Mono.TextEditor/GtkWorkarounds.cs21
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/Command.cs33
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs60
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs105
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs6
6 files changed, 137 insertions, 90 deletions
diff --git a/main/src/addins/MacPlatform/MacMainMenu.cs b/main/src/addins/MacPlatform/MacMainMenu.cs
index 8d5fef4832..28697a9830 100644
--- a/main/src/addins/MacPlatform/MacMainMenu.cs
+++ b/main/src/addins/MacPlatform/MacMainMenu.cs
@@ -245,6 +245,8 @@ namespace MonoDevelop.MacIntegration
System.Console.WriteLine("WARNING: Could not map key ({0})", key);
return false;
}
+ } else {
+ charCode = (ushort) char.ToUpper ((char) charCode);
}
}
diff --git a/main/src/core/Mono.Texteditor/Mono.TextEditor/GtkWorkarounds.cs b/main/src/core/Mono.Texteditor/Mono.TextEditor/GtkWorkarounds.cs
index 9a90d7af0b..589209d96d 100644
--- a/main/src/core/Mono.Texteditor/Mono.TextEditor/GtkWorkarounds.cs
+++ b/main/src/core/Mono.Texteditor/Mono.TextEditor/GtkWorkarounds.cs
@@ -746,20 +746,29 @@ namespace Mono.TextEditor
static extern void gtksharp_container_override_forall (IntPtr gtype, ForallDelegate cb);
}
- public class KeyboardShortcut : IEquatable<KeyboardShortcut>
+ public struct KeyboardShortcut : IEquatable<KeyboardShortcut>
{
- public KeyboardShortcut (Gdk.Key key, Gdk.ModifierType mod)
+ public static readonly KeyboardShortcut Empty = new KeyboardShortcut ((Gdk.Key) 0, (Gdk.ModifierType) 0);
+
+ Gdk.ModifierType modifier;
+ Gdk.Key key;
+
+ public KeyboardShortcut (Gdk.Key key, Gdk.ModifierType modifier)
{
- Modifier = mod;
- Key = key;
+ this.modifier = modifier;
+ this.key = key;
}
public Gdk.Key Key {
- get; private set;
+ get { return key; }
}
public Gdk.ModifierType Modifier {
- get; private set;
+ get { return modifier; }
+ }
+
+ public bool IsEmpty {
+ get { return Key == (Gdk.Key) 0; }
}
public override bool Equals (object obj)
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/Command.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/Command.cs
index 11b5fa93bd..5bac1ff279 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/Command.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/Command.cs
@@ -42,6 +42,7 @@ namespace MonoDevelop.Components.Commands
string description;
IconId icon;
string accelKey;
+ KeyBinding binding;
string category;
bool disabledVisible;
internal string AccelPath;
@@ -75,14 +76,30 @@ namespace MonoDevelop.Components.Commands
public string AccelKey {
get { return accelKey; }
set {
- string binding = accelKey;
- accelKey = value == string.Empty ? null : value;
+ if (string.IsNullOrEmpty (value))
+ value = null;
- if (KeyBindingChanged != null && accelKey != binding)
- KeyBindingChanged (this, new KeyBindingChangedEventArgs (this, binding));
+ if (value == accelKey)
+ return;
+
+ var oldKeyBinding = binding;
+
+ if (value != null)
+ KeyBinding.TryParse (value, out binding);
+ else
+ binding = null;
+
+ accelKey = value;
+
+ if (KeyBindingChanged != null)
+ KeyBindingChanged (this, new KeyBindingChangedEventArgs (this, oldKeyBinding));
}
}
+ public KeyBinding KeyBinding {
+ get { return binding; }
+ }
+
public bool DisabledVisible {
get { return disabledVisible; }
set { disabledVisible = value; }
@@ -102,7 +119,7 @@ namespace MonoDevelop.Components.Commands
}
public class KeyBindingChangedEventArgs {
- public KeyBindingChangedEventArgs (Command command, string oldKeyBinding)
+ public KeyBindingChangedEventArgs (Command command, KeyBinding oldKeyBinding)
{
OldKeyBinding = oldKeyBinding;
Command = command;
@@ -112,12 +129,12 @@ namespace MonoDevelop.Components.Commands
get; private set;
}
- public string OldKeyBinding {
+ public KeyBinding OldKeyBinding {
get; private set;
}
- public string NewKeyBinding {
- get { return Command.AccelKey; }
+ public KeyBinding NewKeyBinding {
+ get { return Command.KeyBinding; }
}
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs
index 1f1aa85d2a..8dcfef6051 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs
@@ -35,6 +35,7 @@ using System.Collections.Generic;
using MonoDevelop.Components.Commands.ExtensionNodes;
using Mono.TextEditor;
using Mono.Addins;
+using MonoDevelop.Core;
namespace MonoDevelop.Components.Commands
{
@@ -47,6 +48,7 @@ namespace MonoDevelop.Components.Commands
uint statusUpdateWait = 500;
DateTime lastUserInteraction;
KeyboardShortcut[] chords;
+ string chord;
Dictionary<object,Command> cmds = new Dictionary<object,Command> ();
Hashtable handlerInfo = new Hashtable ();
@@ -251,6 +253,20 @@ namespace MonoDevelop.Components.Commands
return cset;
}
+ bool isEnabled = true;
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the command manager is enabled. When disabled, all commands are disabled.
+ /// </summary>
+ public bool IsEnabled {
+ get {
+ return isEnabled;
+ }
+ set {
+ isEnabled = value;
+ }
+ }
+
bool CanUseBinding (KeyboardShortcut[] chords, KeyboardShortcut[] accels, out KeyBinding binding)
{
if (chords != null) {
@@ -265,11 +281,11 @@ namespace MonoDevelop.Components.Commands
foreach (var accel in accels) {
if (bindings.ChordExists (accel)) {
// Chords take precedence over bindings with the same shortcut.
- binding = new KeyBinding (null, accel);
+ binding = new KeyBinding (accel);
continue;
}
- binding = new KeyBinding (null, accel);
+ binding = new KeyBinding (accel);
if (bindings.BindingExists (binding))
return true;
}
@@ -280,19 +296,7 @@ namespace MonoDevelop.Components.Commands
return false;
}
- bool isEnabled = true;
-
- /// <summary>
- /// Gets or sets a value indicating whether the command manager is enabled. When disabled, all commands are disabled.
- /// </summary>
- public bool IsEnabled {
- get {
- return isEnabled;
- }
- set {
- isEnabled = value;
- }
- }
+ public event EventHandler<KeyBindingFailedEventArgs> KeyBindingFailed;
[GLib.ConnectBefore]
void OnKeyPressed (object o, Gtk.KeyPressEventArgs e)
@@ -318,13 +322,29 @@ namespace MonoDevelop.Components.Commands
commands = bindings.Commands (binding);
e.RetVal = true;
chords = null;
+ chord = null;
} else if (bindings.AnyChordExists (accels)) {
+ chord = KeyBindingManager.AccelLabelFromKey (e.Event);
e.RetVal = true;
chords = accels;
return;
+ } else if (chords != null) {
+ // Note: The user has entered a valid chord but the accel was invalid.
+ if (KeyBindingFailed != null) {
+ string accel = KeyBindingManager.AccelLabelFromKey (e.Event);
+
+ KeyBindingFailed (this, new KeyBindingFailedEventArgs (GettextCatalog.GetString ("The key combination ({0}, {1}) is not a command.", chord, accel)));
+ }
+
+ e.RetVal = true;
+ chords = null;
+ chord = null;
+ return;
} else {
e.RetVal = false;
chords = null;
+ chord = null;
+
NotifyKeyPressed (e);
return;
}
@@ -2241,5 +2261,15 @@ namespace MonoDevelop.Components.Commands
public Gdk.Key Key { get; internal set; }
public Gdk.ModifierType Modifiers { get; internal set; }
}
+
+ public class KeyBindingFailedEventArgs : EventArgs
+ {
+ public string Message { get; private set; }
+
+ public KeyBindingFailedEventArgs (string message)
+ {
+ Message = message;
+ }
+ }
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs
index 5fd3b43680..78c078b119 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs
@@ -213,6 +213,13 @@ namespace MonoDevelop.Components.Commands
return accel + KeyToString (shortcuts[0].Key);
}
+ public static string AccelLabelFromKey (Gdk.EventKey raw)
+ {
+ bool complete;
+
+ return AccelLabelFromKey (raw, out complete);
+ }
+
static string AccelLabelFromKey (Gdk.Key key, Gdk.ModifierType modifier, out bool complete)
{
string accel = ModifierToString (modifier);
@@ -395,14 +402,14 @@ namespace MonoDevelop.Components.Commands
public static string BindingToDisplayLabel (KeyBinding binding, bool concise)
{
- string label = string.Empty;
-
- if (binding.Chord != null)
- label += ModifierToDisplayLabel (binding.Chord.Modifier, concise) + KeyToDisplayLabel (binding.Chord.Key) + (isMac ? " " : "|");
+ string label;
- label += ModifierToDisplayLabel (binding.Accel.Modifier, concise) + KeyToDisplayLabel (binding.Accel.Key);
+ if (!binding.Chord.IsEmpty)
+ label = ModifierToDisplayLabel (binding.Chord.Modifier, concise) + KeyToDisplayLabel (binding.Chord.Key) + (isMac ? " " : "|");
+ else
+ label = string.Empty;
- return label;
+ return label + ModifierToDisplayLabel (binding.Accel.Modifier, concise) + KeyToDisplayLabel (binding.Accel.Key);
}
static string KeyToDisplayLabel (Gdk.Key key)
@@ -489,6 +496,8 @@ namespace MonoDevelop.Components.Commands
if ((mod = ModifierMask (str)) == Gdk.ModifierType.None) {
if (str.Length > 1)
key = (Gdk.Key) Gdk.Key.Parse (typeof (Gdk.Key), str);
+ else if (str[0] >= 'a' && str[0] <= 'z')
+ key = (Gdk.Key) str[0] - 32;
else
key = (Gdk.Key) str[0];
@@ -595,14 +604,14 @@ namespace MonoDevelop.Components.Commands
if (ChordChanged (oldKeyBinding, newKeyBinding)) {
// keep track of valid modes
- if (oldKeyBinding != null && oldKeyBinding.Chord != null) {
+ if (oldKeyBinding != null && !oldKeyBinding.Chord.IsEmpty) {
if ((refs = chords[oldKeyBinding.Chord] - 1) == 0)
chords.Remove (oldKeyBinding.Chord);
else
chords[oldKeyBinding.Chord] = refs;
}
- if (newKeyBinding != null && newKeyBinding.Chord != null) {
+ if (newKeyBinding != null && !newKeyBinding.Chord.IsEmpty) {
if (!chords.ContainsKey (newKeyBinding.Chord))
chords.Add (newKeyBinding.Chord, 1);
else
@@ -631,20 +640,6 @@ namespace MonoDevelop.Components.Commands
}
}
- void SetBinding (Command command, string oldBinding, string newBinding)
- {
- KeyBinding oldKeyBinding;
- KeyBinding newKeyBinding;
-
- if (!KeyBinding.TryParse (oldBinding, out oldKeyBinding))
- oldKeyBinding = null;
-
- if (!KeyBinding.TryParse (newBinding, out newKeyBinding))
- newKeyBinding = null;
-
- SetBinding (command, oldKeyBinding, newKeyBinding);
- }
-
void OnKeyBindingChanged (object o, KeyBindingChangedEventArgs args)
{
SetBinding (args.Command, args.OldKeyBinding, args.NewKeyBinding);
@@ -662,7 +657,7 @@ namespace MonoDevelop.Components.Commands
return;
}
- SetBinding (command, null, command.AccelKey);
+ SetBinding (command, null, command.KeyBinding);
command.KeyBindingChanged += OnKeyBindingChanged;
commands.Add (command);
}
@@ -680,23 +675,19 @@ namespace MonoDevelop.Components.Commands
command.KeyBindingChanged -= OnKeyBindingChanged;
commands.Remove (command);
- if (string.IsNullOrEmpty (command.AccelKey))
- return;
-
- KeyBinding binding;
- if (!KeyBinding.TryParse (command.AccelKey, out binding))
+ if (command.KeyBinding == null)
return;
- list = bindings[binding];
+ list = bindings[command.KeyBinding];
list.Remove (command);
if (list.Count == 0)
- bindings.Remove (binding);
+ bindings.Remove (command.KeyBinding);
- if (binding.Chord != null && chords.ContainsKey (binding.Chord)) {
- if ((refs = chords[binding.Chord] - 1) == 0)
- chords.Remove (binding.Chord);
+ if (!command.KeyBinding.Chord.IsEmpty && chords.ContainsKey (command.KeyBinding.Chord)) {
+ if ((refs = chords[command.KeyBinding.Chord] - 1) == 0)
+ chords.Remove (command.KeyBinding.Chord);
else
- chords[binding.Chord] = refs;
+ chords[command.KeyBinding.Chord] = refs;
}
}
@@ -705,7 +696,7 @@ namespace MonoDevelop.Components.Commands
///
public List<Command> Commands (KeyBinding binding)
{
- if (!BindingExists (binding))
+ if (binding == null || !BindingExists (binding))
return null;
return bindings[binding];
@@ -857,7 +848,7 @@ namespace MonoDevelop.Components.Commands
#endregion
}
- public class KeyBinding
+ public class KeyBinding : IEquatable<KeyBinding>
{
public KeyBinding (KeyboardShortcut chord, KeyboardShortcut accel)
{
@@ -865,6 +856,12 @@ namespace MonoDevelop.Components.Commands
Accel = accel;
}
+ public KeyBinding (KeyboardShortcut accel)
+ {
+ Chord = KeyboardShortcut.Empty;
+ Accel = accel;
+ }
+
public static bool TryParse (string str, out KeyBinding binding)
{
Gdk.ModifierType chordModifier;
@@ -877,13 +874,8 @@ namespace MonoDevelop.Components.Commands
return false;
}
+ KeyboardShortcut chord = new KeyboardShortcut ((Gdk.Key) chordKey, chordModifier);
KeyboardShortcut accel = new KeyboardShortcut ((Gdk.Key) key, modifier);
- KeyboardShortcut chord;
-
- if (chordKey != 0)
- chord = new KeyboardShortcut ((Gdk.Key) chordKey, chordModifier);
- else
- chord = null;
binding = new KeyBinding (chord, accel);
@@ -900,35 +892,26 @@ namespace MonoDevelop.Components.Commands
public override int GetHashCode ()
{
- int code = Accel.GetHashCode ();
-
- if (Chord != null)
- return Chord.GetHashCode () ^ code;
-
- return code;
+ return Chord.GetHashCode () ^ Accel.GetHashCode ();
}
public override bool Equals (object obj)
{
- KeyBinding binding = obj as KeyBinding;
-
- if (binding == null)
- return false;
-
- if (Chord == null)
- return binding.Chord == null && Accel.Equals (binding.Accel);
-
- if (binding.Chord == null)
- return false;
-
- return Chord.Equals (binding.Chord) && Accel.Equals (binding.Accel);
+ return obj is KeyBinding && Equals ((KeyBinding) obj);
}
+ #region IEquatable[KeyBinding] implementation
+ public bool Equals (KeyBinding other)
+ {
+ return Chord.Equals (other.Chord) && Accel.Equals (other.Accel);
+ }
+ #endregion
+
public override string ToString ()
{
string chord;
- if (Chord != null)
+ if (!Chord.IsEmpty)
chord = KeyBindingManager.AccelLabelFromKey (Chord.Key, Chord.Modifier) + "|";
else
chord = string.Empty;
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
index 2b44b55cfd..14aeb99283 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
@@ -151,6 +151,7 @@ namespace MonoDevelop.Ide
commandService.CommandTargetScanStarted += CommandServiceCommandTargetScanStarted;
commandService.CommandTargetScanFinished += CommandServiceCommandTargetScanFinished;
+ commandService.KeyBindingFailed += KeyBindingFailed;
KeyBindingService.LoadBindingsFromExtensionPath ("/MonoDevelop/Ide/KeyBindingSchemes");
KeyBindingService.LoadCurrentBindings ("MD2");
@@ -279,6 +280,11 @@ namespace MonoDevelop.Ide
};
AutoTestService.NotifyEvent ("MonoDevelop.Ide.IdeStart");
}
+
+ static void KeyBindingFailed (object sender, KeyBindingFailedEventArgs e)
+ {
+ Ide.IdeApp.Workbench.StatusBar.ShowMessage (e.Message);
+ }
//this method is MIT/X11, 2009, Michael Hutchinson / (c) Novell
public static void OpenFiles (IEnumerable<FileOpenInformation> files)