Browse Source

InputBindingCategory class, nested categories

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4285 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts^2
Sergej Andrejev 16 years ago
parent
commit
cf7680a3ee
  1. 16
      AddIns/ICSharpCode.SharpDevelop.addin
  2. BIN
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo
  3. 8
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/StringResources.resx
  4. 3
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsFinder.cs
  5. 1
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/Resources.xaml
  6. 185
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
  7. 71
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs
  8. 4
      src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
  9. 79
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs
  10. 4
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
  11. 47
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingCategory.cs
  12. 6
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
  13. 1
      src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
  14. 2
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs

16
AddIns/ICSharpCode.SharpDevelop.addin

@ -51,6 +51,22 @@ @@ -51,6 +51,22 @@
<Import assembly=":ICSharpCode.TextEditor"/>
</Runtime>
<Path name="/SharpDevelop/Categories">
<Category id="Debug" text="Debug" />
<Categoru id="MainMenu" text="Main menu">
<Category id="File" text="File" />
<Category id="Edit" text="Edit" />
<Category id="Project" text="Project" />
<Category id="Build" text="Build" />
<Category id="Debug" text="Debug" />
<Category id="Search" text="Search" />
<Category id="QualityTools" text="Quality Tools" />
<Category id="XML" text="XML" />
<Category id="Tools" text="Tools" />
<Category id="Window" text="Window" />
</Categoru>
</Path>
<Path name="/SharpDevelop/Workbench/RoutedUICommands">
<RoutedUICommand name="SDTestCommands.Test" text="Create new file" />

BIN
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo

Binary file not shown.

8
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/StringResources.resx

@ -128,8 +128,16 @@ @@ -128,8 +128,16 @@
</data>
<data name="Global.CancelButtonText" xml:space="preserve">
<value>_Cancel</value>
<comment>For testing outside SD</comment>
</data>
<data name="Global.OKButtonText" xml:space="preserve">
<value>_OK</value>
<comment>For testing outside SD</comment>
</data>
<data name="ShortcutsManagement.UnspecifiedAddInName" xml:space="preserve">
<value>Unspecified</value>
</data>
<data name="ShortcutsManagement.UnspecifiedCategoryName" xml:space="preserve">
<value>Uncategorized</value>
</data>
</root>

3
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsFinder.cs

@ -261,7 +261,8 @@ namespace ICSharpCode.ShortcutsManagement.Data @@ -261,7 +261,8 @@ namespace ICSharpCode.ShortcutsManagement.Data
}
}
return category.IsVisible = (forseMatch.HasValue && forseMatch.Value) || isSubElementVisible;
// Show category if has sub elements, forced or matches search filter
return category.IsVisible = (forseMatch.HasValue && forseMatch.Value && (category.SubCategories.Count > 0 || category.Shortcuts.Count > 0)) || isSubElementVisible;
}
}
}

1
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/Resources.xaml

@ -128,6 +128,7 @@ @@ -128,6 +128,7 @@
<DataTrigger Binding="{Binding Converter={StaticResource TypeNameConverter}}" Value="AddIn">
<Setter TargetName="InnerBorder" Property="Panel.Background" Value="#AEFFA8" />
<Setter TargetName="InnerBorder" Property="TextElement.Foreground" Value="#000000" />
<Setter TargetName="OuterBorder" Property="Margin" Value="0" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsVisible}" Value="false">
<Setter Property="Visibility" Value="Collapsed" />

185
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs

