diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo
index 8e19d5a9609..ac06e9d1f00 100644
Binary files a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/StringResources.resx b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/StringResources.resx
index d57792d8378..7f6d85f8edd 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/StringResources.resx
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/StringResources.resx
@@ -140,4 +140,31 @@
Uncategorized
+
+ First chord must have a modifier
+
+
+ Valid gesture
+
+
+ Multi key gesture is not finished
+
+
+ Invalid gesture. Sequence is not coherent.
+
+
+ Time given for gesture entry expired
+
+
+ Failed to add a gesture. First chord should contain a modifier
+
+
+ Failed to add a gesture. Gesture is unfinished. Last chord should have a key
+
+
+ Failed to add a gesture. Gesture must have atleast one chord
+
+
+ Gesture added
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db
index 935d92f604f..b3cac4ddc5a 100644
Binary files a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/block_small.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/block_small.png
new file mode 100644
index 00000000000..cea7cd0f773
Binary files /dev/null and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/block_small.png differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/delete_small.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/delete_small.png
new file mode 100644
index 00000000000..c3134399aeb
Binary files /dev/null and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/delete_small.png differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/info_small.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/info_small.png
new file mode 100644
index 00000000000..2794af30db5
Binary files /dev/null and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/info_small.png differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/plus_small.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/plus_small.png
new file mode 100644
index 00000000000..c78afd1d534
Binary files /dev/null and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/plus_small.png differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/search_small.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/search_small.png
new file mode 100644
index 00000000000..e930b6cad72
Binary files /dev/null and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/search_small.png differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/tick_small.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/tick_small.png
new file mode 100644
index 00000000000..abc312f1862
Binary files /dev/null and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/tick_small.png differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/warning_small.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/warning_small.png
new file mode 100644
index 00000000000..86668e4e07a
Binary files /dev/null and b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/warning_small.png differ
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.addin b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.addin
index 35d4e939c74..642c86ced5f 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.addin
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.addin
@@ -14,6 +14,6 @@
+ class = "ICSharpCode.ShortcutsManagement.Dialogs.ShortcutsManagementOptionsPanel" />
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj
index 7428dac0ac9..44f9d76e0ac 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj
@@ -62,6 +62,8 @@
3.5
+
+
3.5
@@ -88,6 +90,10 @@
MSBuild:Compile
Designer
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -142,11 +148,14 @@
Settings.settings
True
+
-
+
+ MultiKeyGestureTextBox.xaml
+
ShortcutManagementWindow.xaml
@@ -157,6 +166,7 @@
ShortcutsTreeView.xaml
+
@@ -176,6 +186,13 @@
+
+
+
+
+
+
+
Always
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/BoolToVisibilityConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/BoolToVisibilityConverter.cs
index f9e3f8719f9..b7bdf4df198 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/BoolToVisibilityConverter.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/BoolToVisibilityConverter.cs
@@ -26,12 +26,12 @@ public object Convert(object value, Type targetType, object parameter, CultureIn
return (bool)value ? "Visible" : hidden;
}
- throw new NotImplementedException();
+ throw new NotSupportedException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
- throw new NotImplementedException();
+ throw new NotSupportedException();
}
}
}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesCollectionConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesCollectionConverter.cs
index dec24891388..a9439c878fa 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesCollectionConverter.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesCollectionConverter.cs
@@ -31,7 +31,7 @@ public object Convert(object value, Type targetType, object parameter, CultureIn
foreach (var gesture in (ObservableCollection)value) {
inputGestureCollection.Add(gesture);
}
- return new InputGestureCollectionConverter().ConvertToInvariantString(inputGestureCollection).Replace("|", " | ");
+ return new InputGestureCollectionConverter().ConvertToInvariantString(inputGestureCollection);
}
return value.ToString();
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/InputGestureConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/InputGestureConverter.cs
index 908e7c3a685..d8431a8f844 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/InputGestureConverter.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/InputGestureConverter.cs
@@ -2,6 +2,7 @@
using System.Globalization;
using System.Windows.Data;
using System.Windows.Input;
+using ICSharpCode.Core.Presentation;
namespace ICSharpCode.ShortcutsManagement.Converters
{
@@ -20,6 +21,11 @@ public class InputGestureConverter : IValueConverter
///
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
+ if (value is MultiKeyGesture && targetType == typeof(string))
+ {
+ return new MultiKeyGestureConverter().ConvertToInvariantString(value).Replace("+", " + ");
+ }
+
if(value is KeyGesture && targetType == typeof(string))
{
return new KeyGestureConverter().ConvertToInvariantString(value).Replace("+", " + ");
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs
index 92837eec28b..9a7f7010d0b 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.ComponentModel;
namespace ICSharpCode.ShortcutsManagement.Data
@@ -73,17 +72,6 @@ public AddIn(string addInName)
Categories = new List();
}
- ///
- /// Invoke dependency property changed event
- ///
- /// Name of dependency property from this classs
- private void InvokePropertyChanged(string propertyName)
- {
- if (PropertyChanged != null) {
- PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-
///
/// Find shortcut by shortcutId in add-in categories
///
@@ -115,6 +103,9 @@ public object Clone()
return clonedAddIn;
}
+ ///
+ /// Sort add-in sub categories
+ ///
public void SortSubEntries()
{
Categories.Sort((a, b) => a.Name.CompareTo(b.Name));
@@ -129,12 +120,29 @@ public void SortSubEntries()
///
public event PropertyChangedEventHandler PropertyChanged;
+ ///
+ /// Compare add-in to other instances of
+ ///
+ /// Compared object
+ /// Comparison result
public int CompareTo(object obj) {
if (obj is ShortcutCategory) return 1;
if (obj is Shortcut) return 1;
var addInObj = (AddIn)obj;
return Name.CompareTo(addInObj.Name);
- }
+ }
+
+ ///
+ /// Invoke dependency property changed event
+ ///
+ /// Name of dependency property from this classs
+ private void InvokePropertyChanged(string propertyName)
+ {
+ if (PropertyChanged != null)
+ {
+ PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
}
}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/GestureFilterMode.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/GestureFilterMode.cs
new file mode 100644
index 00000000000..e23ea03b8ef
--- /dev/null
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/GestureFilterMode.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ICSharpCode.ShortcutsManagement.Data
+{
+ ///
+ /// Gesture filtering mode
+ ///
+ public enum GestureFilterMode
+ {
+ ///
+ /// Match is successful if template gesture strictly matches compared gesture
+ ///
+ StrictlyMatches,
+
+ ///
+ /// Match is successfull if template gesture partly matches compared geture.
+ /// Template is found in any place within matched gesture
+ ///
+ PartlyMatches,
+
+ ///
+ /// match is successfull if matched gesture starts with provided template
+ ///
+ StartsWith
+ }
+}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/IShortcutTreeEntry.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/IShortcutTreeEntry.cs
index 4c8b1e446a9..da6532d5006 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/IShortcutTreeEntry.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/IShortcutTreeEntry.cs
@@ -1,24 +1,35 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace ICSharpCode.ShortcutsManagement.Data
{
public interface IShortcutTreeEntry : IComparable, ICloneable
{
+ ///
+ /// Shortcut entry name displayed in shortcuts tree
+ ///
string Name
{
get; set;
}
+ ///
+ /// Specifies whether shortcut tree entry is visible
+ ///
bool IsVisible
{
get; set;
}
+ ///
+ /// Sort shortcut entry sub elements
+ ///
void SortSubEntries();
+ ///
+ /// Search for shortcut in this shortcut entry and sub-elements
+ ///
+ ///
+ ///
Shortcut FindShortcut(string shortcutId);
}
}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/KeyGestureTemplate.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/KeyGestureTemplate.cs
deleted file mode 100644
index 3aec34d4426..00000000000
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/KeyGestureTemplate.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-using System;
-using System.Text;
-using System.Windows.Input;
-
-namespace ICSharpCode.ShortcutsManagement.Data
-{
- ///
- /// Describes full key gesture or part of key gesture
- ///
- public class KeyGestureTemplate
- {
- ///
- /// Gets the key associated with key gesture template
- ///
- public Key Key
- {
- get;
- private set;
- }
-
- ///
- /// Get modifier keys associated with key gesture template
- ///
- public ModifierKeys Modifiers
- {
- get;
- private set;
- }
-
- ///
- /// Create new instance of from
- ///
- /// Arguments generated by key event
- public KeyGestureTemplate(KeyEventArgs keyEventArgs)
- {
- var keyboardDevice = (KeyboardDevice)keyEventArgs.Device;
-
- Key = keyEventArgs.Key;
- Modifiers = keyboardDevice.Modifiers;
- }
-
- ///
- /// Create new instance of key gesture template from key gesture
- ///
- /// Key gesture
- public KeyGestureTemplate(KeyGesture gesture)
- {
- Key = gesture.Key;
- Modifiers = gesture.Modifiers;
- }
-
- ///
- /// Create new instance of key gesture template from key and modifiers
- ///
- /// The key associated with key gesture template
- /// Modifier keys associated with key gesture template
- public KeyGestureTemplate(Key key, ModifierKeys modifiers)
- {
- Key = key;
- Modifiers = modifiers;
- }
-
- ///
- /// Create key gesture template from key only (without modifiers)
- ///
- /// The key associated with key gesture template
- public KeyGestureTemplate(Key key)
- {
- Key = key;
- Modifiers = ModifierKeys.None;
- }
-
- ///
- /// Determines whether key gesture matches this key gesture template
- ///
- /// Key gesture
- /// If true both modifiers and key should match. Otherwice gesture matches to template if template describe only part of shortcut
- ///
- public bool Matches(KeyGesture gesture, bool strictMatch)
- {
- if(strictMatch) {
- return Key == gesture.Key && Modifiers == gesture.Modifiers;
- }
-
- var keyMatches = Key == gesture.Key;
-
- // Determine whether template contains only part of modifier keys contained in
- // gesture. For example if template contains Control modifier, but gesture contains
- // Control and Alt true will be returned
- var modifierMatches = gesture.Modifiers - (gesture.Modifiers ^ Modifiers) >= 0;
-
- // Template contains no modifiers compare only keys
- if (Modifiers == ModifierKeys.None) {
- return keyMatches;
- }
-
- // If template has modifiers but key is one of modifier keys return true if
- // modifiers match. This is used because when user presses modifier key it is
- // presented in Key property and Modifiers property
- if (Array.IndexOf(new[] { Key.LeftAlt, Key.RightAlt,
- Key.LeftShift, Key.RightShift,
- Key.LeftCtrl, Key.RightCtrl,
- Key.LWin, Key.RWin,
- Key.System}, Key) >= 0) {
- return modifierMatches;
- }
-
- return modifierMatches && keyMatches;
- }
-
- public bool MatchesCollection(InputGestureCollection gestures, bool strictMatch)
- {
- foreach (InputGesture gesture in gestures)
- {
- if(gesture is KeyGesture && Matches((KeyGesture)gesture, strictMatch))
- {
- return true;
- }
- }
-
- return false;
- }
-
- ///
- /// Returns string that represents
- ///
- /// String
- public override string ToString()
- {
- var pressedButton = new StringBuilder();
-
- // Display modifier
- if ((Modifiers & ModifierKeys.Control) > 0)
- {
- pressedButton.Append("Ctrl + ");
- }
- if ((Modifiers & ModifierKeys.Windows) > 0)
- {
- pressedButton.Append("Windows + ");
- }
- if ((Modifiers & ModifierKeys.Alt) > 0)
- {
- pressedButton.Append("Alt + ");
- }
- if ((Modifiers & ModifierKeys.Shift) > 0)
- {
- pressedButton.Append("Shift + ");
- }
-
- // Filter modifier keys from being displayed twice (example: Control + LeftCtrl)
- if (Array.IndexOf(new[] { Key.LeftAlt, Key.RightAlt,
- Key.LeftShift, Key.RightShift,
- Key.LeftCtrl, Key.RightCtrl,
- Key.LWin, Key.RWin,
- Key.System}, Key) < 0)
- {
- pressedButton.Append(new KeyConverter().ConvertToInvariantString(Key));
- }
-
- return pressedButton.ToString();
- }
- }
-}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs
index fea01099784..6be150bf0b1 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs
@@ -79,6 +79,11 @@ public bool IsVisible
}
}
+ ///
+ /// Notify observers about property changes
+ ///
+ public event PropertyChangedEventHandler PropertyChanged;
+
///
/// Create new instance of shortcut
///
@@ -143,23 +148,10 @@ public object Clone()
}
///
- /// Invoke dependency property changed event
- ///
- /// Name of dependency property from this classs
- private void InvokePropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-
- ///
- /// Notify observers about property changes
+ /// Compare shortcut to other instances of
///
- public event PropertyChangedEventHandler PropertyChanged;
-
-
+ /// Compared object
+ /// Comparison result
public int CompareTo(object obj)
{
if (obj is AddIn) return -1;
@@ -169,8 +161,25 @@ public int CompareTo(object obj)
return Name.CompareTo(shortcutObj.Name);
}
+ ///
+ /// Returns this instance if searched id matches
+ ///
+ /// Searched shortcut id
+ /// Found shortcut instance or null
public Shortcut FindShortcut(string shortcutId) {
return Id == shortcutId ? this : null;
}
+
+ ///
+ /// Invoke dependency property changed event
+ ///
+ /// Name of dependency property from this classs
+ private void InvokePropertyChanged(string propertyName)
+ {
+ if (PropertyChanged != null)
+ {
+ PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
}
}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs
index 3d1cf2f5093..371536cd6bf 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.ComponentModel;
namespace ICSharpCode.ShortcutsManagement.Data
@@ -72,6 +71,11 @@ public List Shortcuts
private set;
}
+ ///
+ /// Notify observers about property changes
+ ///
+ public event PropertyChangedEventHandler PropertyChanged;
+
///
/// Create new instance of category
///
@@ -103,6 +107,9 @@ public object Clone()
return clonedCategory;
}
+ ///
+ /// Sort category shortcuts
+ ///
public void SortSubEntries()
{
SubCategories.Sort((a, b) => a.Name.CompareTo(b.Name));
@@ -140,21 +147,10 @@ public Shortcut FindShortcut(string shortcutId)
}
///
- /// Invoke dependency property changed event
+ /// Compare shortcut category to other instances of
///
- /// Name of dependency property from this classs
- private void InvokePropertyChanged(string propertyName)
- {
- if (PropertyChanged != null) {
- PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-
- ///
- /// Notify observers about property changes
- ///
- public event PropertyChangedEventHandler PropertyChanged;
-
+ /// Compared object
+ /// Comparison result
public int CompareTo(object obj)
{
if (obj is AddIn) return -1;
@@ -163,5 +159,17 @@ public int CompareTo(object obj)
var categoryObj = (ShortcutCategory)obj;
return Name.CompareTo(categoryObj.Name);
}
+
+ ///
+ /// Invoke dependency property changed event
+ ///
+ /// Name of dependency property from this classs
+ private void InvokePropertyChanged(string propertyName)
+ {
+ if (PropertyChanged != null)
+ {
+ PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
}
}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsFinder.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsFinder.cs
index 28574e9ad9a..eedca764833 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsFinder.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsFinder.cs
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Windows.Input;
+using ICSharpCode.Core.Presentation;
+using ICSharpCode.ShortcutsManagement.Extensions;
namespace ICSharpCode.ShortcutsManagement.Data
{
@@ -94,31 +97,32 @@ private static bool HideShortcut(ShortcutCategory category, Shortcut filteredSho
///
/// Hides add-ins and sub-categories if there are no sub-elements left
///
- /// Gesture template (Uncompleted gesture)
- /// If false filter gestures which with only partial match
- public void FilterGesture(KeyGestureTemplate keyGestureTemplate, bool strictMatch)
+ /// Gesture template which should match shortcut gesture partly to make it visible
+ /// Filtering mode
+ public void FilterGesture(InputGesture inputGestureTemplate, GestureFilterMode mode)
{
- FilterGesture(new List { keyGestureTemplate }, strictMatch);
+ FilterGesture(new InputGestureCollection(new[] { inputGestureTemplate }), mode);
}
///
- /// Filter gestures matching provided key gesture template
+ /// Filter gestures matching one of provided gesture templates
///
/// Hides add-ins and sub-categories if there are no sub-elements left
///
- /// Gesture templates collection (Uncompleted gestures)
- /// If false filter gestures which with only partial match
- public void FilterGesture(ICollection keyGestureTemplateCollection, bool strictMatch)
+ /// Collection of gesture templates which (atleast one) should match shortcut gesture partly to make it visible
+ /// Filtering mode
+ public void FilterGesture(InputGestureCollection inputGestureTemplateCollection, GestureFilterMode mode)
{
+ Debug.WriteLine("Changed to" + new InputGestureCollectionConverter().ConvertToInvariantString(inputGestureTemplateCollection));
foreach (var entry in RootEntries)
{
var subCategoryIsVisible = false;
+ // Filter root addin and sub-elements
var rootAddIn = entry as AddIn;
- if (rootAddIn != null)
- {
+ if (rootAddIn != null) {
foreach (var category in rootAddIn.Categories) {
- if (FilterGesture(category, keyGestureTemplateCollection, strictMatch)) {
+ if (FilterGesture(category, inputGestureTemplateCollection, mode)) {
subCategoryIsVisible = true;
}
}
@@ -127,16 +131,18 @@ public void FilterGesture(ICollection keyGestureTemplateColl
rootAddIn.IsVisible = subCategoryIsVisible;
}
+ // Filter root category and sub-elements
var rootCategory = entry as ShortcutCategory;
if (rootCategory != null) {
- FilterGesture(rootCategory, keyGestureTemplateCollection, strictMatch);
+ FilterGesture(rootCategory, inputGestureTemplateCollection, mode);
}
+ // Filter root shortcut
var rootShortcut = entry as Shortcut;
if (rootShortcut != null) {
rootShortcut.IsVisible = false;
- foreach (var template in keyGestureTemplateCollection) {
- if (template.MatchesCollection(new InputGestureCollection(rootShortcut.Gestures), strictMatch)) {
+ foreach (InputGesture template in inputGestureTemplateCollection) {
+ if (template.MatchesCollection(new InputGestureCollection(rootShortcut.Gestures), mode)) {
rootShortcut.IsVisible = true;
break;
}
@@ -146,17 +152,19 @@ public void FilterGesture(ICollection keyGestureTemplateColl
}
///
- /// Filter gestures matching one of provided key gesture templates from templates collection
+ /// Filter gestures matching one of provided gesture templates from templates collection
///
/// Category to filter
- /// Gesture templates collection (Uncompleted gestures)
+ /// Collection of gesture templates which (atleast one) should match shortcut gesture partly to make it visible
+ /// Filtering mode
///
- private static bool FilterGesture(ShortcutCategory category, IEnumerable keyGestureTemplateCollection, bool strictMatch)
+ private static bool FilterGesture(ShortcutCategory category, InputGestureCollection inputGestureTemplateCollection, GestureFilterMode mode)
{
// Apply filter to sub-categories
var isSubElementVisible = false;
foreach (var subCategory in category.SubCategories) {
- if (FilterGesture(subCategory, keyGestureTemplateCollection, strictMatch)) {
+ if (FilterGesture(subCategory, inputGestureTemplateCollection, mode))
+ {
isSubElementVisible = true;
}
}
@@ -164,8 +172,15 @@ private static bool FilterGesture(ShortcutCategory category, IEnumerable 0 && ((KeyGesture)shortcut.Gestures[0]).Key == Key.F5)
+ {
+
+ }
+
+ if (template.MatchesCollection(new InputGestureCollection(shortcut.Gestures), mode))
+ {
gestureMatched = true;
break;
}
@@ -221,7 +236,7 @@ public void Filter(string filterString)
var rootShortcut = entry as Shortcut;
if (rootShortcut != null) {
- rootShortcut.IsVisible = rootShortcut.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0;
+ rootShortcut.IsVisible = filterString == null || rootShortcut.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0;
}
}
}
@@ -252,7 +267,8 @@ private static bool Filter(ShortcutCategory category, string filterString, bool?
// Filter shortcuts which text match the filter
foreach (var shortcut in category.Shortcuts) {
- if ((forseMatch.HasValue && forseMatch.Value) || shortcut.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0) {
+ if ((forseMatch.HasValue && forseMatch.Value) || filterString == null || shortcut.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0)
+ {
shortcut.IsVisible = true;
isSubElementVisible = true;
}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/MultiKeyGestureTextBox.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/MultiKeyGestureTextBox.xaml
new file mode 100644
index 00000000000..869f1a22b18
--- /dev/null
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/MultiKeyGestureTextBox.xaml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/MultiKeyGestureTextBox.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/MultiKeyGestureTextBox.xaml.cs
new file mode 100644
index 00000000000..fa20bc82bc6
--- /dev/null
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/MultiKeyGestureTextBox.xaml.cs
@@ -0,0 +1,305 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using ICSharpCode.Core;
+using ICSharpCode.Core.Presentation;
+
+namespace ICSharpCode.ShortcutsManagement.Dialogs
+{
+ ///
+ /// Notification type enumeration
+ ///
+ public enum NotificationType
+ {
+ ///
+ /// A valid gesture is entered so far
+ ///
+ Valid,
+
+ ///
+ /// Gesture is being entered, but is not valid yet
+ ///
+ Invalid,
+
+ ///
+ /// Gesture was successfully added to gestures collection
+ ///
+ Added,
+
+ ///
+ /// Failed to add gesture to gestures collection
+ ///
+ Failed,
+
+ ///
+ /// Notification message is not displayed
+ ///
+ None
+ }
+
+ ///
+ /// Represents a textbox suited for entering key gestures
+ ///
+ public partial class MultiKeyGestureTextBox : UserControl
+ {
+ ///
+ /// Identifies dependency property
+ ///
+ public static readonly DependencyProperty TextBoxBorderThicknessProperty = DependencyProperty.Register(
+ "TextBoxBorderThickness",
+ typeof(int),
+ typeof(MultiKeyGestureTextBox),
+ new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.AffectsRender));
+
+ ///
+ /// Specifies text box border thickness
+ ///
+ public int TextBoxBorderThickness
+ {
+ get {
+ return (int)GetValue(TextBoxBorderThicknessProperty);
+ }
+ set {
+ SetValue(TextBoxBorderThicknessProperty, value);
+ }
+ }
+
+ ///
+ /// Key gesture entered in text box
+ ///
+ public KeyGesture Gesture
+ {
+ get {
+ if (enteredKeyGestureSequence == null || enteredKeyGestureSequence.Count == 0) {
+ return null;
+ }
+
+ if (enteredKeyGestureSequence.Count == 1) {
+ return enteredKeyGestureSequence.First();
+ }
+
+ return new MultiKeyGesture(enteredKeyGestureSequence);
+ }
+ }
+
+ ///
+ /// Event which is raised when gesture entered in text box changes
+ ///
+ public event EventHandler GestureChanged;
+
+ ///
+ /// Identifies dependency property
+ ///
+ public static readonly DependencyProperty NotificationVisibilityProperty = DependencyProperty.Register(
+ "NotificationVisibility",
+ typeof(Visibility),
+ typeof(MultiKeyGestureTextBox),
+ new FrameworkPropertyMetadata(Visibility.Visible, FrameworkPropertyMetadataOptions.AffectsRender));
+
+ ///
+ /// Whether notifications are displayed under textbox control
+ ///
+ public Visibility NotificationVisibility
+ {
+ get {
+ return (Visibility)GetValue(NotificationVisibilityProperty);
+ }
+ set {
+ SetValue(NotificationVisibilityProperty, value);
+ }
+ }
+
+ ///
+ /// Identifies dependency property
+ ///
+ public static readonly DependencyProperty NotificationTypeProperty = DependencyProperty.Register(
+ "NotificationType",
+ typeof(NotificationType),
+ typeof(MultiKeyGestureTextBox),
+ new FrameworkPropertyMetadata(NotificationType.None, FrameworkPropertyMetadataOptions.AffectsRender));
+
+ ///
+ /// Specifies displayed notification type
+ ///
+ public NotificationType NotificationType
+ {
+ get {
+ return (NotificationType)GetValue(NotificationTypeProperty);
+ }
+ set {
+ SetValue(NotificationTypeProperty, value);
+ }
+ }
+
+ ///
+ /// Identifies dependency property
+ ///
+ public static readonly DependencyProperty NotificationTextProperty = DependencyProperty.Register(
+ "NotificationText",
+ typeof(string),
+ typeof(MultiKeyGestureTextBox),
+ new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
+
+ ///
+ /// Specifies displayed notification text
+ ///
+ public string NotificationText
+ {
+ get {
+ return (string)GetValue(NotificationTextProperty);
+ }
+ set {
+ SetValue(NotificationTextProperty, value);
+ }
+ }
+
+ ///
+ /// Last entered chords
+ ///
+ private readonly List enteredKeyGestureSequence = new List();
+
+ ///
+ /// Time when last successfull chord was entered
+ ///
+ private DateTime lastEnterTime = DateTime.Now;
+
+ ///
+ /// Creates instance of
+ ///
+ public MultiKeyGestureTextBox()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// Displays notifications under gesture text box
+ ///
+ /// Notification text
+ /// Notification type
+ public void DisplayNotification(string notificationText, NotificationType type)
+ {
+ NotificationText = notificationText;
+ NotificationType = type;
+ }
+
+ ///
+ /// Clears all text area, chords and hides notification
+ ///
+ public void Clear()
+ {
+ enteredKeyGestureSequence.Clear();
+ shortcutTextBox.Text = "";
+ DisplayNotification("", NotificationType.None);
+ }
+
+ ///
+ /// Raised when clicked on "Clear" button to the right from gesture text box
+ ///
+ ///
+ ///
+ private void clearTextBox_Click(object sender, RoutedEventArgs e)
+ {
+ Clear();
+ }
+
+
+ ///
+ /// Raised when text inside textbox changes
+ ///
+ /// Sender object
+ /// Event arguments
+ void shortcutTextBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (GestureChanged != null) {
+ GestureChanged.Invoke(sender, new EventArgs());
+ }
+ }
+
+ ///
+ /// Raised before user presses any key inside text box
+ ///
+ /// Sender object
+ /// Event argument
+ private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
+ {
+ e.Handled = true;
+
+ // If a key is holded for a longer time key event is raised repeatedly.
+ // We don't want to handle this kind of events
+ if (e.IsRepeat) {
+ return;
+ }
+
+ // If delete or backspace button is pressed
+ if (e.Key == Key.Back || e.Key == Key.Delete) {
+ Clear();
+ return;
+ }
+
+ // Check whether time given for chord entry haven't expired yet
+ if (DateTime.Now - lastEnterTime > MultiKeyGesture.DelayBetweenGestureInputs) {
+ if (enteredKeyGestureSequence.Count > 0) {
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.GestureTextBox.TimeExpired}"), NotificationType.Invalid);
+ }
+
+ Clear();
+ lastEnterTime = DateTime.Now;
+ }
+
+ var partialKeyGesture = new PartialKeyGesture(e);
+
+ var lastGesture = enteredKeyGestureSequence.Count > 0 ? enteredKeyGestureSequence.LastOrDefault() : null;
+ var isLastGestureComplete = lastGesture != null && lastGesture.Key != Key.None;
+ var isContinuedGesture = lastGesture != null && partialKeyGesture.Modifiers - (partialKeyGesture.Modifiers ^ lastGesture.Modifiers) >= 0;
+
+ // If continuing previous chord
+ if (!isLastGestureComplete && isContinuedGesture)
+ {
+ enteredKeyGestureSequence.RemoveAt(enteredKeyGestureSequence.Count - 1);
+ }
+ // If previous chord is unfinished and second chor is already entered
+ // start from scratch.
+ else if (!isLastGestureComplete)
+ {
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.GestureTextBox.SequenceIsNotCoherent}"), NotificationType.Invalid);
+ Clear();
+ }
+
+ // If successfully finished another chord give more time
+ if (partialKeyGesture.Key != Key.None)
+ {
+ lastEnterTime = DateTime.Now;
+ }
+
+ enteredKeyGestureSequence.Add(partialKeyGesture);
+
+ // Create a multi key gesture if entered more than one chord
+ if (enteredKeyGestureSequence.Count > 0)
+ {
+ var multiKeyGesture = new MultiKeyGesture(enteredKeyGestureSequence);
+ var multiKeyGestureString = new MultiKeyGestureConverter().ConvertToInvariantString(multiKeyGesture);
+ shortcutTextBox.Text = multiKeyGestureString;
+ }
+ else
+ {
+ Clear();
+ }
+
+ if (enteredKeyGestureSequence[0].Modifiers == ModifierKeys.None)
+ {
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.GestureTextBox.FirstChordIsIncomplete}"), NotificationType.Invalid);
+ }
+ else if (partialKeyGesture.Key == Key.None)
+ {
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.GestureTextBox.LastChordIsIncomplete}"), NotificationType.Invalid);
+ }
+ else
+ {
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.GestureTextBox.GestureIsValid}"), NotificationType.Valid);
+ }
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/Resources.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/Resources.xaml
index 0d837dda4b7..a34afe9c19a 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/Resources.xaml
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/Resources.xaml
@@ -8,8 +8,7 @@
-
-
+
@@ -21,7 +20,7 @@
-
+
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml
index 507d2672602..501e44c9268 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml
@@ -1,14 +1,21 @@
-
+ xmlns:Dialogs="clr-namespace:ICSharpCode.ShortcutsManagement.Dialogs"
+ Title="{Binding Text}"
+ MinHeight="400"
+ MinWidth="400"
+ x:Name="_this">
+
+
+
@@ -19,27 +26,27 @@
-
+
-
+
-
-
+
+
-
+
@@ -61,8 +68,8 @@
-
-
+
+
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs
index 28f2305b1a4..bad5a0b1871 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs
@@ -1,13 +1,16 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using ICSharpCode.Core;
+using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop;
using ICSharpCode.ShortcutsManagement.Data;
+using ICSharpCode.ShortcutsManagement.Extensions;
-namespace ICSharpCode.ShortcutsManagement
+namespace ICSharpCode.ShortcutsManagement.Dialogs
{
///
/// This window allows user to modify shortcuts registered in application
@@ -43,11 +46,6 @@ public partial class ShortcutManagementWindow : Window
/// Allways add modified shortcut to this list.
///
private readonly List modifiedShortcuts = new List();
-
- ///
- /// Last entered input gesture
- ///
- private InputGesture lastEnteredInputGesture;
///
/// Initializes new class
@@ -86,17 +84,22 @@ public ShortcutManagementWindow(Shortcut shortcut, ICollection
private void FilterSimilarShortcuts()
{
- var templates = new List();
+ var templates = new InputGestureCollection();
foreach (var gesture in shortcutCopy.Gestures) {
- if (gesture is KeyGesture) {
- templates.Add(new KeyGestureTemplate((KeyGesture)gesture));
+ var multiKeyGestureTemplate = gesture as MultiKeyGesture;
+ if (multiKeyGestureTemplate != null) {
+ if (multiKeyGestureTemplate.Gestures != null && multiKeyGestureTemplate.Gestures.Count > 0) {
+ templates.Add(multiKeyGestureTemplate.Gestures.FirstOrDefault());
+ }
+ } else {
+ templates.Add(gesture);
}
}
// Find shortcuts with same gesture and hide them.
// Also hide modified shortcut from this list
var finder = new ShortcutsFinder(rootEntriesCopy);
- finder.FilterGesture(templates, true);
+ finder.FilterGesture(templates, GestureFilterMode.StartsWith);
finder.HideShortcut(shortcutCopy);
shortcutsManagementOptionsPanel.ExpandAll();
@@ -112,27 +115,6 @@ void Gestures_CollectionChanged(object sender, System.Collections.Specialized.No
{
FilterSimilarShortcuts();
}
-
- ///
- /// Executed when user presses key inside gesture text box.
- ///
- /// Sender object
- /// Event arguments
- private void shortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
- {
- e.Handled = true;
-
- // Get entered key gesture string representation
- shortcutTextBox.Text = new KeyGestureTemplate(e).ToString();
-
- // Accept only valid getures
- lastEnteredInputGesture = null;
- try {
- lastEnteredInputGesture = new KeyGesture(e.Key, Keyboard.Modifiers);
- } catch (NotSupportedException) {
- lastEnteredInputGesture = null;
- }
- }
///
/// Executed when "Remove" button next to gesture is pressed
@@ -152,11 +134,34 @@ private void removeGestureButton_Click(object sender, RoutedEventArgs e)
/// Event arguments
private void addGestureButton_Click(object sender, RoutedEventArgs e)
{
- // Discard duplicate gestures
- if(lastEnteredInputGesture != null && !shortcutCopy.ContainsGesture(lastEnteredInputGesture))
- {
- shortcutCopy.Gestures.Add(lastEnteredInputGesture);
+ // Check if any chords are entered
+ if (gestureTextBox.Gesture == null) {
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.ModificationWindow.AdditionFailedNoChords}"), NotificationType.Failed);
+ return;
+ }
+
+ // Check whether first chord is finished
+ var partialKeyGesture = gestureTextBox.Gesture as PartialKeyGesture;
+ if (partialKeyGesture != null && partialKeyGesture.Modifiers == ModifierKeys.None) {
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.ModificationWindow.AdditionFailedFirstChordIsIncomplete}"), NotificationType.Failed);
+ return;
+ }
+
+ // Check whether last chord is finished
+ var multiKeyGesture = gestureTextBox.Gesture as MultiKeyGesture;
+ if (multiKeyGesture != null && multiKeyGesture.Gestures.Last().Key == Key.None) {
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.ModificationWindow.AdditionFailedLastChordIsIncompete}"), NotificationType.Failed);
+ return;
+ }
+
+ if (partialKeyGesture != null) {
+ var keyGesture = new KeyGesture(partialKeyGesture.Key, partialKeyGesture.Modifiers);
+ shortcutCopy.Gestures.Add(keyGesture);
+ } else {
+ shortcutCopy.Gestures.Add(gestureTextBox.Gesture);
}
+
+ DisplayNotification(StringParser.Parse("${res:ShortcutsManagement.ModificationWindow.AdditionIsSuccessfull}"), NotificationType.Added);
}
///
@@ -170,22 +175,18 @@ private void shortcutsManagementOptionsPanel_RemoveShortcutClick(object sender,
// Remove gestures registered in modified shortcut from deleted shortcut
var removedShortcutGestures = e.RemovedShortcut.Gestures;
- for (int i = removedShortcutGestures.Count - 1; i >= 0; i--)
- {
- foreach (var modifiedInputGesture in shortcutCopy.Gestures)
- {
+ for (int i = removedShortcutGestures.Count - 1; i >= 0; i--) {
+ foreach (var modifiedInputGesture in shortcutCopy.Gestures) {
var modifiedKeyGesture = modifiedInputGesture as KeyGesture;
var removedKeyGesture = removedShortcutGestures[i] as KeyGesture;
if (modifiedKeyGesture != null
- && removedKeyGesture != null
- && modifiedKeyGesture.Key == removedKeyGesture.Key
- && modifiedKeyGesture.Modifiers == removedKeyGesture.Modifiers)
- {
+ && removedKeyGesture != null
+ && modifiedKeyGesture.Key == removedKeyGesture.Key
+ && modifiedKeyGesture.Modifiers == removedKeyGesture.Modifiers) {
removedShortcutGestures.RemoveAt(i);
FilterSimilarShortcuts();
- if (!modifiedShortcuts.Contains(e.RemovedShortcut))
- {
+ if (!modifiedShortcuts.Contains(e.RemovedShortcut)) {
modifiedShortcuts.Add(e.RemovedShortcut);
}
@@ -216,6 +217,17 @@ private void saveButton_Click(object sender, RoutedEventArgs e)
Close();
}
+ ///
+ /// Display message describing shortcut addition result
+ ///
+ /// Displayed message text
+ /// Message type
+ public void DisplayNotification(string notificationText, NotificationType type)
+ {
+ gestureTextBox.NotificationText = notificationText;
+ gestureTextBox.NotificationType = type;
+ }
+
///
/// Execute this method when Reset button is clicked.
///
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml
index fb1ffef194e..5e750a82858 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml
@@ -1,4 +1,4 @@
-
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
index fd7afa3bf65..524244a08c4 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
@@ -9,7 +9,7 @@
using AddIn=ICSharpCode.Core.AddIn;
using ShortcutManagement=ICSharpCode.ShortcutsManagement.Data;
-namespace ICSharpCode.ShortcutsManagement
+namespace ICSharpCode.ShortcutsManagement.Dialogs
{
///
/// Interaction logic for ShortcutsManagementOptionsPanel.xaml
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsTreeView.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsTreeView.xaml
index 2f9195c2bc8..4540c71e0ea 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsTreeView.xaml
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsTreeView.xaml
@@ -5,7 +5,9 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ShortcutsManagement="clr-namespace:ICSharpCode.ShortcutsManagement"
xmlns:Converters="clr-namespace:ICSharpCode.ShortcutsManagement.Converters"
- xmlns:Data="clr-namespace:ICSharpCode.ShortcutsManagement.Data"
+ xmlns:Data="clr-namespace:ICSharpCode.ShortcutsManagement.Data"
+ xmlns:Dialogs="clr-namespace:ICSharpCode.ShortcutsManagement.Dialogs"
+ xmlns:Extensions="clr-namespace:ICSharpCode.ShortcutsManagement.Extensions"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="300" d:DesignWidth="300" >
@@ -31,7 +33,7 @@
-
+
@@ -43,7 +45,7 @@
-
+
@@ -55,9 +57,9 @@
-
+
-
+
@@ -82,8 +84,10 @@
-
-
+
+
+
+
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsTreeView.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsTreeView.xaml.cs
index 828c773403f..a5bc958c6e2 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsTreeView.xaml.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsTreeView.xaml.cs
@@ -4,15 +4,18 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop;
using ICSharpCode.ShortcutsManagement.Data;
+using ICSharpCode.ShortcutsManagement.Dialogs;
+using ICSharpCode.ShortcutsManagement.Extensions;
namespace ICSharpCode.ShortcutsManagement
{
///
/// This panel is used in SharpDevelop options window to manage shortcuts
///
- public partial class ShortcutsTreeView : UserControl, IOptionPanel
+ public partial class ShortcutsTreeView : UserControl
{
///
/// Identifies dependency property
@@ -85,21 +88,20 @@ public ShortcutsTreeView()
InitializeComponent();
}
- private void shortcutEntry_MouseDown(object sender, MouseButtonEventArgs e)
- {
- if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2) {
- if (shortcutsTreeView.SelectedItem is Shortcut) {
- ShowShortcutManagementWindow((Shortcut)shortcutsTreeView.SelectedItem);
- }
- }
- }
-
+ ///
+ /// Display shorcut management window
+ ///
+ /// Shortcut to modify
private void ShowShortcutManagementWindow(Shortcut shortcut)
{
var shortcutManagementWindow = new ShortcutManagementWindow(shortcut, RootEntries);
shortcutManagementWindow.ShowDialog();
}
+ ///
+ /// Select first enabled shortcut in shortcut tree
+ ///
+ /// Set focus to this shortcut entry
public void SelectFirstVisibleShortcut(bool setFocus)
{
var path = new List();
@@ -113,12 +115,16 @@ public void SelectFirstVisibleShortcut(bool setFocus)
}
}
}
-
+ ///
+ /// Find path to first with true
+ ///
+ /// Starting node
+ /// Accumulated path
private void FindFirstVisibleItemPath(IShortcutTreeEntry parent, List path)
{
+ // Find first visible add-in
var addIn = parent as AddIn;
- if(addIn != null)
- {
+ if(addIn != null) {
var selectedCategory = addIn.Categories.FirstOrDefault(a => a.IsVisible);
if (selectedCategory != null) {
path.Add(selectedCategory);
@@ -127,20 +133,19 @@ private void FindFirstVisibleItemPath(IShortcutTreeEntry parent, List a.IsVisible);
- if (selectedCategory != null)
- {
+ if (selectedCategory != null) {
path.Add(selectedCategory);
FindFirstVisibleItemPath(selectedCategory, path);
return;
}
+ // Find first visible shortcut
var selectedShortcut = category.Shortcuts.FirstOrDefault(a => a.IsVisible);
- if (selectedShortcut != null)
- {
+ if (selectedShortcut != null) {
path.Add(selectedShortcut);
FindFirstVisibleItemPath(selectedShortcut, path);
return;
@@ -148,34 +153,14 @@ private void FindFirstVisibleItemPath(IShortcutTreeEntry parent, List
+ /// Expand all elements of the tree
+ ///
public void ExpandAll()
{
shortcutsTreeView.SetExpandAll(true);
}
- #region IOptionPanel
- public void LoadOptions()
- {
- }
-
- public bool SaveOptions()
- {
- return true;
- }
-
- public object Owner
- {
- get; set;
- }
-
- public object Control
- {
- get {
- return this;
- }
- }
- #endregion
-
///
/// Raised when user starts to type inside shortcuts tree
///
@@ -227,6 +212,27 @@ private void searchTextBox_TextChanged(object sender, TextChangedEventArgs e)
}
}
+ ///
+ /// Raised when changing search type
+ ///
+ /// Sender object
+ /// Event arguments
+ private void searchTypeToggleButton_Click(object sender, RoutedEventArgs e)
+ {
+ searchTextBox.Text = "";
+ gestureTextBox.shortcutTextBox.Text = "";
+
+ new ShortcutsFinder(RootEntries).Filter("");
+ shortcutsTreeView.SetExpandAll(false);
+
+ if(!searchTypeToggleButton.IsChecked.HasValue || !searchTypeToggleButton.IsChecked.Value) {
+ Keyboard.Focus(searchTextBox);
+ } else {
+ Keyboard.Focus(gestureTextBox.shortcutTextBox);
+ }
+ }
+
+
///
/// Raised when user presses a key inside search box
///
@@ -248,32 +254,40 @@ private void searchTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
ShowShortcutManagementWindow((Shortcut)shortcutsTreeView.SelectedItem);
return;
}
+ }
+ ///
+ /// Raised if gestures entered in gesture text box change
+ ///
+ /// Senrer object
+ /// Event arguments
+ private void gestureTextBox_GestureChanged(object sender, EventArgs e)
+ {
// Exit if filtering by text (Handled in searchTextBox_TextChanged)
if (searchTypeToggleButton.IsChecked.HasValue && !searchTypeToggleButton.IsChecked.Value) {
return;
}
- // Filter shortcuts with similar gestures assigned and display entered gesture inside search textbox
- var keyGestureTemplate = new KeyGestureTemplate(e.Key, Keyboard.Modifiers);
- new ShortcutsFinder(RootEntries).FilterGesture(keyGestureTemplate, false);
- SelectFirstVisibleShortcut(false);
- searchTextBox.Text = new KeyGestureTemplate(e).ToString();
-
- e.Handled = true;
+ if (gestureTextBox.Gesture != null) {
+ new ShortcutsFinder(RootEntries).FilterGesture(gestureTextBox.Gesture, GestureFilterMode.PartlyMatches);
+ SelectFirstVisibleShortcut(false);
+ } else {
+ new ShortcutsFinder(RootEntries).Filter("");
+ }
}
///
- /// Raised when changing search type
+ /// Raised when user double click on shortcut tree item
///
/// Sender object
/// Event arguments
- private void searchTypeToggleButton_Click(object sender, RoutedEventArgs e)
+ private void shortcutEntry_MouseDown(object sender, MouseButtonEventArgs e)
{
- searchTextBox.Text = "";
-
- new ShortcutsFinder(RootEntries).Filter("");
- shortcutsTreeView.SetExpandAll(false);
+ if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2) {
+ if (shortcutsTreeView.SelectedItem is Shortcut) {
+ ShowShortcutManagementWindow((Shortcut)shortcutsTreeView.SelectedItem);
+ }
+ }
}
}
@@ -291,7 +305,7 @@ public Shortcut RemovedShortcut
{
get;
private set;
- }
+ }
///
/// Constructor
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/PartialKeyGestureExtensions.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/PartialKeyGestureExtensions.cs
new file mode 100644
index 00000000000..9641a37f684
--- /dev/null
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/PartialKeyGestureExtensions.cs
@@ -0,0 +1,140 @@
+using System.Collections.Generic;
+using System.Windows.Input;
+using ICSharpCode.Core.Presentation;
+using ICSharpCode.ShortcutsManagement.Data;
+
+namespace ICSharpCode.ShortcutsManagement.Extensions
+{
+ ///
+ /// extensions
+ ///
+ public static class PartialKeyGestureExtensions
+ {
+ ///
+ /// Returns true whether compared gesture matches input gesture template
+ ///
+ /// Input gesture template
+ /// Compared input gesture
+ /// Match mode
+ /// Returns true if template matches compared geture
+ private static bool IsTemplate(this InputGesture inputGestureTemplate, InputGesture inputGesture, GestureFilterMode mode)
+ {
+ var multiKeyGesture = inputGesture as MultiKeyGesture;
+ var multiKeyGestureTemplate = inputGestureTemplate as MultiKeyGesture;
+ var partialKeyGesture = inputGesture as PartialKeyGesture;
+ var partialKeyGestureTemplate = inputGestureTemplate as PartialKeyGesture;
+ var keyGesture = inputGesture as KeyGesture;
+ var keyGestureTemplate = inputGestureTemplate as KeyGesture;
+
+ // If multi key gesture is matched to a template
+ if (multiKeyGesture != null && keyGestureTemplate != null)
+ {
+ // Make a multi key gesture template out of single key gesture template
+ if(multiKeyGestureTemplate == null)
+ {
+ if (partialKeyGestureTemplate != null)
+ {
+ multiKeyGestureTemplate = new MultiKeyGesture(new List { partialKeyGestureTemplate });
+ }
+ else
+ {
+ partialKeyGestureTemplate = new PartialKeyGesture(keyGestureTemplate);
+ multiKeyGestureTemplate = new MultiKeyGesture(new List {partialKeyGestureTemplate});
+ }
+ }
+
+ // Check for common missmatches
+ if(multiKeyGestureTemplate.Gestures == null
+ || multiKeyGesture.Gestures == null
+ || multiKeyGestureTemplate.Gestures.Count == 0
+ || multiKeyGesture.Gestures.Count == 0
+ || multiKeyGestureTemplate.Gestures.Count > multiKeyGesture.Gestures.Count)
+ {
+ return false;
+ }
+
+ // Stores N previous chords
+ var previousChords = new LinkedList();
+
+ // Search whether chord sequece matches template sequenc in any place
+ foreach (PartialKeyGesture chord in multiKeyGesture.Gestures)
+ {
+ // Accumulates previous chords
+ previousChords.AddLast(chord);
+ if (previousChords.Count > multiKeyGestureTemplate.Gestures.Count)
+ {
+ previousChords.RemoveFirst();
+ }
+
+ // Only start comparing with template when needed amount of previous chords where collected
+ if (previousChords.Count == multiKeyGestureTemplate.Gestures.Count)
+ {
+ var multiKeyGestureTemplateEnumerator = multiKeyGestureTemplate.Gestures.GetEnumerator();
+ var previousChordsEnumerator = previousChords.GetEnumerator();
+
+ multiKeyGestureTemplateEnumerator.Reset();
+
+ // Compare two chord sequences in a loop
+ var multiKeyGesturesMatch = true;
+ while (previousChordsEnumerator.MoveNext() && multiKeyGestureTemplateEnumerator.MoveNext())
+ {
+ if (multiKeyGestureTemplateEnumerator.Current.Modifiers != previousChordsEnumerator.Current.Modifiers
+ || multiKeyGestureTemplateEnumerator.Current.Key != previousChordsEnumerator.Current.Key)
+ {
+ multiKeyGesturesMatch = false;
+ break;
+ }
+ }
+
+ if(multiKeyGesturesMatch)
+ {
+ return true;
+ }
+
+ if (mode == GestureFilterMode.StartsWith)
+ {
+ break;
+ }
+ }
+ }
+ }
+ else if (multiKeyGestureTemplate == null && keyGesture != null && keyGestureTemplate != null)
+ {
+ var gestureModifiers = partialKeyGesture != null ? partialKeyGesture.Modifiers : keyGesture.Modifiers;
+ var gestureKey = partialKeyGesture != null ? partialKeyGesture.Key : keyGesture.Key;
+
+ var templateModifiers = partialKeyGestureTemplate != null ? partialKeyGestureTemplate.Modifiers : keyGestureTemplate.Modifiers;
+ var templateKey = partialKeyGestureTemplate != null ? partialKeyGestureTemplate.Key : keyGestureTemplate.Key;
+
+ if (mode == GestureFilterMode.PartlyMatches)
+ {
+ return (templateModifiers == ModifierKeys.None || templateModifiers == gestureModifiers)
+ && (templateKey == Key.None || templateKey == gestureKey);
+ }
+
+ return templateModifiers == gestureModifiers && templateKey == gestureKey;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Determines whether this instance of matches any of provided templates
+ ///
+ /// This input gesture
+ /// Collection of input gestures templates which (at least one of them) should match this input gesture to return true
+ /// Matching mode
+ /// True if this gsture matches templates collection, otherwise false
+ public static bool MatchesCollection(this InputGesture thisGesture, InputGestureCollection inputGestureTemplateCollection, GestureFilterMode mode)
+ {
+ foreach (InputGesture gesture in inputGestureTemplateCollection) {
+ if (thisGesture.IsTemplate(gesture, mode))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs
index b7818731fde..0224f5f7504 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs
@@ -4,7 +4,7 @@
using System.Windows.Documents;
using System.Windows.Media;
-namespace ICSharpCode.ShortcutsManagement
+namespace ICSharpCode.ShortcutsManagement.Extensions
{
///
/// Contains attached properties
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs
index c79ad73aa07..94e429706f8 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs
@@ -6,10 +6,10 @@
using System.Windows.Controls.Primitives;
using System.Windows.Input;
-namespace ICSharpCode.ShortcutsManagement
+namespace ICSharpCode.ShortcutsManagement.Extensions
{
///
- /// TreeView extention methods
+ /// extention methods
///
public static class TreeViewExtensions
{
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml
index d9d2e0036fb..6171d69a7b5 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml
@@ -1,14 +1,13 @@
-
+
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs
index 45dec338c18..7d3cf81d932 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs
@@ -18,10 +18,11 @@ public Window1()
// Test data
var rootEntries = new ObservableCollection();
-
+
var addin1 = new AddInSection("SharpDevelop");
rootEntries.Add(addin1);
addin1.Categories.Add(new ShortcutCategory("Editing"));
+ addin1.Categories[0].Shortcuts.Add(new Shortcut("MultiKey", GetGestures("Ctrl+C, Ctrl+K")));
addin1.Categories[0].Shortcuts.Add(new Shortcut("Copy", GetGestures("Ctrl + C")));
addin1.Categories[0].Shortcuts.Add(new Shortcut("Paste", GetGestures("Ctrl + V | Ctrl+Insert")));
addin1.Categories[0].Shortcuts.Add(new Shortcut("Cut", GetGestures("Ctrl + X")));