diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo
index 763864d7dc..de3e8c9331 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/ShortcutsManagement.csproj b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj
index aee48ab3ec..3584421c92 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj
@@ -156,6 +156,7 @@
True
+
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs
index 9a7f7010d0..103fc1662a 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs
@@ -126,8 +126,8 @@ namespace ICSharpCode.ShortcutsManagement.Data
/// Compared object
/// Comparison result
public int CompareTo(object obj) {
- if (obj is ShortcutCategory) return 1;
- if (obj is Shortcut) return 1;
+ if (obj is ShortcutCategory) return -1;
+ if (obj is Shortcut) return -1;
var addInObj = (AddIn)obj;
return Name.CompareTo(addInObj.Name);
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/MapTable.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/MapTable.cs
new file mode 100644
index 0000000000..0417812046
--- /dev/null
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/MapTable.cs
@@ -0,0 +1,44 @@
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ICSharpCode.ShortcutsManagement.Data
+{
+ public class MapTable : IEnumerable>
+ {
+ private readonly Dictionary forwardMaping = new Dictionary();
+
+ private readonly Dictionary backwardMaping = new Dictionary();
+
+ public void Add(T1 mappingObject, T2 mappedObject)
+ {
+ forwardMaping.Add(mappingObject, mappedObject);
+ backwardMaping.Add(mappedObject, mappingObject);
+ }
+
+ public T2 MapForward(T1 mappingObject)
+ {
+ return forwardMaping[mappingObject];
+ }
+
+ public T1 MapBackward(T2 mappingObject)
+ {
+ return backwardMaping[mappingObject];
+ }
+
+ public void Clear()
+ {
+ forwardMaping.Clear();
+ backwardMaping.Clear();
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ return forwardMaping.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return forwardMaping.GetEnumerator();
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs
index 59234a91ee..e83e535e56 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs
@@ -159,8 +159,8 @@ namespace ICSharpCode.ShortcutsManagement.Data
/// Comparison result
public int CompareTo(object obj)
{
- if (obj is AddIn) return -1;
- if (obj is ShortcutCategory) return -1;
+ if (obj is AddIn) return 1;
+ if (obj is ShortcutCategory) return 1;
var shortcutObj = (Shortcut)obj;
return Name.CompareTo(shortcutObj.Name);
diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs
index 371536cd6b..3334394618 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs
@@ -153,8 +153,8 @@ namespace ICSharpCode.ShortcutsManagement.Data
/// Comparison result
public int CompareTo(object obj)
{
- if (obj is AddIn) return -1;
- if (obj is Shortcut) return 1;
+ if (obj is AddIn) return 1;
+ if (obj is Shortcut) return -1;
var categoryObj = (ShortcutCategory)obj;
return Name.CompareTo(categoryObj.Name);
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 e1a3de6340..0c95c6a70b 100644
--- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
+++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
@@ -52,7 +52,7 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
///
/// Stores shortcut entry to input binding convertion map
///
- private readonly Dictionary shortcutsMap = new Dictionary();
+ private readonly MapTable shortcutsMap = new MapTable();
private List rootEntries;
@@ -91,7 +91,6 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
}
BindProfiles();
- BindShortcuts();
}
private void BindProfiles()
@@ -130,90 +129,58 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
private void BindShortcuts()
{
+ shortcutsMap.Clear();
+
// Root shortcut tree entries
rootEntries = new List();
// Stores SD input binding category to category section convertion map
- var categoriesMap = new Dictionary();
+ var categoriesMap = new MapTable();
var unspecifiedCategory = new ShortcutCategory(StringParser.Parse("${res:ShortcutsManagement.UnspecifiedCategoryName}"));
rootEntries.Add(unspecifiedCategory);
- // Go through all input bindings
- var inputBindingInfos = CommandManager.FindInputBindingInfos(null, null, null);
- foreach (var inputBindingInfo in inputBindingInfos)
+ CommandManager.InputBindingCategories.Sort((c1, c2) => c1.Path.CompareTo(c2.Path));
+ var parentCategories = new LinkedList();
+ var previousDepth = 0;
+ foreach(var bindingCategory in CommandManager.InputBindingCategories)
{
- // Find appropriate or create new category sections within add-in section for input binding
- var shortcutCategorySections = new List();
- if (inputBindingInfo.Categories.Count == 0)
- {
- // If no category specified assign to "Uncotegorized" category
- shortcutCategorySections.Add(unspecifiedCategory);
- }
- else
- {
- // Go throu all categories and find or create appropriate category sections
- foreach (var bindingCategory in inputBindingInfo.Categories)
+ var categoryName = Regex.Replace(StringParser.Parse(bindingCategory.Text), @"&([^\s])", @"$1");
+ var shortcutCategory = new ShortcutCategory(categoryName);
+ categoriesMap.Add(bindingCategory, shortcutCategory);
+
+ AddCategory:
+ var currentDepth = bindingCategory.Path.Split('/').Length - 1;
+ if (currentDepth > previousDepth)
{
- ShortcutCategory categorySection;
- if (categoriesMap.ContainsKey(bindingCategory))
+ previousDepth++;
+
+ if (previousDepth > 1)
{
- // If found appropriate category assign shortcut to it
- categorySection = categoriesMap[bindingCategory];
+ parentCategories.Last.Value.SubCategories.Add(shortcutCategory);
}
else
{
- // Create appropriate category section and root category sections
-
- // Create direct category to which shortcut will be assigned
- var categoryName = StringParser.Parse(bindingCategory.Name);
- categoryName = Regex.Replace(categoryName, @"&([^\s])", @"$1");
- categorySection = new ShortcutCategory(categoryName);
- categoriesMap.Add(bindingCategory, categorySection);
-
- // Go down to root level and create all parent categories
- var currentBindingCategory = bindingCategory;
- var currentShortcutCategory = categorySection;
- while (currentBindingCategory.ParentCategory != null)
- {
- ShortcutCategory parentCategorySection;
-
- if (!categoriesMap.ContainsKey(currentBindingCategory.ParentCategory))
- {
- // Create parent category section if it's not created yet
- var parentCategoryName = StringParser.Parse(currentBindingCategory.ParentCategory.Name);
- parentCategoryName = Regex.Replace(parentCategoryName, @"&([^\s])", @"$1");
- parentCategorySection = new ShortcutCategory(parentCategoryName);
-
- categoriesMap.Add(currentBindingCategory.ParentCategory, parentCategorySection);
- }
- else
- {
- // Use existing category section as parent category section
- parentCategorySection = categoriesMap[currentBindingCategory.ParentCategory];
- }
-
- // Add current category section to root category section children
- if (!parentCategorySection.SubCategories.Contains(currentShortcutCategory))
- {
- parentCategorySection.SubCategories.Add(currentShortcutCategory);
- }
-
- currentShortcutCategory = parentCategorySection;
- currentBindingCategory = currentBindingCategory.ParentCategory;
- }
-
- // Add root category section to add-in categories list
- if (!rootEntries.Contains(currentShortcutCategory))
- {
- rootEntries.Add(currentShortcutCategory);
- }
+ rootEntries.Add(shortcutCategory);
}
- shortcutCategorySections.Add(categorySection);
+ parentCategories.AddLast(shortcutCategory);
}
- }
+ else
+ {
+ while (previousDepth >= currentDepth)
+ {
+ parentCategories.RemoveLast();
+ previousDepth--;
+ }
+ goto AddCategory;
+ }
+ }
+
+ var inputBindingInfos = CommandManager.FindInputBindingInfos(null, null, null);
+ foreach (var inputBindingInfo in inputBindingInfos)
+ {
// Get shortcut entry text. Normaly shortcut entry text is equalt to routed command text
// but this value can be overriden through InputBindingInfo.RoutedCommandText value
var shortcutText = inputBindingInfo.RoutedCommand.Text;
@@ -228,27 +195,26 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
// Strip this sign from shortcut entry text
shortcutText = Regex.Replace(shortcutText, @"&([^\s])", @"$1");
- var gestures = inputBindingInfo.DefaultGestures;
- if(SelectedProfile != null)
+ var shortcut = new Shortcut(shortcutText, new InputGestureCollection(inputBindingInfo.ActiveGestures));
+ shortcutsMap.Add(shortcut, inputBindingInfo);
+
+ // Assign shortcut to all categories it is registered in
+ if (inputBindingInfo.Categories != null && inputBindingInfo.Categories.Count > 0)
{
- var userDefinedGestures = SelectedProfile[inputBindingInfo.Identifier];
- if(userDefinedGestures != null)
+ foreach (var bindingCategory in inputBindingInfo.Categories)
{
- gestures = userDefinedGestures;
+ var shortcutCategory = categoriesMap.MapForward(bindingCategory);
+ shortcutCategory.Shortcuts.Add(shortcut);
}
}
- var shortcut = new Shortcut(shortcutText, gestures);
-
- // Assign shortcut to all categories it is registered in
- foreach (var categorySection in shortcutCategorySections)
+ else
{
- categorySection.Shortcuts.Add(shortcut);
+ rootEntries.Add(shortcut);
}
-
- shortcutsMap.Add(shortcut, inputBindingInfo);
}
rootEntries.Sort();
+
foreach (var entry in rootEntries)
{
entry.SortSubEntries();
@@ -268,13 +234,13 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
}
}
- UserDefinedGesturesManager.CurrentProfile = SelectedProfile;
-
+ shortcutsMap.ForEach(p => p.Value.IsModifyed = true);
foreach (var pair in shortcutsMap)
{
pair.Value.IsModifyed = true;
}
+ UserDefinedGesturesManager.CurrentProfile = SelectedProfile;
CommandManager.InvokeInputBindingUpdateHandlers();
foreach (var profile in profiles)
@@ -472,7 +438,7 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
originalRelatedShortcut.Gestures.Clear();
originalRelatedShortcut.Gestures.AddRange(relatedShortcutCopy.Gestures);
- var id = shortcutsMap[originalRelatedShortcut].Identifier;
+ var id = shortcutsMap.MapForward(originalRelatedShortcut).Identifier;
SelectedProfile[id] = new InputGestureCollection(relatedShortcutCopy.Gestures);
}
}
diff --git a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
index 8f7d7ddc84..6c9e0f7d93 100644
--- a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
+++ b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
@@ -202,6 +202,15 @@ namespace ICSharpCode.SharpDevelop.Commands
public class ToolMenuBuilder : IMenuItemBuilder
{
+ private static InputBindingCategory externalToolsCategory;
+
+ static ToolMenuBuilder()
+ {
+ var categoryName = StringParser.Parse("External tools");
+ externalToolsCategory = new InputBindingCategory("/MainMenu/Tools/ExternalTools", categoryName);
+ ICSharpCode.Core.Presentation.CommandManager.RegisterInputBindingCategory(externalToolsCategory);
+ }
+
private bool bindingsAssigned = false;
public ICollection BuildItems(Codon codon, object owner)
@@ -230,7 +239,7 @@ namespace ICSharpCode.SharpDevelop.Commands
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
- inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories("Main Menu/${res:XML.MainMenu.ToolMenu}/External tools"));
+ inputBindingInfo.Categories.Add(externalToolsCategory);
CommandManager.RegisterInputBinding(inputBindingInfo);
}
@@ -528,8 +537,15 @@ namespace ICSharpCode.SharpDevelop.Commands
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.DefaultGestures = gestures;
- var menuPath = "Main Menu/${res:XML.MainMenu.ViewMenu}" + (Category == padContent.Category && padContent.Category == "Main" ? "" : "/" + padContent.Category);
- inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories(menuPath));
+
+ var categoryPath = "/MainMenu/View" + (Category == padContent.Category && padContent.Category != "Main" ? "/" + padContent.Class : "");
+ var category = ICSharpCode.Core.Presentation.CommandManager.GetInputBindingCategory(categoryPath, false);
+ if(category == null) {
+ category = new InputBindingCategory(categoryPath, padContent.Category);
+ ICSharpCode.Core.Presentation.CommandManager.RegisterInputBindingCategory(category);
+ }
+
+ inputBindingInfo.Categories.Add(category);
inputBindingInfo.AddIn = addIn;
CommandManager.RegisterInputBinding(inputBindingInfo);
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
index 0c4b141da2..4db95f1f7e 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
@@ -75,6 +75,8 @@ namespace ICSharpCode.SharpDevelop.Gui
public void Initialize()
{
+ CommandsService.RegisterInputBindingCategories(this, "/SharpDevelop/Workbench/InputBindingCategories");
+
// Use shortened assembly qualified name to not lose user defined gestures
// when sharp develop is updated
CommandManager.DefaultContextName =
diff --git a/src/Main/Core/Project/ICSharpCode.Core.csproj b/src/Main/Core/Project/ICSharpCode.Core.csproj
index 351cf0e5f8..c6d7bc6158 100644
--- a/src/Main/Core/Project/ICSharpCode.Core.csproj
+++ b/src/Main/Core/Project/ICSharpCode.Core.csproj
@@ -66,6 +66,7 @@
+
diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingCategoryDoozer.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingCategoryDoozer.cs
new file mode 100644
index 0000000000..9527fdda66
--- /dev/null
+++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingCategoryDoozer.cs
@@ -0,0 +1,48 @@
+/*
+ * Created by SharpDevelop.
+ * User: Administrator
+ * Date: 7/3/2009
+ * Time: 4:50 PM
+ *
+ * To change this template use Tools | Options | Coding | Edit Standard Headers.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ICSharpCode.Core
+{
+ ///
+ /// Description of InputBindingInfoCategory.
+ ///
+ public class InputBindingCategoryDoozer : IDoozer
+ {
+ ///
+ public bool HandleConditions {
+ get {
+ return true;
+ }
+ }
+
+ ///
+ /// Builds InputBindingDescriptor
+ ///
+ public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems)
+ {
+ return new InputBindingCategoryDescriptor(codon, subItems);
+ }
+ }
+
+ public class InputBindingCategoryDescriptor
+ {
+ public string Id;
+ public string Text;
+ public List Children;
+
+ public InputBindingCategoryDescriptor(Codon codon, System.Collections.ArrayList subItems) {
+ Id = codon.Properties["id"];
+ Text = codon.Properties["text"];
+ Children = subItems != null ? subItems.Cast().ToList() : new List();
+ }
+ }
+}
diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuRootDoozer.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuRootDoozer.cs
index ffbfa34f6f..3c10689423 100644
--- a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuRootDoozer.cs
+++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuRootDoozer.cs
@@ -37,11 +37,6 @@ namespace ICSharpCode.Core
{
get; private set;
}
-
- public string Name
- {
- get; private set;
- }
public string Path
{
@@ -57,10 +52,6 @@ namespace ICSharpCode.Core
if(codon.Properties.Contains("category")){
Category = codon.Properties["category"];
}
-
- if(codon.Properties.Contains("name")){
- Name = codon.Properties["name"];
- }
}
}
}
diff --git a/src/Main/Core/Project/Src/AddInTree/AddInTree.cs b/src/Main/Core/Project/Src/AddInTree/AddInTree.cs
index 87bc8e279c..8ef65e6643 100644
--- a/src/Main/Core/Project/Src/AddInTree/AddInTree.cs
+++ b/src/Main/Core/Project/Src/AddInTree/AddInTree.cs
@@ -35,6 +35,7 @@ namespace ICSharpCode.Core
doozers.Add("ToolbarItem", new ToolbarItemDoozer());
doozers.Add("Include", new IncludeDoozer());
doozers.Add("InputBinding", new InputBindingDoozer());
+ doozers.Add("InputBindingCategory", new InputBindingCategoryDoozer());
doozers.Add("CommandBinding", new CommandBindingDoozer());
doozers.Add("RoutedUICommand", new RoutedUICommandDoozer());
doozers.Add("GesturesPlaceHolder", new GesturesPlaceHolderDoozer());
diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandManager.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandManager.cs
index 63c0b25f1e..f3123c8e47 100644
--- a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandManager.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandManager.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
@@ -49,7 +50,7 @@ namespace ICSharpCode.Core.Presentation
private static Dictionary namedUITypes = new Dictionary();
// Categories
- private static List categories = new List();
+ public static List InputBindingCategories = new List();
///
/// Register UI element instance accessible by unique name
@@ -492,7 +493,11 @@ namespace ICSharpCode.Core.Presentation
/// Update handler
public static void RegisterClassInputBindingsUpdateHandler(Type ownerType, BindingsUpdatedHandler handler)
{
- RegisterClassInputBindingsUpdateHandler(ownerType.AssemblyQualifiedName, handler);
+ // Use shortened assembly qualified name to not lose user defined gestures
+ // when sharp develop is updated
+ var ownerTypeName = string.Format("{0}, {1}", ownerType.FullName, ownerType.Assembly.GetName().Name);
+
+ RegisterClassInputBindingsUpdateHandler(ownerTypeName, handler);
}
///
@@ -593,14 +598,9 @@ namespace ICSharpCode.Core.Presentation
private static void InvokeAllBindingUpdateHandlers(System.Collections.IDictionary updateHandlers)
{
- foreach(var updateHandlerPair in updateHandlers) {
+ foreach(DictionaryEntry updateHandlerPair in updateHandlers) {
// TODO: This can be fixed with .NET 4.0
- List handlers = null;
- if(updateHandlerPair is KeyValuePair>) {
- handlers = ((KeyValuePair>)updateHandlerPair).Value;
- } else if(updateHandlerPair is KeyValuePair