Browse Source

InputBindingCategory codon

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4397 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts^2
Sergej Andrejev 16 years ago
parent
commit
4003bdda88
  1. BIN
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo
  2. 1
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj
  3. 4
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs
  4. 44
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/MapTable.cs
  5. 4
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs
  6. 4
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs
  7. 132
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
  8. 22
      src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
  9. 2
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
  10. 1
      src/Main/Core/Project/ICSharpCode.Core.csproj
  11. 48
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingCategoryDoozer.cs
  12. 9
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuRootDoozer.cs
  13. 1
      src/Main/Core/Project/Src/AddInTree/AddInTree.cs
  14. 103
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandManager.cs
  15. 45
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
  16. 27
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingCategory.cs
  17. 85
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingCategoryCollection.cs
  18. 5
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
  19. 1
      src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj

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

Binary file not shown.

1
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj

@ -156,6 +156,7 @@ @@ -156,6 +156,7 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Src\Data\IShortcutTreeEntry.cs" />
<Compile Include="Src\Data\MapTable.cs" />
<Compile Include="Src\Data\SeparatorData.cs" />
<Compile Include="Src\Data\Shortcut.cs" />
<Compile Include="Src\Data\ShortcutCategory.cs" />

4
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs

@ -126,8 +126,8 @@ namespace ICSharpCode.ShortcutsManagement.Data @@ -126,8 +126,8 @@ namespace ICSharpCode.ShortcutsManagement.Data
/// <param name="obj">Compared object</param>
/// <returns>Comparison result</returns>
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);

44
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/MapTable.cs

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
using System.Collections;
using System.Collections.Generic;
namespace ICSharpCode.ShortcutsManagement.Data
{
public class MapTable<T1, T2> : IEnumerable<KeyValuePair<T1, T2>>
{
private readonly Dictionary<T1, T2> forwardMaping = new Dictionary<T1, T2>();
private readonly Dictionary<T2, T1> backwardMaping = new Dictionary<T2, T1>();
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<KeyValuePair<T1, T2>> GetEnumerator()
{
return forwardMaping.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return forwardMaping.GetEnumerator();
}
}
}

4
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs

@ -159,8 +159,8 @@ namespace ICSharpCode.ShortcutsManagement.Data @@ -159,8 +159,8 @@ namespace ICSharpCode.ShortcutsManagement.Data
/// <returns>Comparison result</returns>
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);

4
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs

@ -153,8 +153,8 @@ namespace ICSharpCode.ShortcutsManagement.Data @@ -153,8 +153,8 @@ namespace ICSharpCode.ShortcutsManagement.Data
/// <returns>Comparison result</returns>
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);

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

@ -52,7 +52,7 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -52,7 +52,7 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
/// <summary>
/// Stores shortcut entry to input binding convertion map
/// </summary>
private readonly Dictionary<Shortcut, InputBindingInfo> shortcutsMap = new Dictionary<Shortcut, InputBindingInfo>();
private readonly MapTable<Shortcut, InputBindingInfo> shortcutsMap = new MapTable<Shortcut, InputBindingInfo>();
private List<IShortcutTreeEntry> rootEntries;
@ -91,7 +91,6 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -91,7 +91,6 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
}
BindProfiles();
BindShortcuts();
}
private void BindProfiles()
@ -130,90 +129,58 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -130,90 +129,58 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
private void BindShortcuts()
{
shortcutsMap.Clear();
// Root shortcut tree entries
rootEntries = new List<IShortcutTreeEntry>();
// Stores SD input binding category to category section convertion map
var categoriesMap = new Dictionary<InputBindingCategory, ShortcutCategory>();
var categoriesMap = new MapTable<InputBindingCategory, ShortcutCategory>();
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<ShortcutCategory>();
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<ShortcutCategory>();
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 @@ -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 @@ -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 @@ -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);
}
}

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

@ -202,6 +202,15 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -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 @@ -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 @@ -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);

2
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -75,6 +75,8 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -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 =

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

@ -66,6 +66,7 @@ @@ -66,6 +66,7 @@
<Compile Include="Src\AddInTree\AddIn\DefaultDoozers\Command\GesturesPlaceHolderDoozer.cs" />
<Compile Include="Src\AddInTree\AddIn\DefaultDoozers\Command\InputBindingDescriptor.cs" />
<Compile Include="Src\AddInTree\AddIn\DefaultDoozers\Command\InputBindingDoozer.cs" />
<Compile Include="Src\AddInTree\AddIn\DefaultDoozers\Command\InputBindingCategoryDoozer.cs" />
<Compile Include="Src\AddInTree\AddIn\DefaultDoozers\Command\RoutedUICommandDescriptor.cs" />
<Compile Include="Src\AddInTree\AddIn\DefaultDoozers\Command\RoutedUICommandDoozer.cs" />
<Compile Include="Src\AddInTree\AddIn\DefaultDoozers\MenuItem\MenuRootDoozer.cs" />