@ -1,5 +1,4 @@ @@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using System.Windows.Controls;
using System.Windows.Input;
@ -17,131 +16,128 @@ namespace ICSharpCode.ShortcutsManagement @@ -17,131 +16,128 @@ namespace ICSharpCode.ShortcutsManagement
/// </summary>
public partial class ShortcutsManagementOptionsPanel : UserControl, IOptionPanel
{
/// <summary>
/// Stores shortcut entry to input binding convertion map
/// </summary>
private readonly Dictionary<Shortcut, InputBindingInfo> shortcutsMap = new Dictionary<Shortcut, InputBindingInfo>();
private static InputGestureCollection GetGestures(string gesturesString)
{
var converter = new InputGestureCollectionConverter();
return (InputGestureCollection)converter.ConvertFromInvariantString(gesturesString);
}
public ShortcutsManagementOptionsPanel()
{
ResourceService.RegisterStrings("ICSharpCode.ShortcutsManagement.Resources.StringResources", GetType().Assembly);
InitializeComponent();
// Test data
var rootEntries = new ObservableCollection<IShortcutTreeEntry>();
var addin1 = new ShortcutManagement.AddIn("SharpDevelop");
rootEntries.Add(addin1);
addin1.Categories.Add(new ShortcutCategory("Editing"));
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")));
addin1.Categories[0].Shortcuts.Add(new Shortcut("Undo", GetGestures("Ctrl + Z")));
addin1.Categories[0].Shortcuts.Add(new Shortcut("Redo", GetGestures("Ctrl + Y")));
addin1.Categories.Add(new ShortcutCategory("Building"));
addin1.Categories[1].Shortcuts.Add(new Shortcut("Build", GetGestures("Ctrl + Shift+B")));
addin1.Categories[1].Shortcuts.Add(new Shortcut("Run", GetGestures("F5")));
addin1.Categories[1].Shortcuts.Add(new Shortcut("Run without debuger", GetGestures("Ctrl + F5")));
addin1.Categories[1].Shortcuts.Add(new Shortcut("Attach debuger", GetGestures("Ctrl + F8")));
addin1.Categories.Add(new ShortcutCategory("Uncategorized"));
addin1.Categories[2].Shortcuts.Add(new Shortcut("Attach debuger", GetGestures("Ctrl + F8")));
var addin2 = new ShortcutManagement.AddIn("Search & replace");
rootEntries.Add(addin2);
addin2.Categories.Add(new ShortcutCategory("Uncategorized"));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Quick find", GetGestures("Ctrl + F")));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Quick replace", GetGestures("Ctrl + H")));
addin2.Categories[0].SubCategories.Add(new ShortcutCategory("Subcategory 3"));
addin2.Categories[0].SubCategories[0].SubCategories.Add(new ShortcutCategory("Subcategory 4"));
addin2.Categories[0].SubCategories[0].SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut N", GetGestures("Ctrl + N")));
addin2.Categories[0].SubCategories[0].SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut O", GetGestures("Ctrl + O")));
addin2.Categories[0].SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut L", GetGestures("Ctrl + L")));
addin2.Categories[0].SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut M", GetGestures("Ctrl + M")));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Find in files", GetGestures("Ctrl + Shift + F | Ctrl + Shift + H | Ctrl + I")));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Replace in files", GetGestures("Ctrl + Shift + H")));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Find symbol", null));
var addin3 = new ShortcutManagement.AddIn("Unspecified");
rootEntries.Add(addin3);
addin3.Categories.Add(new ShortcutCategory("Uncategorized"));
addin3.Categories[0].Shortcuts.Add(new Shortcut("Test regex expression", null));
var rootCategory = new ShortcutCategory("Without addin");
rootEntries.Add(rootCategory);
rootCategory.SubCategories.Add(new ShortcutCategory("Subcategory 1"));
rootCategory.SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut H", GetGestures("Ctrl + H")));
rootCategory.SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut I", GetGestures("Ctrl + I")));
rootCategory.SubCategories.Add(new ShortcutCategory("Subcategory 2"));
rootCategory.SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut J", GetGestures("Ctrl + J")));
rootCategory.SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut K", GetGestures("Ctrl + K")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut A", GetGestures("Ctrl + A")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut B", GetGestures("Ctrl + B")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut C", GetGestures("Ctrl + C")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut D", GetGestures("Ctrl + D")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut E", null));
rootEntries.Add(new Shortcut("Shortcut F", GetGestures("Ctrl + F")));
rootEntries.Add(new Shortcut("Shortcut G", GetGestures("Ctrl + G")));
shortcutsManagementOptionsPanel.DataContext = rootEntries;
}
public void LoadOptions()
{
// Load shortcuts for real
var unspecifiedAddInSection = new ShortcutManagement.AddIn("Unspecified");
unspecifiedAddInSection.Categories.Add(new ShortcutCategory("Uncategorized"));
var rootEntries = new List<IShortcutTreeEntry>();
rootEntries.Add(unspecifiedAddInSection);
// Root shortcut tree entries
var rootEntries = new List<IShortcutTreeEntry>();
// Stores SD add-in to add-in section convertion map
var addInsMap = new Dictionary<AddIn, ShortcutManagement.AddIn>();
var categoriesMap = new Dictionary<ShortcutManagement.AddIn, Dictionary<string, ShortcutCategory>>();
// Stores SD input binding category to category section convertion map
var categoriesMap = new Dictionary<ShortcutManagement.AddIn, Dictionary<InputBindingCategory, ShortcutCategory>>();
// Create default add-in for input bindings which don't specify add-in
var unspecifiedAddInSection = new ShortcutManagement.AddIn(StringParser.Parse("${res:ShortcutsManagement.UnspecifiedAddInName}"));
unspecifiedAddInSection.Categories.Add(new ShortcutCategory(StringParser.Parse("${res:ShortcutsManagement.UnspecifiedCategoryName}")));
rootEntries.Add(unspecifiedAddInSection);
// Go through all input bindings
var inputBindingInfos = CommandsRegistry.FindInputBindingInfos(null, null, null);
foreach(var inputBindingInfo in inputBindingInfos) {
// Find appropriate or create new add-in section for input binding
ShortcutManagement.AddIn addinSection;
if(inputBindingInfo.AddIn == null) {
if (inputBindingInfo.AddIn == null) {
addinSection = unspecifiedAddInSection;
} else if (addInsMap.ContainsKey(inputBindingInfo.AddIn)) {
addinSection = addInsMap[inputBindingInfo.AddIn];
} else {
addinSection = new ShortcutManagement.AddIn(inputBindingInfo.AddIn.Name);
addinSection.Categories.Add(new ShortcutCategory("Uncategorized"));
addinSection.Categories.Add(new ShortcutCategory(StringParser.Parse("${res:ShortcutsManagement.UnspecifiedCategoryName}")));
addInsMap.Add(inputBindingInfo.AddIn, addinSection);
categoriesMap.Add(addinSection, new Dictionary<string, ShortcutCategory>());
categoriesMap.Add(addinSection, new Dictionary<InputBindingCategory, ShortcutCategory>());
rootEntries.Add(addinSection);
}
ShortcutCategory categorySection;
if(string.IsNullOrEmpty(inputBindingInfo.CategoryName)) {
categorySection = addinSection.Categories[0];
} else if(!categoriesMap[addinSection].ContainsKey(inputBindingInfo.CategoryName)) {
categorySection = new ShortcutCategory(inputBindingInfo.CategoryName);
addinSection.Categories.Add(categorySection);
categoriesMap[addinSection].Add(inputBindingInfo.CategoryName, categorySection);
// Find appropriate or create new category sections within add-in section for input binding
var shortcutCategorySections = new List<ShortcutCategory>();
if (inputBindingInfo.Categories.Count == 0) {
// If no category specified assign to "Uncotegorized" category
shortcutCategorySections.Add(addinSection.Categories[0]);
} else {
categorySection = categoriesMap[addinSection][inputBindingInfo.CategoryName];
// Go throu all categories and find or create appropriate category sections
foreach (var bindingCategory in inputBindingInfo.Categories) {
ShortcutCategory categorySection;
if (categoriesMap[addinSection].ContainsKey(bindingCategory)) {
// If found appropriate category assign shortcut to it
categorySection = categoriesMap[addinSection][bindingCategory];
} else {
// Create appropriate category section and root category sections
// Create direct category to which shortcut will be assigned
var categoryName = StringParser.Parse(bindingCategory.Name);
categorySection = new ShortcutCategory(categoryName);
categoriesMap[addinSection].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[addinSection].ContainsKey(currentBindingCategory.ParentCategory)) {
// Create parent category section if it's not created yet
var parentCategoryName = StringParser.Parse(currentBindingCategory.ParentCategory.Name);
parentCategorySection = new ShortcutCategory(parentCategoryName);
categoriesMap[addinSection].Add(currentBindingCategory.ParentCategory, parentCategorySection);
} else {
// Use existing category section as parent category section
parentCategorySection = categoriesMap[addinSection][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 (!addinSection.Categories.Contains(currentShortcutCategory)) {
addinSection.Categories.Add(currentShortcutCategory);
}
}
shortcutCategorySections.Add(categorySection);
}
}
// 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;
if (!string.IsNullOrEmpty(inputBindingInfo.RoutedCommandText)) {
shortcutText = inputBindingInfo.RoutedCommandText;
}
var shortcutText = !string.IsNullOrEmpty(inputBindingInfo.RoutedCommandText)
? inputBindingInfo.RoutedCommandText
: inputBindingInfo.RoutedCommand.Text;
shortcutText = StringParser.Parse(shortcutText);
// Some commands have "&" sign to mark alternative key used to call this command from menu
// Strip this sign
// Strip this sign from shortcut entry text
shortcutText = Regex.Replace(shortcutText, @"&([^\s])", @"$1");
var shortcut = new Shortcut(shortcutText, inputBindingInfo.Gestures);
categorySection.Shortcuts.Add(shortcut);
// Assign shortcut to all categories it is registered in
foreach (var categorySection in shortcutCategorySections) {
categorySection.Shortcuts.Add(shortcut);
}
shortcutsMap.Add(shortcut, inputBindingInfo);
shortcutsMap.Add(shortcut, inputBindingInfo);
}
rootEntries.Sort();
@ -154,10 +150,9 @@ namespace ICSharpCode.ShortcutsManagement @@ -154,10 +150,9 @@ namespace ICSharpCode.ShortcutsManagement
shortcutsManagementOptionsPanel.DataContext = rootEntries;
}
public bool SaveOptions() {
foreach (var pair in shortcutsMap)
{
public bool SaveOptions()
{
foreach (var pair in shortcutsMap) {
var shortcut = pair.Key;
var inputBindingInfo = pair.Value;

71
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs

@ -1,4 +1,9 @@ @@ -1,4 +1,9 @@
using System.Windows;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.Core.Presentation;
using ICSharpCode.ShortcutsManagement.Data;
using AddInSection = ICSharpCode.ShortcutsManagement.Data.AddIn;
namespace ICSharpCode.ShortcutsManagement
{
@ -10,6 +15,70 @@ namespace ICSharpCode.ShortcutsManagement @@ -10,6 +15,70 @@ namespace ICSharpCode.ShortcutsManagement
public Window1()
{
InitializeComponent();
// Test data
var rootEntries = new ObservableCollection<IShortcutTreeEntry>();
var addin1 = new AddInSection("SharpDevelop");
rootEntries.Add(addin1);
addin1.Categories.Add(new ShortcutCategory("Editing"));
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")));
addin1.Categories[0].Shortcuts.Add(new Shortcut("Undo", GetGestures("Ctrl + Z")));
addin1.Categories[0].Shortcuts.Add(new Shortcut("Redo", GetGestures("Ctrl + Y")));
addin1.Categories.Add(new ShortcutCategory("Building"));
addin1.Categories[1].Shortcuts.Add(new Shortcut("Build", GetGestures("Ctrl + Shift+B")));
addin1.Categories[1].Shortcuts.Add(new Shortcut("Run", GetGestures("F5")));
addin1.Categories[1].Shortcuts.Add(new Shortcut("Run without debuger", GetGestures("Ctrl + F5")));
addin1.Categories[1].Shortcuts.Add(new Shortcut("Attach debuger", GetGestures("Ctrl + F8")));
addin1.Categories.Add(new ShortcutCategory("Uncategorized"));
addin1.Categories[2].Shortcuts.Add(new Shortcut("Attach debuger", GetGestures("Ctrl + F8")));
var addin2 = new AddInSection("Search & replace");
rootEntries.Add(addin2);
addin2.Categories.Add(new ShortcutCategory("Uncategorized"));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Quick find", GetGestures("Ctrl + F")));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Quick replace", GetGestures("Ctrl + H")));
addin2.Categories[0].SubCategories.Add(new ShortcutCategory("Subcategory 3"));
addin2.Categories[0].SubCategories[0].SubCategories.Add(new ShortcutCategory("Subcategory 4"));
addin2.Categories[0].SubCategories[0].SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut N", GetGestures("Ctrl + N")));
addin2.Categories[0].SubCategories[0].SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut O", GetGestures("Ctrl + O")));
addin2.Categories[0].SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut L", GetGestures("Ctrl + L")));
addin2.Categories[0].SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut M", GetGestures("Ctrl + M")));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Find in files", GetGestures("Ctrl + Shift + F | Ctrl + Shift + H | Ctrl + I")));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Replace in files", GetGestures("Ctrl + Shift + H")));
addin2.Categories[0].Shortcuts.Add(new Shortcut("Find symbol", null));
var addin3 = new AddInSection("Unspecified");
rootEntries.Add(addin3);
addin3.Categories.Add(new ShortcutCategory("Uncategorized"));
addin3.Categories[0].Shortcuts.Add(new Shortcut("Test regex expression", null));
var rootCategory = new ShortcutCategory("Without addin");
rootEntries.Add(rootCategory);
rootCategory.SubCategories.Add(new ShortcutCategory("Subcategory 1"));
rootCategory.SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut H", GetGestures("Ctrl + H")));
rootCategory.SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut I", GetGestures("Ctrl + I")));
rootCategory.SubCategories.Add(new ShortcutCategory("Subcategory 2"));
rootCategory.SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut J", GetGestures("Ctrl + J")));
rootCategory.SubCategories[0].Shortcuts.Add(new Shortcut("Shortcut K", GetGestures("Ctrl + K")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut A", GetGestures("Ctrl + A")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut B", GetGestures("Ctrl + B")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut C", GetGestures("Ctrl + C")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut D", GetGestures("Ctrl + D")));
rootCategory.Shortcuts.Add(new Shortcut("Shortcut E", null));
rootEntries.Add(new Shortcut("Shortcut F", GetGestures("Ctrl + F")));
rootEntries.Add(new Shortcut("Shortcut G", GetGestures("Ctrl + G")));
optionsPanel.DataContext = rootEntries;
}
private static InputGestureCollection GetGestures(string gesturesString)
{
var converter = new InputGestureCollectionConverter();
return (InputGestureCollection)converter.ConvertFromInvariantString(gesturesString);
}
}
}

4
src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs

@ -471,7 +471,7 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -471,7 +471,7 @@ namespace ICSharpCode.SharpDevelop.Commands
}
var routedCommandName = "SDViewCommands.ShowView_" + padContent.Class;
var routedCommandText = "Show view \"" + MenuService.ConvertLabel(StringParser.Parse(padContent.Title)) + "\"";
var routedCommandText = MenuService.ConvertLabel(StringParser.Parse(padContent.Title));
// TODO: fix this hack
if(!bindingsAssigned.Contains(routedCommandName)) {
@ -497,7 +497,7 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -497,7 +497,7 @@ namespace ICSharpCode.SharpDevelop.Commands
inputBindingInfo.ContextName = CommandsRegistry.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = gestures;
inputBindingInfo.CategoryName = "Views";
inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories("Menu Items/Views"));
inputBindingInfo.AddIn = addIn;
CommandsRegistry.RegisterInputBinding(inputBindingInfo);

79
src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs

@ -5,6 +5,8 @@ using System.Windows; @@ -5,6 +5,8 @@ using System.Windows;
using ICSharpCode.Core;
using System.Threading;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
namespace ICSharpCode.Core.Presentation
{
@ -39,6 +41,8 @@ namespace ICSharpCode.Core.Presentation @@ -39,6 +41,8 @@ namespace ICSharpCode.Core.Presentation
private static Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>> commandBindingsUpdateHandlers = new Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>>();
private static Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>> inputBindingsUpdateHandlers = new Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>>();
private static List<InputBindingCategory> categories = new List<InputBindingCategory>();
/// <summary>
/// Get reference to routed UI command by name
/// </summary>
@ -110,12 +114,20 @@ namespace ICSharpCode.Core.Presentation @@ -110,12 +114,20 @@ namespace ICSharpCode.Core.Presentation
}
}
/// <summary>
/// Register input binding by specifying this binding parameters
/// </summary>
/// <param name="inputBindingInfo">Input binding parameters</param>
public static void RegisterInputBinding(InputBindingInfo inputBindingInfo)
{
inputBidnings.Add(inputBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(inputBindingInfo.ContextName, null);
}
/// <summary>
/// Unregister input binding
/// </summary>
/// <param name="inputBindingInfo">Input binding parameters</param>
public static void UnregisterInputBinding(InputBindingInfo inputBindingInfo)
{
inputBidnings.Remove(inputBindingInfo);
@ -129,7 +141,6 @@ namespace ICSharpCode.Core.Presentation @@ -129,7 +141,6 @@ namespace ICSharpCode.Core.Presentation
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Unregister binding assigned to specific context instance</param>
/// <param name="routedCommandName">Routed UI command name</param>
/// <param name="gesture">Gesture</param>
public static ICollection<InputBindingInfo> FindInputBindingInfos(string contextName, UIElement contextInstance, string routedCommandName) {
var foundBindings = new List<InputBindingInfo>();
for(int i = inputBidnings.Count - 1; i >= 0; i--) {
@ -228,9 +239,9 @@ namespace ICSharpCode.Core.Presentation @@ -228,9 +239,9 @@ namespace ICSharpCode.Core.Presentation
}
/// <summary>
/// Remove all managed input bindings from input bindings collection
/// Remove all managed input bindings from <see cref="InputBindingCollection" />
/// </summary>
/// <param name="inputBindingCollection"></param>
/// <param name="inputBindingCollection">Input binding cllection containing managed input bindings</param>
public static void RemoveManagedInputBindings(InputBindingCollection inputBindingCollection) {
for(int i = inputBindingCollection.Count - 1; i >= 0; i--) {
if(inputBindingCollection[i] is ManagedInputBinding) {
@ -239,10 +250,18 @@ namespace ICSharpCode.Core.Presentation @@ -239,10 +250,18 @@ namespace ICSharpCode.Core.Presentation
}
}
/// <summary>
/// Register command binding by specifying command binding parameters
/// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void RegisterCommandBinding(CommandBindingInfo commandBindingInfo) {
commandBindings.Add(commandBindingInfo);
}
/// <summary>
/// Unregister command binding
/// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void UnregisterCommandBinding(CommandBindingInfo commandBindingInfo) {
commandBindings.Remove(commandBindingInfo);
}
@ -331,9 +350,9 @@ namespace ICSharpCode.Core.Presentation @@ -331,9 +350,9 @@ namespace ICSharpCode.Core.Presentation
}
/// <summary>
/// Remove all managed command bindungs from command bindings collection
/// Remove all managed command bindings from <see cref="CommandBindingCollection" />
/// </summary>
/// <param name="commandBindingsCollection"></param>
/// <param name="commandBindingsCollection">Command binding cllection containing managed input bindings</param>
public static void RemoveManagedCommandBindings(CommandBindingCollection commandBindingsCollection) {
for(int i = commandBindingsCollection.Count - 1; i >= 0; i--) {
if(commandBindingsCollection[i] is ManagedCommandBinding) {
@ -343,9 +362,9 @@ namespace ICSharpCode.Core.Presentation @@ -343,9 +362,9 @@ namespace ICSharpCode.Core.Presentation
}
/// <summary>
/// Load all registered commands in addin
/// Load all registered commands in add-in
/// </summary>
/// <param name="addIn">Addin</param>
/// <param name="addIn">Add-in</param>
public static void LoadAddinCommands(AddIn addIn) {
foreach(var binding in commandBindings) {
if(binding.AddIn != addIn) continue;
@ -363,7 +382,8 @@ namespace ICSharpCode.Core.Presentation @@ -363,7 +382,8 @@ namespace ICSharpCode.Core.Presentation
}
/// <summary>
/// Load command
/// Register command object (either instance of <see cref="System.Windows.Input.ICommand" /> or <see cref="ICSharpCode.Core.ICommand" />)
/// which can be identified by command name
/// </summary>
/// <param name="commandName">Command name</param>
/// <param name="command">Command instance</param>
@ -379,7 +399,7 @@ namespace ICSharpCode.Core.Presentation @@ -379,7 +399,7 @@ namespace ICSharpCode.Core.Presentation
}
/// <summary>
/// Load context
/// Register binding owner instance which can be identified by unique name
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="context">Context class instance</param>
@ -479,5 +499,46 @@ namespace ICSharpCode.Core.Presentation @@ -479,5 +499,46 @@ namespace ICSharpCode.Core.Presentation
return gestures;
}
/// <summary>
/// Register input binding category
///
/// Format:
/// , - Separates categories
/// / - Describes hierarchy meaning category to the left is child of the category to the right
///
/// <code>parent/child</code>
/// </summary>
/// <param name="categoriesString">String representing list of categories.</param>
/// <returns>Returns list of categories which can be assigned to input binding</returns>
public static List<InputBindingCategory> RegisterInputBindingCategories(string categoriesString) {
var registeredCategories = new List<InputBindingCategory>();
// Split categories
var categoryPaths = Regex.Split(categoriesString, @"\s*\,\s*");
foreach(var categoryPath in categoryPaths) {
// Split category path
var pathEntries = Regex.Split(categoryPath, @"\s*\/\s*").ToList();
var accumulatedPath = "";
InputBindingCategory parentCategory = null;
// In a loop create category hierarchy specified in a path
foreach(var categoryPathEntry in pathEntries) {
accumulatedPath += "/" + categoryPathEntry;
var matchingCategory = categories.FirstOrDefault(c => c.Path == accumulatedPath);
if(matchingCategory == null) {
matchingCategory = new InputBindingCategory(categoryPathEntry, parentCategory);
matchingCategory.Path = accumulatedPath;
categories.Add(matchingCategory);
}
parentCategory = matchingCategory;
}
registeredCategories.Add(parentCategory);
}
return registeredCategories;
}
}
}

