Skip to content
This repository has been archived by the owner on Oct 16, 2020. It is now read-only.

Commit

Permalink
InputBindingCategory class, nested categories
Browse files Browse the repository at this point in the history
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4285 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
  • Loading branch information
sandrejev committed Jun 12, 2009
1 parent 11471cd commit cf7680a
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 113 deletions.
16 changes: 16 additions & 0 deletions AddIns/ICSharpCode.SharpDevelop.addin
Expand Up @@ -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" />
Expand Down
Binary file modified src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo
Binary file not shown.
Expand Up @@ -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>
Expand Up @@ -261,7 +261,8 @@ private static bool Filter(ShortcutCategory category, string filterString, bool?
}
}

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;
}
}
}
Expand Up @@ -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" />
Expand Down
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using System.Windows.Controls;
using System.Windows.Input;
Expand All @@ -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();
Expand All @@ -154,10 +150,9 @@ public void LoadOptions()
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;

Expand Down

0 comments on commit cf7680a

Please sign in to comment.