48
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingCategoryDoozer.cs

@ -0,0 +1,48 @@ @@ -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
{
/// <summary>
/// Description of InputBindingInfoCategory.
/// </summary>
public class InputBindingCategoryDoozer : IDoozer
{
/// <see cref="IDoozer.HandleConditions" />
public bool HandleConditions {
get {
return true;
}
}
/// <see cref="IDoozer.BuildItem(object, Codon, System.Collections.ArrayList)">
/// Builds InputBindingDescriptor
/// </see>
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<InputBindingCategoryDescriptor> Children;
public InputBindingCategoryDescriptor(Codon codon, System.Collections.ArrayList subItems) {
Id = codon.Properties["id"];
Text = codon.Properties["text"];
Children = subItems != null ? subItems.Cast<InputBindingCategoryDescriptor>().ToList() : new List<InputBindingCategoryDescriptor>();
}
}
}

9
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuRootDoozer.cs

@ -37,11 +37,6 @@ namespace ICSharpCode.Core @@ -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 @@ -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"];
}
}
}
}

1
src/Main/Core/Project/Src/AddInTree/AddInTree.cs

@ -35,6 +35,7 @@ namespace ICSharpCode.Core @@ -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());

103
src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandManager.cs

@ -1,4 +1,5 @@ @@ -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 @@ -49,7 +50,7 @@ namespace ICSharpCode.Core.Presentation
private static Dictionary<string, Type> namedUITypes = new Dictionary<string, Type>();
// Categories
private static List<InputBindingCategory> categories = new List<InputBindingCategory>();
public static List<InputBindingCategory> InputBindingCategories = new List<InputBindingCategory>();
/// <summary>
/// Register UI element instance accessible by unique name
@ -492,7 +493,11 @@ namespace ICSharpCode.Core.Presentation @@ -492,7 +493,11 @@ namespace ICSharpCode.Core.Presentation
/// <param name="handler">Update handler</param>
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);
}
/// <summary>
@ -593,14 +598,9 @@ namespace ICSharpCode.Core.Presentation @@ -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<BindingsUpdatedHandler> handlers = null;
if(updateHandlerPair is KeyValuePair<string, List<BindingsUpdatedHandler>>) {
handlers = ((KeyValuePair<string, List<BindingsUpdatedHandler>>)updateHandlerPair).Value;
} else if(updateHandlerPair is KeyValuePair<object, List<BindingsUpdatedHandler>>) {
handlers = ((KeyValuePair<object, List<BindingsUpdatedHandler>>)updateHandlerPair).Value;
}
var handlers = (List<BindingsUpdatedHandler>)updateHandlerPair.Value;
if(handlers != null) {
foreach(var handler in handlers) {
@ -739,49 +739,62 @@ namespace ICSharpCode.Core.Presentation @@ -739,49 +739,62 @@ 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>();
if(string.IsNullOrEmpty(categoriesString)) {
return registeredCategories;
public static InputBindingCategory GetInputBindingCategory(string categoryPath, bool throwWhenNotFound)
{
foreach(var category in InputBindingCategories) {
if(category.Path == categoryPath) {
return category;
}
}
// 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;
if(throwWhenNotFound) {
throw new ApplicationException(string.Format("InputBindingCategory with path {0} was not found", categoryPath));
}
return null;
}
public static ICollection<InputBindingCategory> GetInputBindingCategoryCollection(string categoryPathCollectionString, bool throwWhenNotFound)
{
var categoryPathCollection = categoryPathCollectionString.Split(',');
var categories = new List<InputBindingCategory>();
foreach(var categoryPath in categoryPathCollection) {
var category = CommandManager.GetInputBindingCategory(categoryPath, throwWhenNotFound);
// 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);
if(category != null) {
categories.Add(category);
}
}
return categories;
}
public static IEnumerable<InputBindingCategory> GetInputBindingCategoryChildren(string categoryPath)
{
var categoryDepth = categoryPath.Count(c => c == '/');
foreach(var currentCategory in InputBindingCategories) {
if(currentCategory.Path.StartsWith(categoryPath)) {
var currentCategoryDepth = currentCategory.Path.Count(c => c == '/');
if(currentCategoryDepth == categoryDepth + 1)
{
yield return currentCategory;
}
parentCategory = matchingCategory;
}
registeredCategories.Add(parentCategory);
}
}
public static void RegisterInputBindingCategory(InputBindingCategory category)
{
if(string.IsNullOrEmpty(category.Path)) {
throw new ArgumentException("InputBindingCategory path can not be empty");
}
if(string.IsNullOrEmpty(category.Text)) {
throw new ArgumentException("InputBindingCategory text can not be empty");
}
return registeredCategories;
InputBindingCategories.Add(category);
}
/// <summary>

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

@ -3,6 +3,7 @@ using System.Reflection; @@ -3,6 +3,7 @@ using System.Reflection;
using System.Windows.Input;
using System.Windows.Documents;
using System.Text;
using System.Collections.Generic;
using System.Collections;
using ICSharpCode.Core;
@ -17,7 +18,7 @@ namespace ICSharpCode.Core.Presentation @@ -17,7 +18,7 @@ namespace ICSharpCode.Core.Presentation
{
var menuRoots = AddInTree.BuildItems<MenuRootDescriptor>(menuRootsLocationPath, caller);
foreach(var menuRoot in menuRoots) {
CommandsService.RegisterSingleMenuBindings(menuRoot.Path, caller, menuRoot.Name);
CommandsService.RegisterSingleMenuBindings(menuRoot.Path, caller, menuRoot.Category);
}
}
@ -69,19 +70,24 @@ namespace ICSharpCode.Core.Presentation @@ -69,19 +70,24 @@ namespace ICSharpCode.Core.Presentation
var defaultGesture = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromInvariantString(codon.Properties["shortcut"]);
inputBindingInfo.DefaultGestures.AddRange(defaultGesture);
var menuCategories = CommandManager.RegisterInputBindingCategories(categoryPath);
inputBindingInfo.Categories.AddRange(menuCategories);
// Menu category
var menuCategory = CommandManager.GetInputBindingCategory(categoryPath, true);
inputBindingInfo.Categories.Add(menuCategory);
// User defined categories
if(codon.Properties.Contains("category")) {
var userDefinedCategories = CommandManager.RegisterInputBindingCategories(codon.Properties["category"]);
inputBindingInfo.Categories.AddRange(userDefinedCategories);
var additionalCategories = CommandManager.GetInputBindingCategoryCollection(codon.Properties["category"], true);
inputBindingInfo.Categories.AddRange(additionalCategories);
}
CommandManager.RegisterInputBinding(inputBindingInfo);
}
if(item.SubItems != null) {
RegisterSingleMenuBindings(item.SubItems, caller, categoryPath + "/" + item.Codon.Properties["label"]);
var subMenuCategory = new InputBindingCategory(categoryPath + "/" + item.Codon.Id, codon.Properties["label"]);
CommandManager.RegisterInputBindingCategory(subMenuCategory);
RegisterSingleMenuBindings(item.SubItems, caller, categoryPath + "/" + item.Codon.Id);
}
}
}
@ -102,6 +108,27 @@ namespace ICSharpCode.Core.Presentation @@ -102,6 +108,27 @@ namespace ICSharpCode.Core.Presentation
RegisterRoutedCommands(typeof(EditingCommands));
}
public static void RegisterInputBindingCategories(object caller, string path) {
var descriptors = AddInTree.BuildItems<InputBindingCategoryDescriptor>(path, caller, false);
foreach(var desc in descriptors)
{
RegisterInputBindingCategories(desc, "");
}
}
private static void RegisterInputBindingCategories(InputBindingCategoryDescriptor descriptor, string categoryPath)
{
categoryPath = categoryPath + "/" + descriptor.Id;
var category = new InputBindingCategory(categoryPath, descriptor.Text);
CommandManager.RegisterInputBindingCategory(category);
foreach(var desc in descriptor.Children)
{
RegisterInputBindingCategories(desc, categoryPath);
}
}
public static void RegisterRoutedUICommands(object caller, string path)
{
var descriptors = AddInTree.BuildItems<RoutedUICommandDescriptor>(path, caller, false);
@ -161,7 +188,8 @@ namespace ICSharpCode.Core.Presentation @@ -161,7 +188,8 @@ namespace ICSharpCode.Core.Presentation
}
if(!string.IsNullOrEmpty(desc.Category)) {
inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories(desc.Category));
var categories = CommandManager.GetInputBindingCategoryCollection(desc.Category, true);
inputBindingInfo.Categories.AddRange(categories);
}
CommandManager.RegisterInputBinding(inputBindingInfo);
@ -194,7 +222,8 @@ namespace ICSharpCode.Core.Presentation @@ -194,7 +222,8 @@ namespace ICSharpCode.Core.Presentation
}
if(!string.IsNullOrEmpty(desc.Category)) {
inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories(desc.Category));
var categories = CommandManager.GetInputBindingCategoryCollection(desc.Category, true);
inputBindingInfo.Categories.AddRange(categories);
}
CommandManager.RegisterInputBinding(inputBindingInfo);

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

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
using System;
using System.Linq;
using System.Collections.Generic;
namespace ICSharpCode.Core.Presentation
{
@ -12,16 +14,20 @@ namespace ICSharpCode.Core.Presentation @@ -12,16 +14,20 @@ namespace ICSharpCode.Core.Presentation
/// </summary>
/// <param name="name">Category name</param>
/// <param name="parentCategory">Parent category (null - root level category)</param>
public InputBindingCategory(string name, InputBindingCategory parentCategory)
public InputBindingCategory(string path, string text)
{
Name = name;
ParentCategory = parentCategory;
if(path == "/ContextMenus/Tabs")
{
}
Path = path;
Text = text;
}
/// <summary>
/// Category name
/// </summary>
public string Name
public string Text
{
get; set;
}
@ -29,9 +35,12 @@ namespace ICSharpCode.Core.Presentation @@ -29,9 +35,12 @@ namespace ICSharpCode.Core.Presentation
/// <summary>
/// Reference to parent category
/// </summary>
public InputBindingCategory ParentCategory
public List<InputBindingCategory> Children
{
get; set;
get
{
return CommandManager.GetInputBindingCategoryChildren(Path).ToList();
}
}
/// <summary>
@ -40,8 +49,12 @@ namespace ICSharpCode.Core.Presentation @@ -40,8 +49,12 @@ namespace ICSharpCode.Core.Presentation
/// Format:
/// /category/subcategory
/// </summary>
internal string Path {
public string Path {
get; set;
}
public override string ToString() {
return Path;
}
}
}