4
src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.Core.Presentation @@ -70,7 +70,7 @@ namespace ICSharpCode.Core.Presentation
}
if(!string.IsNullOrEmpty(desc.Category)) {
inputBindingInfo.CategoryName = desc.Category;
inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories(desc.Category));
}
CommandsRegistry.RegisterInputBinding(inputBindingInfo);
@ -96,7 +96,7 @@ namespace ICSharpCode.Core.Presentation @@ -96,7 +96,7 @@ namespace ICSharpCode.Core.Presentation
}
if(!string.IsNullOrEmpty(desc.Category)) {
inputBindingInfo.CategoryName = desc.Category;
inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories(desc.Category));
}
CommandsRegistry.RegisterInputBinding(inputBindingInfo);

47
src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingCategory.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
using System;
namespace ICSharpCode.Core.Presentation
{
/// <summary>
/// Stores input binding category description
/// </summary>
public class InputBindingCategory
{
/// <summary>
/// Creates new instance of <see cref="InputBindingCategory" />
/// </summary>
/// <param name="name">Category name</param>
/// <param name="parentCategory">Parent category (null - root level category)</param>
public InputBindingCategory(string name, InputBindingCategory parentCategory)
{
Name = name;
ParentCategory = parentCategory;
}
/// <summary>
/// Category name
/// </summary>
public string Name
{
get; set;
}
/// <summary>
/// Reference to parent category
/// </summary>
public InputBindingCategory ParentCategory
{
get; set;
}
/// <summary>
/// Category path is used to specify hierarchical category position
///
/// Format:
/// /category/subcategory
/// </summary>
internal string Path {
get; set;
}
}
}

6
src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
using System;
using System.Windows;
using System.Windows.Input;
using System.Collections.Generic;
namespace ICSharpCode.Core.Presentation
{
@ -13,6 +14,7 @@ namespace ICSharpCode.Core.Presentation @@ -13,6 +14,7 @@ namespace ICSharpCode.Core.Presentation
public InputBindingInfo() {
ContextName = CommandsRegistry.DefaultContextName;
Categories = new List<InputBindingCategory>();
}
/// <summary>
@ -90,8 +92,8 @@ namespace ICSharpCode.Core.Presentation @@ -90,8 +92,8 @@ namespace ICSharpCode.Core.Presentation
get; set;
}
public string CategoryName {
get; set;
public List<InputBindingCategory> Categories {
get; private set;
}
}
}

1
src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj

@ -71,6 +71,7 @@ @@ -71,6 +71,7 @@
<Compile Include="CommandsService\CommandsService.cs" />
<Compile Include="CommandsService\CommandsRegistry.cs" />
<Compile Include="CommandsService\GesturePlaceHolderRegistry.cs" />
<Compile Include="CommandsService\InputBindingCategory.cs" />
<Compile Include="CommandsService\InputBindingInfo.cs" />
<Compile Include="CommandsService\InputGestureCollectionConverter.cs" />
<Compile Include="CommandsService\InputGestureCollectionExtensions.cs" />

2
src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs

@ -153,7 +153,7 @@ namespace ICSharpCode.Core.Presentation @@ -153,7 +153,7 @@ namespace ICSharpCode.Core.Presentation
var shortcut = codon.Properties["shortcut"];
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.AddIn = codon.AddIn;
inputBindingInfo.CategoryName = "Menu items";
inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories("Menu Items"));
inputBindingInfo.ContextName = CommandsRegistry.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromInvariantString(codon.Properties["gestures"]);

Loading…
Cancel
Save