85
src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingCategoryCollection.cs

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
/*
* Created by SharpDevelop.
* User: Administrator
* Date: 7/4/2009
* Time: 9:02 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
namespace ICSharpCode.Core.Presentation
{
/// <summary>
/// Description of InputBindingCategoryCollection.
/// </summary>
public class InputBindingCategoryCollection : ICollection<InputBindingCategory>
{
private List<InputBindingCategory> categories = new List<InputBindingCategory>();
public InputBindingCategoryCollection()
{
}
public int Count {
get {
return categories.Count;
}
}
public bool IsReadOnly {
get {
return false;
}
}
public void Add(InputBindingCategory category)
{
if(category == null) {
throw new ArgumentException("InputBindingCategory can not be null");
}
if(!categories.Contains(category)) {
categories.Add(category);
}
}
public void Clear()
{
categories.Clear();
}
public bool Contains(InputBindingCategory category)
{
return categories.Contains(category);
}
public void AddRange(IEnumerable<InputBindingCategory> categories)
{
foreach(var category in categories) {
Add(category);
}
}
public void CopyTo(InputBindingCategory[] array, int arrayIndex)
{
categories.CopyTo(array, arrayIndex);
}
public bool Remove(InputBindingCategory category)
{
return categories.Remove(category);
}
public IEnumerator<InputBindingCategory> GetEnumerator()
{
return categories.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return categories.GetEnumerator();
}
}
}

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

@ -19,8 +19,7 @@ namespace ICSharpCode.Core.Presentation @@ -19,8 +19,7 @@ namespace ICSharpCode.Core.Presentation
OldInputBindings = new InputBindingCollection();
NewInputBindings = new InputBindingCollection();
DefaultGestures = new InputGestureCollection();
Categories = new List<InputBindingCategory>();
Categories = new InputBindingCategoryCollection();
}
public string ownerInstanceName;
@ -179,7 +178,7 @@ namespace ICSharpCode.Core.Presentation @@ -179,7 +178,7 @@ namespace ICSharpCode.Core.Presentation
/// <summary>
/// List of categories associated with input binding
/// </summary>
public List<InputBindingCategory> Categories {
public InputBindingCategoryCollection Categories {
get; private set;
}

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

@ -72,6 +72,7 @@ @@ -72,6 +72,7 @@
<Compile Include="CommandsService\CommandsService.cs" />
<Compile Include="CommandsService\GesturePlaceHolderRegistry.cs" />
<Compile Include="CommandsService\InputBindingCategory.cs" />
<Compile Include="CommandsService\InputBindingCategoryCollection.cs" />
<Compile Include="CommandsService\InputBindingInfo.cs" />
<Compile Include="CommandsService\UserDefinedGesturesManager.cs" />
<Compile Include="CommandsService\UserGesturesProfile.cs" />

Loading…
Cancel
Save