Browse Source

CategoryManager fixes. More support for menu builders and some for context menus

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4364 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts^2
Sergej Andrejev 16 years ago
parent
commit
3b4db44ffc
  1. 51
      AddIns/ICSharpCode.SharpDevelop.addin
  2. 4
      src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.addin
  3. 3
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  4. BIN
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo
  5. 1
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj
  6. 29
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/GestureFilterMode.cs
  7. 4
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsFinder.cs
  8. 6
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/Resources.xaml
  9. 201
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
  10. 1
      src/AddIns/Misc/UnitTesting/Src/TestClass.cs
  11. 59
      src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
  12. 36
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
  13. 4
      src/Main/Base/Project/Src/TextEditor/Codons/EditActionDoozer.cs
  14. 1
      src/Main/Core/Project/ICSharpCode.Core.csproj
  15. 66
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuRootDoozer.cs
  16. 1
      src/Main/Core/Project/Src/AddInTree/AddInTree.cs
  17. 10
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs
  18. 216
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandManager.cs
  19. 86
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
  20. 37
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
  21. 42
      src/Main/ICSharpCode.Core.Presentation/CommandsService/UserDefinedGesturesManager.cs
  22. 41
      src/Main/ICSharpCode.Core.Presentation/Input/InputGestureCollectionExtensions.cs
  23. 61
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
  24. 13
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
  25. 21
      src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs
  26. 16
      src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs

51
AddIns/ICSharpCode.SharpDevelop.addin

@ -67,6 +67,22 @@ @@ -67,6 +67,22 @@
</Categoru>
</Path>
<Path name="/SharpDevelop/MenuLocations">
<MenuRoot path="/SharpDevelop/Workbench/MainMenu" name="Main Menu" />
<MenuRoot path="/SharpDevelop/Workbench/OpenFileTab/ContextMenu" name="Context menus/Tabs" />
<MenuRoot path="/SharpDevelop/ViewContent/AvalonEdit/ContextMenu" name="Context menus/Text Editor" />
<MenuRoot path="/SharpDevelop/ViewContent/TextEditor/ContextMenu" name="Context menus/Text Editor" />
<MenuRoot path="/SharpDevelop/ViewContent/DefaultTextEditor/ClassMemberContextMenu" name="Context menus/Text Editor" />
<MenuRoot path="/SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu" name="Context menus/Text Editor" />
<MenuRoot path="/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/Common" name="Context menus/Text Editor/Refactoring" />
<MenuRoot path="/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/Parameter" name="Context menus/Text Editor/Refactoring" />
<MenuRoot path="/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/LocalVariable" name="Context menus/Text Editor/Refactoring" />
<MenuRoot path="/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/ParameterDefinition" name="Context menus/Text Editor/Refactoring" />
<MenuRoot path="/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/LocalVariableDefinition" name="Context menus/Text Editor/Refactoring" />
</Path>
<Path name="/SharpDevelop/Workbench/RoutedUICommands">
<RoutedUICommand name="SDTestCommands.Test" text="Create new file" />
@ -270,6 +286,7 @@ @@ -270,6 +286,7 @@
</Path>
<Path name="/SharpDevelop/Workbench/InputBindings">
</Path>
<Path name = "/SharpDevelop/Workbench/Ambiences">
@ -495,6 +512,7 @@ @@ -495,6 +512,7 @@
<Include id="CutPasteRemoveRename" path="/SharpDevelop/Pads/ProjectBrowser/ContextMenu/CutPasteRemoveRename"/>
</Path>
<Path path = "/SharpDevelop/Pads/ProjectBrowser/ContextMenu/SolutionItemNode">
<MenuItem id = "OpenFile"
label = "${res:ProjectComponent.ContextMenu.Open}"
@ -508,6 +526,7 @@ @@ -508,6 +526,7 @@
<Include id="CutCopyRemoveRename" path="/SharpDevelop/Pads/ProjectBrowser/ContextMenu/CutCopyRemoveRename"/>
</Path>
<Path path = "/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectNode">
<MenuItem id = "Build project"
label = "${res:ProjectComponent.ContextMenu.Build}"
@ -730,6 +749,7 @@ @@ -730,6 +749,7 @@
class = "ICSharpCode.SharpDevelop.Project.Commands.RenameEntryEvent"/>
</Path>
<Path name = "/SharpDevelop/Pads/ProjectBrowser/ContextMenu/CutCopyPasteDeleteRename">
<MenuItem id = "Cut"
label = "${res:XML.MainMenu.EditMenu.Cut}"
@ -1786,7 +1806,7 @@ @@ -1786,7 +1806,7 @@
<MenuItem id = "Step out"
label = "${res:XML.MainMenu.DebugMenu.StepOut}"
icon = "Icons.16x16.Debug.StepOut"
shortcut = "Shift|F11"
shortcut = "Shift+F11"
class = "ICSharpCode.SharpDevelop.Project.Commands.StepOutDebuggingCommand"
command = "SDDebugCommands.StepOut" />
</Condition>
@ -1810,22 +1830,22 @@ @@ -1810,22 +1830,22 @@
<MenuItem id = "Search" label = "${res:XML.MainMenu.SearchMenu}" type="Menu">
<MenuItem id = "SearchIncremental"
label = "${res:XML.MainMenu.SearchMenu.IncrementalSearch}"
shortcut = "Control|E"
shortcut = "Ctrl+E"
class = "ICSharpCode.SharpDevelop.DefaultEditor.Commands.RunIncrementalSearch"/>
<MenuItem id = "SearchReverseIncremental"
label = "${res:XML.MainMenu.SearchMenu.ReverseIncrementalSearch}"
shortcut = "Control|Shift|E"
shortcut = "Ctrl+Shift+E"
class = "ICSharpCode.SharpDevelop.DefaultEditor.Commands.RunReverseIncrementalSearch"/>
<MenuItem id = "SearchInFilesSeparator" type = "Separator" />
<!-- <Condition name = "WindowActive" activewindow="ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.ITextEditorControlProvider" action="Disable"> -->
<MenuItem id = "ToggleBookmark"
label = "${res:XML.MainMenu.SearchMenu.ToggleBookmark}"
shortcut = "Control|F2"
shortcut = "Ctrl+F2"
icon = "Bookmarks.ToggleMark"
class = "ICSharpCode.SharpDevelop.Bookmarks.ToggleBookmark"/>
<MenuItem id = "PrevBookmark"
label = "${res:XML.MainMenu.SearchMenu.PrevBookmark}"
shortcut = "Alt|F2"
shortcut = "Alt+F2"
icon = "Bookmarks.GotoPrevInFile"
class = "ICSharpCode.SharpDevelop.Bookmarks.PrevBookmark"/>
<MenuItem id = "NextBookmark"
@ -1840,12 +1860,12 @@ @@ -1840,12 +1860,12 @@
<MenuItem id = "Separator2" type = "Separator" />
<MenuItem id = "GotoLineNr"
label = "${res:XML.MainMenu.SearchMenu.GotoLineNr}"
shortcut = "Control|G"
shortcut = "Ctrl+G"
class = "ICSharpCode.SharpDevelop.DefaultEditor.Commands.GotoLineNumber"/>
<MenuItem id = "Separator3" type = "Separator" />
<MenuItem id = "GotoBrace"
label = "${res:XML.MainMenu.SearchMenu.GotoBrace}"
shortcut = "Control|B"
shortcut = "Ctrl+B"
class = "ICSharpCode.SharpDevelop.DefaultEditor.Commands.GotoMatchingBrace"/>
<!-- </Condition> -->
</MenuItem>
@ -1895,7 +1915,8 @@ @@ -1895,7 +1915,8 @@
<MenuItem id = "Options"
label = "${res:XML.MainMenu.ToolMenu.Options}"
icon = "Icons.16x16.Options"
class = "ICSharpCode.SharpDevelop.Commands.OptionsCommand"/>
class = "ICSharpCode.SharpDevelop.Commands.OptionsCommand"
shortcut = "Ctrl+OemComma" />
</MenuItem> <!-- end TOOLS menu -->
<MenuItem id = "Window" label = "${res:XML.MainMenu.WindowMenu}" type="Menu">
@ -1908,7 +1929,7 @@ @@ -1908,7 +1929,7 @@
<MenuItem id = "PrevWindow"
label = "${res:XML.MainMenu.WindowMenu.PrvWindow}"
icon = "Icons.16x16.PrevWindowIcon"
shortcut = "Shift|Control|Tab"
shortcut = "Ctrl+Shift+Tab"
class = "ICSharpCode.SharpDevelop.Commands.SelectPrevWindow" />
<MenuItem id ="NxtPrvSeparator" type = "Separator" />
<MenuItem id = "SplitView"
@ -2181,15 +2202,15 @@ @@ -2181,15 +2202,15 @@
<Condition name = "WindowActive" activewindow="ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.ITextEditorControlProvider" action="Disable">
<MenuItem id = "ToggleFolding"
label = "${res:XML.MainMenu.EditMenu.FoldingMenu.ToggleFolding}"
shortcut = "Shift|Control|M"
shortcut = "Ctrl+Shift+M"
class = "ICSharpCode.SharpDevelop.DefaultEditor.Commands.ToggleFolding"/>
<MenuItem id = "ToggleAllFoldings"
label = "${res:XML.MainMenu.EditMenu.FoldingMenu.ToggleAllFoldings}"
shortcut = "Shift|Control|L"
shortcut = "Ctrl+Shift+L"
class = "ICSharpCode.SharpDevelop.DefaultEditor.Commands.ToggleAllFoldings"/>
<MenuItem id = "ShowDefinitionsOnly"
label = "${res:XML.MainMenu.EditMenu.FoldingMenu.ShowDefinitions}"
shortcut = "Shift|Control|P"
shortcut = "Ctrl+Shift+P"
class = "ICSharpCode.SharpDevelop.DefaultEditor.Commands.ShowDefinitionsOnly"/>
</Condition>
</MenuItem>
@ -2279,9 +2300,9 @@ @@ -2279,9 +2300,9 @@
they're used for the standalone version too, only put keys in the
tree that are sharpdevelop specific, general keys put into TextAreaControl.GenerateDefaultActions -->
<Path name = "/AddIns/DefaultTextEditor/EditActions">
<EditAction id = "TemplateCompletion" class = "ICSharpCode.SharpDevelop.DefaultEditor.Actions.TemplateCompletion" keys = "Control|J"/>
<EditAction id = "CodeCompletionPopup" class = "ICSharpCode.SharpDevelop.DefaultEditor.Actions.CodeCompletionPopup" keys = "Control|Space"/>
<EditAction id = "GoToDefinition" class = "ICSharpCode.SharpDevelop.DefaultEditor.Actions.GoToDefinition" keys = "Control|Enter"/>
<EditAction id = "TemplateCompletion" class = "ICSharpCode.SharpDevelop.DefaultEditor.Actions.TemplateCompletion" keys = "Ctrl+J"/>
<EditAction id = "CodeCompletionPopup" class = "ICSharpCode.SharpDevelop.DefaultEditor.Actions.CodeCompletionPopup" keys = "Ctrl+Space"/>
<EditAction id = "GoToDefinition" class = "ICSharpCode.SharpDevelop.DefaultEditor.Actions.GoToDefinition" keys = "Ctrl+Enter"/>
<EditAction id = "ExpandTemplateAction" class = "ICSharpCode.SharpDevelop.DefaultEditor.Actions.ExpandTemplateAction" keys = "Tab"/>
</Path>

4
src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.addin

@ -60,12 +60,12 @@ @@ -60,12 +60,12 @@
icon="Icons.16x16.RunProgramIcon"
class="ICSharpCode.PythonBinding.RunDebugPythonCommand"
label="${res:XML.MainMenu.RunMenu.Run}"
shortcut="Control|Shift|R"/>
shortcut="Ctrl+Shift+R"/>
<MenuItem id="RunWithoutDebugger"
icon="Icons.16x16.Debug.StartWithoutDebugging"
class="ICSharpCode.PythonBinding.RunPythonCommand"
label="${res:XML.MainMenu.DebugMenu.RunWithoutDebug}"
shortcut="Control|Shift|W"/>
shortcut="Ctrl+Shift+W"/>
</Condition>
<Condition name="IsProcessRunning" isdebugging="True" action="Disable">
<MenuItem id="Stop"

3
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs

@ -124,12 +124,9 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -124,12 +124,9 @@ namespace ICSharpCode.AvalonEdit.AddIn
commandBindingInfo.RoutedCommandName = "SDWindowCommands.SplitView";
commandBindingInfo.ExecutedEventHandler = OnSplitView;
commandBindingInfo.CanExecuteEventHandler = OnCanSplitView;
commandBindingInfo.Name = "CodeEditorCommandBinding";
CommandManager.RegisterCommandBinding(commandBindingInfo);
}
public CodeEditor()
{
textMarkerService = new TextMarkerService(this);

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

Binary file not shown.

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

@ -126,6 +126,7 @@ @@ -126,6 +126,7 @@
<DependentUpon>Window1.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Content Include="ShortcutsManagement.cd" />
</ItemGroup>
<ItemGroup>
<Compile Include="Src\Converters\BoolToVisibilityConverter.cs" />

29
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/GestureFilterMode.cs

@ -1,29 +0,0 @@ @@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.ShortcutsManagement.Data
{
/// <summary>
/// Gesture filtering mode
/// </summary>
public enum GestureFilterMode
{
/// <summary>
/// Match is successful if template gesture strictly matches compared gesture
/// </summary>
StrictlyMatches,
/// <summary>
/// Match is successfull if template gesture partly matches compared geture.
/// Template is found in any place within matched gesture
/// </summary>
PartlyMatches,
/// <summary>
/// match is successfull if matched gesture starts with provided template
/// </summary>
StartsWith
}
}

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

@ -34,7 +34,7 @@ namespace ICSharpCode.ShortcutsManagement.Data @@ -34,7 +34,7 @@ namespace ICSharpCode.ShortcutsManagement.Data
/// Also this function hides parent categories and Add-in if it has no sub
/// elements left
/// </summary>
/// <param name="shortcut">Shortcut to be heden</param>
/// <param name="shortcut">Shortcut to be hidden</param>
public void HideShortcut(Shortcut shortcut)
{
foreach (var entry in RootEntries) {
@ -77,7 +77,7 @@ namespace ICSharpCode.ShortcutsManagement.Data @@ -77,7 +77,7 @@ namespace ICSharpCode.ShortcutsManagement.Data
// Determine whether provided shortcut is in provided category and
// hide it if so
foreach (var shortcut in category.Shortcuts) {
if (shortcut == filteredShortcut) {
if (shortcut.Id == filteredShortcut.Id) {
shortcut.IsVisible = false;
}

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

@ -98,7 +98,7 @@ @@ -98,7 +98,7 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<Border Name="OuterBorder" BorderThickness="2" CornerRadius="8" Margin="20,0,0,0">
<Border Name="OuterBorder" BorderThickness="2" CornerRadius="8">
<StackPanel>
<Border Name="InnerBorder" Background="White" BorderThickness="0.6" CornerRadius="8" Padding="0,6,6,6" >
<Grid>
@ -110,7 +110,9 @@ @@ -110,7 +110,9 @@
<ContentPresenter Name="PART_Header" ContentSource="Header" VerticalAlignment="Center" Grid.Column="1" />
</Grid>
</Border>
<ItemsPresenter x:Name="ItemsHost" />
<Border Name="ItemsBorder" Margin="20,0,0,0" >
<ItemsPresenter x:Name="ItemsHost" />
</Border>
</StackPanel>
</Border>
<ControlTemplate.Triggers>

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

@ -31,9 +31,137 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -31,9 +31,137 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
}
public void LoadOptions()
{
var rootEntries = GetCategoryRootEntries();
new ShortcutsFinder(rootEntries).Filter("");
shortcutsManagementOptionsPanel.DataContext = rootEntries;
}
private List<IShortcutTreeEntry> GetCategoryRootEntries()
{
// Root shortcut tree entries
var rootEntries = new List<IShortcutTreeEntry>();
// Stores SD input binding category to category section convertion map
var categoriesMap = new Dictionary<InputBindingCategory, ShortcutCategory>();
var unspecifiedCategory = new ShortcutCategory("Uncategorized");
rootEntries.Add(unspecifiedCategory);
// Go through all input bindings
var inputBindingInfos = CommandManager.FindInputBindingInfos(null, null, null);
foreach (var inputBindingInfo in inputBindingInfos)
{
// 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)
{
ShortcutCategory categorySection;
if (categoriesMap.ContainsKey(bindingCategory))
{
// If found appropriate category assign shortcut to it
categorySection = categoriesMap[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);
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);
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);
}
}
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;
}
shortcutText = StringParser.Parse(shortcutText);
// Some commands have "&" sign to mark alternative key used to call this command from menu
// Strip this sign from shortcut entry text
shortcutText = Regex.Replace(shortcutText, @"&([^\s])", @"$1");
var shortcut = new Shortcut(shortcutText, inputBindingInfo.Gestures);
// Assign shortcut to all categories it is registered in
foreach (var categorySection in shortcutCategorySections)
{
categorySection.Shortcuts.Add(shortcut);
}
shortcutsMap.Add(shortcut, inputBindingInfo);
}
rootEntries.Sort();
foreach (var entry in rootEntries)
{
entry.SortSubEntries();
}
return rootEntries;
}
private List<IShortcutTreeEntry> GetAddinRootEntries()
{
// Root shortcut tree entries
var rootEntries = new List<IShortcutTreeEntry>();
var rootEntries = new List<IShortcutTreeEntry>();
// Stores SD add-in to add-in section convertion map
var addInsMap = new Dictionary<AddIn, ShortcutManagement.AddIn>();
@ -47,15 +175,21 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -47,15 +175,21 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
rootEntries.Add(unspecifiedAddInSection);
// Go through all input bindings
var inputBindingInfos = CommandManager.FindInputBindingInfos(null, null, null, null, null);
foreach(var inputBindingInfo in inputBindingInfos) {
var inputBindingInfos = CommandManager.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)) {
}
else if (addInsMap.ContainsKey(inputBindingInfo.AddIn))
{
addinSection = addInsMap[inputBindingInfo.AddIn];
} else {
}
else
{
addinSection = new ShortcutManagement.AddIn(inputBindingInfo.AddIn.Name);
addinSection.Categories.Add(new ShortcutCategory(StringParser.Parse("${res:ShortcutsManagement.UnspecifiedCategoryName}")));
addInsMap.Add(inputBindingInfo.AddIn, addinSection);
@ -65,43 +199,56 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -65,43 +199,56 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
// 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 (inputBindingInfo.Categories.Count == 0)
{
// If no category specified assign to "Uncotegorized" category
shortcutCategorySections.Add(addinSection.Categories[0]);
} else {
}
else
{
// Go throu all categories and find or create appropriate category sections
foreach (var bindingCategory in inputBindingInfo.Categories) {
foreach (var bindingCategory in inputBindingInfo.Categories)
{
ShortcutCategory categorySection;
if (categoriesMap[addinSection].ContainsKey(bindingCategory)) {
if (categoriesMap[addinSection].ContainsKey(bindingCategory))
{
// If found appropriate category assign shortcut to it
categorySection = categoriesMap[addinSection][bindingCategory];
} else {
}
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[addinSection].Add(bindingCategory, categorySection);
// Go down to root level and create all parent categories
var currentBindingCategory = bindingCategory;
var currentShortcutCategory = categorySection;
while (currentBindingCategory.ParentCategory != null) {
while (currentBindingCategory.ParentCategory != null)
{
ShortcutCategory parentCategorySection;
if (!categoriesMap[addinSection].ContainsKey(currentBindingCategory.ParentCategory)) {
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 {
}
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)) {
if (!parentCategorySection.SubCategories.Contains(currentShortcutCategory))
{
parentCategorySection.SubCategories.Add(currentShortcutCategory);
}
@ -110,7 +257,8 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -110,7 +257,8 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
}
// Add root category section to add-in categories list
if (!addinSection.Categories.Contains(currentShortcutCategory)) {
if (!addinSection.Categories.Contains(currentShortcutCategory))
{
addinSection.Categories.Add(currentShortcutCategory);
}
}
@ -122,7 +270,8 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -122,7 +270,8 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
// 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)) {
if (!string.IsNullOrEmpty(inputBindingInfo.RoutedCommandText))
{
shortcutText = inputBindingInfo.RoutedCommandText;
}
@ -133,13 +282,14 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -133,13 +282,14 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
shortcutText = Regex.Replace(shortcutText, @"&([^\s])", @"$1");
var shortcut = new Shortcut(shortcutText, inputBindingInfo.Gestures);
// Assign shortcut to all categories it is registered in
foreach (var categorySection in shortcutCategorySections) {
foreach (var categorySection in shortcutCategorySections)
{
categorySection.Shortcuts.Add(shortcut);
}
shortcutsMap.Add(shortcut, inputBindingInfo);
shortcutsMap.Add(shortcut, inputBindingInfo);
}
rootEntries.Sort();
@ -148,8 +298,7 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -148,8 +298,7 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
entry.SortSubEntries();
}
new ShortcutsFinder(rootEntries).Filter("");
shortcutsManagementOptionsPanel.DataContext = rootEntries;
return rootEntries;
}
public bool SaveOptions()
@ -160,7 +309,11 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs @@ -160,7 +309,11 @@ namespace ICSharpCode.ShortcutsManagement.Dialogs
if (inputBindingInfo.Gestures.Count == shortcut.Gestures.Count) {
foreach (var gesture in shortcut.Gestures) {
inputBindingInfo.Gestures.ContainsCopy(gesture);
if(!inputBindingInfo.Gestures.ContainsTemplateFor(gesture, GestureCompareMode.ExactlyMatches))
{
inputBindingInfo.IsModifyed = true;
break;
}
}
} else {
inputBindingInfo.IsModifyed = true;

1
src/AddIns/Misc/UnitTesting/Src/TestClass.cs

@ -56,6 +56,7 @@ namespace ICSharpCode.UnitTesting @@ -56,6 +56,7 @@ namespace ICSharpCode.UnitTesting
}
}
}
return false;
}

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

@ -202,16 +202,47 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -202,16 +202,47 @@ namespace ICSharpCode.SharpDevelop.Commands
public class ToolMenuBuilder : IMenuItemBuilder
{
private bool bindingsAssigned = false;
public ICollection BuildItems(Codon codon, object owner)
{
var items = new System.Windows.Controls.MenuItem[ToolLoader.Tool.Count];
for (int i = 0; i < ToolLoader.Tool.Count; ++i) {
ExternalTool tool = ToolLoader.Tool[i];
items[i] = new System.Windows.Controls.MenuItem {
Header = tool.ToString()
};
items[i].Click += delegate { RunTool(tool); };
items[i] = new System.Windows.Controls.MenuItem();
var routedCommandName = "SDToolsCommands.RunExternalTool_" + tool.ToString();
var routedCommandText = MenuService.ConvertLabel(StringParser.Parse(tool.ToString()));
if(!bindingsAssigned) {
var addIn = AddInTree.AddIns.FirstOrDefault(a => a.Name == "SharpDevelop");
// Dynamicaly create routed UI command to loaded pad and bindings for it
CommandManager.RegisterRoutedUICommand(routedCommandName, routedCommandText);
var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.CanExecuteEventHandler = delegate(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; };
commandBindingInfo.ExecutedEventHandler = delegate { RunTool(tool); };
CommandManager.RegisterCommandBinding(commandBindingInfo);
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories("Main Menu/${res:XML.MainMenu.ToolMenu}/External tools"));
CommandManager.RegisterInputBinding(inputBindingInfo);
}
var updatedGestures = CommandManager.FindInputGestures(CommandManager.DefaultContextName, null, routedCommandName);
var updatedGesturesText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
items[i].InputGestureText = updatedGesturesText;
items[i].Command = CommandManager.GetRoutedUICommand(routedCommandName);
items[i].Header = StringParser.Parse(tool.ToString());
}
bindingsAssigned = true;
return items;
}
@ -488,21 +519,18 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -488,21 +519,18 @@ namespace ICSharpCode.SharpDevelop.Commands
commandBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.AddIn = addIn;
commandBindingInfo.Name = "ViewMenuCommandBinding_" + routedCommandName + "_" + routedCommandName + "_" + addIn.Name + "_" + CommandManager.DefaultContextName;
CommandManager.RegisterCommandBinding(commandBindingInfo);
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(padContent.Shortcut);
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = gestures;
inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories("Menu Items/Views"));
inputBindingInfo.AddIn = addIn;
inputBindingInfo.Name = "ViewMenuInputBinding_" + routedCommandName + "_" + routedCommandName + "_" + addIn.Name + "_" + CommandManager.DefaultContextName;
var menuPath = "Main Menu/${res:XML.MainMenu.ViewMenu}" + (padContent.Category == "Main" ? "" : "/" + padContent.Title);
inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories(menuPath));
inputBindingInfo.AddIn = addIn;
CommandManager.RegisterInputBinding(inputBindingInfo);
bindingsAssigned.Add(routedCommandName);
@ -510,19 +538,10 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -510,19 +538,10 @@ namespace ICSharpCode.SharpDevelop.Commands
item.Command = CommandManager.GetRoutedUICommand(routedCommandName);
var updatedGestures = CommandManager.FindInputGestures(CommandManager.DefaultContextName, null, null, null, routedCommandName);
var updatedGestures = CommandManager.FindInputGestures(CommandManager.DefaultContextName, null, routedCommandName);
var updatedGesturesText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
item.InputGestureText = updatedGesturesText;
// item.Command = new BringPadToFrontCommand(padContent);
// if (!string.IsNullOrEmpty(padContent.Shortcut)) {
// var kg = Core.Presentation.MenuService.ParseShortcut(padContent.Shortcut);
// WorkbenchSingleton.MainWindow.InputBindings.Add(
// new System.Windows.Input.InputBinding(item.Command, kg)
// );
// item.InputGestureText = kg.GetDisplayStringForCulture(Thread.CurrentThread.CurrentUICulture);
// }
list.Add(item);
}
}

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

@ -75,35 +75,27 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -75,35 +75,27 @@ namespace ICSharpCode.SharpDevelop.Gui
public void Initialize()
{
foreach (PadDescriptor content in AddInTree.BuildItems<PadDescriptor>(viewContentPath, this, false)) {
if (content != null) {
ShowPad(content);
}
}
CommandManager.DefaultContextName = this.GetType().AssemblyQualifiedName;
CommandsService.RegisterBuiltInRoutedUICommands();
// Use shortened assembly qualified name to not lose user defined gestures
// when sharp develop is updated
CommandManager.DefaultContextName =
string.Format("{0}, {1}", GetType().FullName, GetType().Assembly.GetName().Name);
CommandsService.RegisterBuiltInRoutedUICommands();
// Load all commands and and key bindings from addin tree
CommandsService.RegisterRoutedUICommands(this, "/SharpDevelop/Workbench/RoutedUICommands");
CommandsService.RegisterCommandBindings(this, "/SharpDevelop/Workbench/CommandBindings");
CommandsService.RegisterInputBindings(this, "/SharpDevelop/Workbench/InputBindings");
CommandsService.RegisterMenuBindings("/SharpDevelop/MenuLocations", this);
// Register context and load all commands from addin
CommandManager.LoadAddinCommands(AddInTree.AddIns.FirstOrDefault(a => a.Name == "SharpDevelop"));
//CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
// var newBindings = CommandsRegistry.FindCommandBindings(CommandsRegistry.DefaultContextName, null, null, null);
// CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
// CommandBindings.AddRange(newBindings);
//});
//CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
// var newBindings = CommandsRegistry.FindInputBindings(null, null, null);
// CommandsRegistry.RemoveManagedInputBindings(InputBindings);
// InputBindings.AddRange(newBindings);
//});
foreach (PadDescriptor content in AddInTree.BuildItems<PadDescriptor>(viewContentPath, this, false)) {
if (content != null) {
ShowPad(content);
}
}
mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath);

4
src/Main/Base/Project/Src/TextEditor/Codons/EditActionDoozer.cs

@ -20,8 +20,8 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Codons @@ -20,8 +20,8 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Codons
/// Creates IEditAction objects for the text editor.
/// </summary>
/// <attribute name="keys" use="required">
/// Comma-separated list of keyboard shortcuts that activate the edit action.
/// E.g. "Control|C,Control|Insert"
/// semicolon-separated list of keyboard shortcuts that activate the edit action.
/// E.g. "Ctrl+C;Ctrl+Insert"
/// </attribute>
/// <attribute name="class" use="required">
/// Name of the IEditAction class.

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

@ -68,6 +68,7 @@ @@ -68,6 +68,7 @@
<Compile Include="Src\AddInTree\AddIn\DefaultDoozers\Command\InputBindingDoozer.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" />
<Compile Include="Src\AddInTree\AddIn\ExtensionPath.cs" />
<Compile Include="Src\AddInTree\AddIn\IConditionEvaluator.cs" />
<Compile Include="Src\AddInTree\AddIn\ICondition.cs" />

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

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
/*
* Created by SharpDevelop.
* User: Administrator
* Date: 6/28/2009
* Time: 10:12 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections;
namespace ICSharpCode.Core
{
/// <summary>
/// Description of MenuDescriptionDoozer.
/// </summary>
public class MenuRootDoozer : IDoozer
{
public bool HandleConditions {
get {
return true;
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
{
return new MenuRootDescriptor(caller, codon);
}
}
public class MenuRootDescriptor
{
private Codon codon;
public string Category
{
get; private set;
}
public string Name
{
get; private set;
}
public string Path
{
get; private set;
}
public MenuRootDescriptor(object caller, Codon codon)
{
this.codon = codon;
Path = codon.Properties["path"];
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

@ -31,6 +31,7 @@ namespace ICSharpCode.Core @@ -31,6 +31,7 @@ namespace ICSharpCode.Core
doozers.Add("String", new StringDoozer());
doozers.Add("Icon", new IconDoozer());
doozers.Add("MenuItem", new MenuItemDoozer());
doozers.Add("MenuRoot", new MenuRootDoozer());
doozers.Add("ToolbarItem", new ToolbarItemDoozer());
doozers.Add("Include", new IncludeDoozer());
doozers.Add("InputBinding", new InputBindingDoozer());

10
src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs

@ -20,16 +20,6 @@ namespace ICSharpCode.Core.Presentation @@ -20,16 +20,6 @@ namespace ICSharpCode.Core.Presentation
NewCommandBindings = new CommandBindingCollection();
}
/// <summary>
/// Command binding info name
///
/// The name should be unique to register a command binding
/// </summary>
public string Name
{
get; set;
}
/// <summary>
/// Name of the routed command which will be invoked when this binding is triggered
/// </summary>

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

@ -21,11 +21,6 @@ namespace ICSharpCode.Core.Presentation @@ -21,11 +21,6 @@ namespace ICSharpCode.Core.Presentation
/// </summary>
public static class CommandManager
{
/// <summary>
/// This element is used to represent null key in dictionary
/// </summary>
private static UIElement NullUIElement = new UIElement();
/// <summary>
/// Default application context.
///
@ -46,8 +41,8 @@ namespace ICSharpCode.Core.Presentation @@ -46,8 +41,8 @@ namespace ICSharpCode.Core.Presentation
}
// Binding infos
private static Dictionary<string, CommandBindingInfo> commandBindings = new Dictionary<string, CommandBindingInfo>();
private static Dictionary<string, InputBindingInfo> inputBidnings = new Dictionary<string, InputBindingInfo>();
private static List<CommandBindingInfo> commandBindings = new List<CommandBindingInfo>();
private static List<InputBindingInfo> inputBidnings = new List<InputBindingInfo>();
// Commands
private static Dictionary<string, RoutedUICommand> routedCommands = new Dictionary<string, RoutedUICommand>();
@ -232,28 +227,43 @@ namespace ICSharpCode.Core.Presentation @@ -232,28 +227,43 @@ namespace ICSharpCode.Core.Presentation
/// <param name="inputBindingInfo">Input binding parameters</param>
public static void RegisterInputBinding(InputBindingInfo inputBindingInfo)
{
if(string.IsNullOrEmpty(inputBindingInfo.Name)) {
throw new ArgumentException("InputBindingInfo instance should have a name assigned");
}
if(inputBidnings.ContainsKey(inputBindingInfo.Name)) {
throw new ArgumentException("InputBindingInfo instance with provided name is already registered");
}
// Replace default gestures with user defined gestures
var userGestures = UserDefinedGesturesManager.GetInputBindingGesture(inputBindingInfo.Name);
var userGestures = UserDefinedGesturesManager.GetInputBindingGesture(inputBindingInfo);
if(userGestures != null) {
inputBindingInfo.Gestures = userGestures;
}
if(inputBindingInfo.OwnerTypeName != null || inputBindingInfo.OwnerType != null) {
RegisterClassDefaultInputBindingHandler(inputBindingInfo);
} else if (inputBindingInfo.OwnerInstanceName != null || inputBindingInfo.OwnerInstance != null) {
RegisterInstaceDefaultInputBindingHandler(inputBindingInfo);
var similarInputBinding = FindInputBindingInfos(
inputBindingInfo.OwnerTypeName,
inputBindingInfo.OwnerInstanceName,
inputBindingInfo.RoutedCommandName).FirstOrDefault();
if(similarInputBinding != null) {
foreach(InputGesture gesture in inputBindingInfo.Gestures) {
if(!similarInputBinding.Gestures.ContainsTemplateFor(gesture, GestureCompareMode.ExactlyMatches)) {
similarInputBinding.Gestures.Add(gesture);
}
}
foreach(var category in inputBindingInfo.Categories) {
if(!similarInputBinding.Categories.Contains(category)) {
similarInputBinding.Categories.Add(category);
}
}
similarInputBinding.IsModifyed = true;
similarInputBinding.DefaultInputBindingHandler.Invoke();
} else {
throw new ArgumentException("Binding owner must be specified");
if(inputBindingInfo.OwnerTypeName != null || inputBindingInfo.OwnerType != null) {
RegisterClassDefaultInputBindingHandler(inputBindingInfo);
} else if (inputBindingInfo.OwnerInstanceName != null || inputBindingInfo.OwnerInstance != null) {
RegisterInstaceDefaultInputBindingHandler(inputBindingInfo);
} else {
throw new ArgumentException("Binding owner must be specified");
}
inputBidnings.Add(inputBindingInfo);
}
inputBidnings.Add(inputBindingInfo.Name, inputBindingInfo);
}
/// <summary>
@ -262,22 +272,35 @@ namespace ICSharpCode.Core.Presentation @@ -262,22 +272,35 @@ namespace ICSharpCode.Core.Presentation
/// <param name="inputBindingInfo">Input binding parameters</param>
public static void UnregisterInputBinding(InputBindingInfo inputBindingInfo)
{
inputBidnings.Remove(inputBindingInfo.Name);
}
/// <summary>
/// Get instance of <see cref="InputBindingInfo" /> by name
/// </summary>
/// <param name="inputBindingName">Input binding info name</param>
/// <returns>Input binding info matching provided name</returns>
public static InputBindingInfo GetInputBindingInfo(string inputBindingName) {
InputBindingInfo bindingInfo;
inputBidnings.TryGetValue(inputBindingName, out bindingInfo);
var similarInputBindingInfos = FindInputBindingInfos(
inputBindingInfo.OwnerTypeName,
inputBindingInfo.OwnerInstanceName,
inputBindingInfo.RoutedCommandName);
return bindingInfo;
foreach(var similarInputBindingInfo in similarInputBindingInfos) {
inputBidnings.Remove(similarInputBindingInfo);
// Remove command bindings
if(similarInputBindingInfo.OwnerType != null) {
foreach(InputBinding binding in similarInputBindingInfo.OldInputBindings) {
RemoveClassInputBinding(similarInputBindingInfo.OwnerType, binding);
}
foreach(InputBinding binding in similarInputBindingInfo.NewInputBindings) {
RemoveClassInputBinding(similarInputBindingInfo.OwnerType, binding);
}
} else if (similarInputBindingInfo.OwnerInstance != null) {
foreach(InputBinding binding in similarInputBindingInfo.OldInputBindings) {
similarInputBindingInfo.OwnerInstance.InputBindings.Remove(binding);
}
foreach(InputBinding binding in similarInputBindingInfo.NewInputBindings) {
similarInputBindingInfo.OwnerInstance.InputBindings.Remove(binding);
}
}
}
}
/// <summary>
/// Find input input binding infos which satisfy provided arguments
///
@ -286,17 +309,15 @@ namespace ICSharpCode.Core.Presentation @@ -286,17 +309,15 @@ 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>
public static ICollection<InputBindingInfo> FindInputBindingInfos(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName) {
public static ICollection<InputBindingInfo> FindInputBindingInfos(string ownerTypeName, string ownerInstanceName, string routedCommandName) {
var foundBindings = new List<InputBindingInfo>();
foreach(var binding in inputBidnings) {
if( (ownerInstanceName == null || binding.Value.OwnerInstanceName == ownerInstanceName)
&& (ownerInstance == null || binding.Value.OwnerInstance == ownerInstance)
&& (ownerTypeName == null || binding.Value.OwnerTypeName == ownerTypeName)
&& (ownerType == null || binding.Value.OwnerType == ownerType)
&& (routedCommandName == null || binding.Value.RoutedCommandName == routedCommandName)) {
if( (ownerInstanceName == null || binding.OwnerInstanceName == ownerInstanceName)
&& (ownerTypeName == null || binding.OwnerTypeName == ownerTypeName)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName)) {
foundBindings.Add(binding.Value);
foundBindings.Add(binding);
}
}
@ -340,14 +361,6 @@ namespace ICSharpCode.Core.Presentation @@ -340,14 +361,6 @@ namespace ICSharpCode.Core.Presentation
/// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void RegisterCommandBinding(CommandBindingInfo commandBindingInfo) {
if(string.IsNullOrEmpty(commandBindingInfo.Name)) {
throw new ArgumentException("cCommandBindingInfo instance should have a name assigned");
}
if(commandBindings.ContainsKey(commandBindingInfo.Name)) {
throw new ArgumentException("CommandBindingInfo instance with provided name is already registered");
}
commandBindingInfo.GenerateCommandBindings();
if(commandBindingInfo.OwnerTypeName != null || commandBindingInfo.OwnerType != null) {
@ -358,7 +371,7 @@ namespace ICSharpCode.Core.Presentation @@ -358,7 +371,7 @@ namespace ICSharpCode.Core.Presentation
throw new ArgumentException("Binding owner must be specified");
}
commandBindings.Add(commandBindingInfo.Name, commandBindingInfo);
commandBindings.Add(commandBindingInfo);
}
/// <summary>
@ -366,24 +379,33 @@ namespace ICSharpCode.Core.Presentation @@ -366,24 +379,33 @@ namespace ICSharpCode.Core.Presentation
/// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void UnregisterCommandBinding(CommandBindingInfo commandBindingInfo) {
commandBindings.Remove(commandBindingInfo.Name);
// Remove command bindings
if(commandBindingInfo.OwnerType != null) {
foreach(CommandBinding binding in commandBindingInfo.OldCommandBindings) {
RemoveClassCommandBinding(commandBindingInfo.OwnerType, binding);
}
var similarCommandBindingInfos = FindCommandBindingInfos(
commandBindingInfo.OwnerTypeName,
commandBindingInfo.OwnerInstanceName,
commandBindingInfo.RoutedCommandName,
null
);
foreach(var similarCommandBindingInfo in similarCommandBindingInfos) {
commandBindings.Remove(similarCommandBindingInfo);
foreach(CommandBinding binding in commandBindingInfo.NewCommandBindings) {
RemoveClassCommandBinding(commandBindingInfo.OwnerType, binding);
}
} else if (commandBindingInfo.OwnerInstance != null) {
foreach(CommandBinding binding in commandBindingInfo.OldCommandBindings) {
commandBindingInfo.OwnerInstance.CommandBindings.Remove(binding);
}
foreach(CommandBinding binding in commandBindingInfo.NewCommandBindings) {
commandBindingInfo.OwnerInstance.CommandBindings.Remove(binding);
// Remove command bindings
if(similarCommandBindingInfo.OwnerType != null) {
foreach(CommandBinding binding in similarCommandBindingInfo.OldCommandBindings) {
RemoveClassCommandBinding(similarCommandBindingInfo.OwnerType, binding);
}
foreach(CommandBinding binding in similarCommandBindingInfo.NewCommandBindings) {
RemoveClassCommandBinding(similarCommandBindingInfo.OwnerType, binding);
}
} else if (similarCommandBindingInfo.OwnerInstance != null) {
foreach(CommandBinding binding in similarCommandBindingInfo.OldCommandBindings) {
similarCommandBindingInfo.OwnerInstance.CommandBindings.Remove(binding);
}
foreach(CommandBinding binding in similarCommandBindingInfo.NewCommandBindings) {
similarCommandBindingInfo.OwnerInstance.CommandBindings.Remove(binding);
}
}
}
}
@ -659,16 +681,16 @@ namespace ICSharpCode.Core.Presentation @@ -659,16 +681,16 @@ namespace ICSharpCode.Core.Presentation
/// <param name="addIn">Add-in</param>
public static void LoadAddinCommands(AddIn addIn) {
foreach(var binding in commandBindings) {
if(binding.Value.AddIn != addIn) continue;
if(binding.AddIn != addIn) continue;
if(binding.Value.CommandTypeName != null && !commands.ContainsKey(binding.Value.CommandTypeName)){
var command = addIn.CreateObject(binding.Value.CommandTypeName);
if(binding.CommandTypeName != null && !commands.ContainsKey(binding.CommandTypeName)){
var command = addIn.CreateObject(binding.CommandTypeName);
var wpfCommand = command as System.Windows.Input.ICommand;
if(wpfCommand == null) {
wpfCommand = new WpfCommandWrapper((ICSharpCode.Core.ICommand)command);
}
commands.Add(binding.Value.CommandTypeName, wpfCommand);
commands.Add(binding.CommandTypeName, wpfCommand);
}
}
}
@ -690,18 +712,6 @@ namespace ICSharpCode.Core.Presentation @@ -690,18 +712,6 @@ namespace ICSharpCode.Core.Presentation
}
}
/// <summary>
/// Get registered instance of <see cref="CommandBindingInfo" />
/// </summary>
/// <param name="commandBindingName">Command binding info name</param>
/// <returns>Command binding info matching provided name</returns>
public static CommandBindingInfo GetCommandBindingInfo(string commandBindingName) {
CommandBindingInfo bindingInfo;
commandBindings.TryGetValue(commandBindingName, out bindingInfo);
return bindingInfo;
}
/// <summary>
/// Get list of all command bindings which satisfy provided parameters
///
@ -712,18 +722,16 @@ namespace ICSharpCode.Core.Presentation @@ -712,18 +722,16 @@ namespace ICSharpCode.Core.Presentation
/// <param name="routedCommandName">Context class full name</param>
/// <param name="className">Context class full name</param>
/// <returns>Collection of managed command bindings</returns>
public static ICollection<CommandBindingInfo> FindCommandBindingInfos(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName, string className) {
public static ICollection<CommandBindingInfo> FindCommandBindingInfos(string ownerTypeName, string ownerInstanceName, string routedCommandName, string className) {
var foundBindings = new List<CommandBindingInfo>();
foreach(var binding in commandBindings) {
if( (ownerInstanceName == null || binding.Value.OwnerInstanceName == ownerInstanceName)
&& (ownerInstance == null || binding.Value.OwnerInstance == ownerInstance)
&& (ownerTypeName == null || binding.Value.OwnerTypeName == ownerTypeName)
&& (ownerType == null || binding.Value.OwnerType == ownerType)
&& (routedCommandName == null || binding.Value.RoutedCommandName == routedCommandName)
&& (className == null || binding.Value.CommandTypeName == className)) {
if( (ownerInstanceName == null || binding.OwnerInstanceName == ownerInstanceName)
&& (ownerTypeName == null || binding.OwnerTypeName == ownerTypeName)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName)
&& (className == null || binding.CommandTypeName == className)) {
foundBindings.Add(binding.Value);
foundBindings.Add(binding);
}
}
@ -741,12 +749,14 @@ namespace ICSharpCode.Core.Presentation @@ -741,12 +749,14 @@ namespace ICSharpCode.Core.Presentation
/// <param name="contextInstance">Get gestures assigned only to specific context</param>
/// <param name="routedCommandName">Routed UI command name</param>
/// <param name="gesture">Gesture</param>
public static InputGestureCollection FindInputGestures(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName) {
var bindings = FindInputBindingInfos(ownerTypeName, ownerType, ownerInstanceName, ownerInstance, routedCommandName);
public static InputGestureCollection FindInputGestures(string ownerTypeName, string ownerInstanceName, string routedCommandName) {
var bindings = FindInputBindingInfos(ownerTypeName, ownerInstanceName, routedCommandName);
var gestures = new InputGestureCollection();
foreach(InputBindingInfo bindingInfo in bindings) {
gestures.AddRange(bindingInfo.Gestures);
if(bindingInfo.Gestures != null) {
gestures.AddRange(bindingInfo.Gestures);
}
}
return gestures;
@ -766,6 +776,10 @@ namespace ICSharpCode.Core.Presentation @@ -766,6 +776,10 @@ namespace ICSharpCode.Core.Presentation
public static List<InputBindingCategory> RegisterInputBindingCategories(string categoriesString) {
var registeredCategories = new List<InputBindingCategory>();
if(string.IsNullOrEmpty(categoriesString)) {
return registeredCategories;
}
// Split categories
var categoryPaths = Regex.Split(categoriesString, @"\s*\,\s*");
foreach(var categoryPath in categoryPaths) {
@ -799,10 +813,8 @@ namespace ICSharpCode.Core.Presentation @@ -799,10 +813,8 @@ namespace ICSharpCode.Core.Presentation
/// <param name="destinationPath">Destination file path</param>
public static void SaveGestures(string destinationPath)
{
foreach(var inputBindingInfo in inputBidnings) {
UserDefinedGesturesManager.SetInputBindingGesture(
inputBindingInfo.Key,
inputBindingInfo.Value.Gestures);
foreach(var binding in inputBidnings) {
UserDefinedGesturesManager.SetInputBindingGestures(binding, binding.Gestures);
}
UserDefinedGesturesManager.Save(destinationPath);
@ -817,11 +829,11 @@ namespace ICSharpCode.Core.Presentation @@ -817,11 +829,11 @@ namespace ICSharpCode.Core.Presentation
UserDefinedGesturesManager.Load(sourcePath);
foreach(var inputBindingInfo in inputBidnings) {
var userGestures = UserDefinedGesturesManager.GetInputBindingGesture(inputBindingInfo.Key);
var userGestures = UserDefinedGesturesManager.GetInputBindingGesture(inputBindingInfo);
if(userGestures != null) {
inputBindingInfo.Value.Gestures = userGestures;
inputBindingInfo.Value.IsModifyed = true;
inputBindingInfo.Gestures = userGestures;
inputBindingInfo.IsModifyed = true;
}
}
}

86
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;
using ICSharpCode.Core;
namespace ICSharpCode.Core.Presentation
@ -12,6 +13,69 @@ namespace ICSharpCode.Core.Presentation @@ -12,6 +13,69 @@ namespace ICSharpCode.Core.Presentation
/// </summary>
public static class CommandsService
{
public static void RegisterMenuBindings(string menuRootsLocationPath, object caller)
{
var menuRoots = AddInTree.BuildItems<MenuRootDescriptor>(menuRootsLocationPath, caller);
foreach(var menuRoot in menuRoots) {
CommandsService.RegisterSingleMenuBindings(menuRoot.Path, caller, menuRoot.Name);
}
}
public static void RegisterSingleMenuBindings(string menuPath, object caller, string categoryPath)
{
var menuItemNode = AddInTree.GetTreeNode(menuPath);
var menuItems = menuItemNode.BuildChildItems<MenuItemDescriptor>(caller);
RegisterSingleMenuBindings(menuItems, caller, categoryPath);
}
private static void RegisterSingleMenuBindings(IList menuItems, object caller, string categoryPath) {
foreach(MenuItemDescriptor item in menuItems) {
var codon = item.Codon;
if(codon.Properties["type"] == "" || codon.Properties["type"] == "command") {
string routedCommandName = null;
string routedCommandText = null;
if(codon.Properties.Contains("command")) {
routedCommandName = codon.Properties["command"];
routedCommandText = codon.Properties["command"];
} else if(codon.Properties.Contains("link") || codon.Properties.Contains("class")) {
routedCommandName = string.IsNullOrEmpty(codon.Properties["link"]) ? codon.Properties["class"] : codon.Properties["link"];
routedCommandText = codon.Properties["label"];
}
var routedCommand = CommandManager.GetRoutedUICommand(routedCommandName);
if(routedCommand == null) {
routedCommand = CommandManager.RegisterRoutedUICommand(routedCommandName, routedCommandText);
}
if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) {
var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.AddIn = codon.AddIn;
commandBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
commandBindingInfo.CommandInstance = CommandWrapper.GetCommand(codon, null, codon.Properties["loadclasslazy"] == "true");
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.IsLazy = true;
CommandManager.RegisterCommandBinding(commandBindingInfo);
}
// Register input bindings
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.AddIn = codon.AddIn;
inputBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromInvariantString(codon.Properties["shortcut"]);
inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories(categoryPath));
CommandManager.RegisterInputBinding(inputBindingInfo);
}
if(item.SubItems != null) {
RegisterSingleMenuBindings(item.SubItems, caller, categoryPath + "/" + item.Codon.Properties["label"]);
}
}
}
public static void RegisterRoutedCommands(Type type) {
var typeProperties = type.GetProperties(BindingFlags.Static | BindingFlags.Public);
foreach(var property in typeProperties) {
@ -52,27 +116,16 @@ namespace ICSharpCode.Core.Presentation @@ -52,27 +116,16 @@ namespace ICSharpCode.Core.Presentation
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
commandBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
commandBindingInfoName.AppendFormat("{0}_", desc.OwnerInstanceName);
} else if(!string.IsNullOrEmpty(desc.OwnerTypeName)) {
commandBindingInfo.OwnerTypeName = desc.OwnerTypeName;
commandBindingInfoName.AppendFormat("{0}_", desc.OwnerTypeName);
} else {
commandBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
commandBindingInfoName.AppendFormat("{0}_", CommandManager.DefaultContextName);
}
commandBindingInfo.RoutedCommandName = desc.Command;
commandBindingInfoName.AppendFormat("{0}_", desc.Command);
commandBindingInfo.CommandTypeName = desc.Class;
commandBindingInfoName.AppendFormat("{0}_", desc.Class);
commandBindingInfo.AddIn = desc.Codon.AddIn;
commandBindingInfoName.Append(desc.Codon.AddIn.Name);
commandBindingInfo.IsLazy = desc.Lazy;
commandBindingInfo.Name = "CommandBinding_" + commandBindingInfoName.ToString();
CommandManager.RegisterCommandBinding(commandBindingInfo);
// If gestures are provided register input binding in the same context
@ -80,7 +133,6 @@ namespace ICSharpCode.Core.Presentation @@ -80,7 +133,6 @@ namespace ICSharpCode.Core.Presentation
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures);
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.Name = "InputBinding_" + commandBindingInfoName.ToString();
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
inputBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
@ -114,26 +166,17 @@ namespace ICSharpCode.Core.Presentation @@ -114,26 +166,17 @@ namespace ICSharpCode.Core.Presentation
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures);
var inputBindingInfo = new InputBindingInfo();
StringBuilder inputBindingInfoName = new StringBuilder();
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
inputBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
inputBindingInfoName.AppendFormat("{0}_", desc.OwnerInstanceName);
} else if(!string.IsNullOrEmpty(desc.OwnerTypeName)) {
inputBindingInfo.OwnerTypeName = desc.OwnerTypeName;
inputBindingInfoName.AppendFormat("{0}_", desc.OwnerTypeName);
} else {
inputBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
inputBindingInfoName.AppendFormat("{0}_", CommandManager.DefaultContextName);
}
inputBindingInfo.AddIn = desc.Codon.AddIn;
inputBindingInfoName.AppendFormat("{0}_", desc.Codon.AddIn.Name);
inputBindingInfo.RoutedCommandName = desc.Command;
inputBindingInfoName.AppendFormat("{0}_", desc.Command);
inputBindingInfo.Gestures = gestures;
if(!string.IsNullOrEmpty(desc.CommandText)) {
@ -144,7 +187,6 @@ namespace ICSharpCode.Core.Presentation @@ -144,7 +187,6 @@ namespace ICSharpCode.Core.Presentation
inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories(desc.Category));
}
inputBindingInfo.Name = inputBindingInfoName.ToString();
CommandManager.RegisterInputBinding(inputBindingInfo);
}
}

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

@ -22,15 +22,6 @@ namespace ICSharpCode.Core.Presentation @@ -22,15 +22,6 @@ namespace ICSharpCode.Core.Presentation
Categories = new List<InputBindingCategory>();
}
/// <summary>
/// Command binding info name
///
/// The name should be unique to register command binding
/// </summary>
public string Name {
get; set;
}
public string ownerInstanceName;
/// <summary>
@ -70,13 +61,6 @@ namespace ICSharpCode.Core.Presentation @@ -70,13 +61,6 @@ namespace ICSharpCode.Core.Presentation
return ownerInstance;
}
set {
if(ownerInstanceName != null || ownerInstance != null || ownerType != null || ownerTypeName != null) {
throw new ArgumentException("This binding already has an owner");
}
ownerInstance = value;
}
}
private string ownerTypeName;
@ -146,11 +130,22 @@ namespace ICSharpCode.Core.Presentation @@ -146,11 +130,22 @@ namespace ICSharpCode.Core.Presentation
get; set;
}
private InputGestureCollection _gestures;
/// <summary>
/// Gestures which triggers this binding
/// </summary>
public InputGestureCollection Gestures {
get; set;
get {
if(_gestures == null) {
return new InputGestureCollection();
}
return _gestures;
}
set {
_gestures = value;
}
}
/// <summary>
@ -192,9 +187,11 @@ namespace ICSharpCode.Core.Presentation @@ -192,9 +187,11 @@ namespace ICSharpCode.Core.Presentation
OldInputBindings = NewInputBindings;
NewInputBindings = new InputBindingCollection();
foreach(InputGesture gesture in Gestures) {
var inputBinding = new InputBinding(RoutedCommand, gesture);
NewInputBindings.Add(inputBinding);
if(Gestures != null) {
foreach(InputGesture gesture in Gestures) {
var inputBinding = new InputBinding(RoutedCommand, gesture);
NewInputBindings.Add(inputBinding);
}
}
}

42
src/Main/ICSharpCode.Core.Presentation/CommandsService/UserDefinedGesturesManager.cs

@ -25,9 +25,9 @@ namespace ICSharpCode.Core.Presentation @@ -25,9 +25,9 @@ namespace ICSharpCode.Core.Presentation
foreach(var definedGestures in userDefinedGestures) {
var bindingInfoNode = xmlDocument.CreateElement("InputBindingInfo");
var nameAttribute = xmlDocument.CreateAttribute("name");
nameAttribute.Value = definedGestures.Key;
bindingInfoNode.Attributes.Append(nameAttribute);
var idAttribute = xmlDocument.CreateAttribute("id");
idAttribute.Value = definedGestures.Key;
bindingInfoNode.Attributes.Append(idAttribute);
var gesturesAttribute = xmlDocument.CreateAttribute("gestures");
gesturesAttribute.Value = new InputGestureCollectionConverter().ConvertToInvariantString(definedGestures.Value);
@ -53,10 +53,10 @@ namespace ICSharpCode.Core.Presentation @@ -53,10 +53,10 @@ namespace ICSharpCode.Core.Presentation
xmlDocument.Load(sourcePath);
foreach(XmlElement bindingInfoNode in xmlDocument.SelectNodes("//InputBindingInfo")) {
var name = bindingInfoNode.Attributes["name"].Value;
var identifier = bindingInfoNode.Attributes["id"].Value;
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromInvariantString(bindingInfoNode.Attributes["gestures"].Value);
userDefinedGestures[name] = gestures;
userDefinedGestures[identifier] = gestures;
}
}
}
@ -64,14 +64,19 @@ namespace ICSharpCode.Core.Presentation @@ -64,14 +64,19 @@ namespace ICSharpCode.Core.Presentation
/// <summary>
/// Get user defined input binding gestures
/// </summary>
/// <param name="inputBindingInfoName">Input binding name</param>
/// <param name="inputBindingInfoName">Input binding</param>
/// <returns>Gestures assigned to this input binding</returns>
public static InputGestureCollection GetInputBindingGesture(string inputBindingInfoName)
public static InputGestureCollection GetInputBindingGesture(InputBindingInfo inputBindingInfo)
{
InputGestureCollection gestures;
userDefinedGestures.TryGetValue(inputBindingInfoName, out gestures);
var identifier = GetInputBindingInfoIdentifier(inputBindingInfo);
if(identifier != null) {
InputGestureCollection gestures;
userDefinedGestures.TryGetValue(identifier, out gestures);
return gestures;
}
return gestures;
return null;
}
/// <summary>
@ -79,9 +84,22 @@ namespace ICSharpCode.Core.Presentation @@ -79,9 +84,22 @@ namespace ICSharpCode.Core.Presentation
/// </summary>
/// <param name="inputBindingInfoName">Input binding name</param>
/// <param name="inputGestureCollection">Gesture assigned to this input binding</param>
public static void SetInputBindingGesture(string inputBindingInfoName, InputGestureCollection inputGestureCollection)
public static void SetInputBindingGestures(InputBindingInfo inputBindingInfo, InputGestureCollection inputGestureCollection)
{
userDefinedGestures[inputBindingInfoName] = inputGestureCollection;
var identifier = GetInputBindingInfoIdentifier(inputBindingInfo);
userDefinedGestures[identifier] = inputGestureCollection;
}
private static string GetInputBindingInfoIdentifier(InputBindingInfo inputBindingInfo) {
if(inputBindingInfo.OwnerTypeName != null) {
return string.Format("OwnerType={0};RoutedCommandName={1}", inputBindingInfo.OwnerTypeName, inputBindingInfo.RoutedCommandName);
} else if(inputBindingInfo.OwnerInstanceName != null) {
return string.Format("OwnerInstance={0};RoutedCommandName={1}", inputBindingInfo.OwnerInstanceName, inputBindingInfo.RoutedCommandName);
} else {
return null;
}
}
}
}

41
src/Main/ICSharpCode.Core.Presentation/Input/InputGestureCollectionExtensions.cs

@ -19,41 +19,12 @@ namespace ICSharpCode.Core.Presentation @@ -19,41 +19,12 @@ namespace ICSharpCode.Core.Presentation
}
public static bool ContainsCopy(this InputGestureCollection gestures, InputGesture searchedGesture) {
var searchedMultiKeyGesture = searchedGesture as MultiKeyGesture;
var searchedKeyGesture = searchedGesture as KeyGesture;
var searchedMouseGesture = searchedGesture as MouseGesture;
foreach(var gesture in gestures) {
if(searchedMultiKeyGesture != null) {
var multiKeyGesture = gesture as MultiKeyGesture;
if(multiKeyGesture != null && multiKeyGesture.Chords != null && searchedMultiKeyGesture.Chords != null && multiKeyGesture.Chords.Count == searchedMultiKeyGesture.Chords.Count) {
var foundMatch = true;
foreach(var partialGesture in multiKeyGesture.Chords) {
foreach(var searchedPartialGesture in searchedMultiKeyGesture.Chords) {
if(partialGesture.Key != searchedPartialGesture.Key || partialGesture.Modifiers != searchedPartialGesture.Modifiers) {
foundMatch = false;
break;
}
}
}
if(foundMatch) {
return true;
}
}
} else if(searchedKeyGesture != null) {
var keyGesture = gesture as KeyGesture;
if(keyGesture != null && keyGesture.Key == searchedKeyGesture.Key && keyGesture.Modifiers == searchedKeyGesture.Modifiers) {
return true;
}
} else if(searchedMouseGesture != null) {
var mouseGesture = gesture as MouseGesture;
if(mouseGesture != null && mouseGesture.MouseAction == searchedMouseGesture.MouseAction && mouseGesture.Modifiers == searchedMouseGesture.Modifiers) {
return true;
}
}
}
public static bool ContainsTemplateFor(this InputGestureCollection inputGestureTemplateCollection, InputGesture testedGesture, GestureCompareMode mode) {
foreach (InputGesture template in inputGestureTemplateCollection) {
if (template.IsTemplateFor(testedGesture, mode)) {
return true;
}
}
return false;
}

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

@ -14,6 +14,7 @@ using System.Windows; @@ -14,6 +14,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Text;
using CommandManager=ICSharpCode.Core.Presentation.CommandManager;
namespace ICSharpCode.Core.Presentation
{
@ -120,65 +121,29 @@ namespace ICSharpCode.Core.Presentation @@ -120,65 +121,29 @@ namespace ICSharpCode.Core.Presentation
public MenuCommand(UIElement inputBindingOwner, Codon codon, object caller, bool createCommand) : base(codon, caller)
{
string routedCommandName = null;
string routedCommandText = null;
if(codon.Properties.Contains("command")) {
routedCommandName = codon.Properties["command"];
routedCommandText = codon.Properties["command"];
} else if(codon.Properties.Contains("link") || codon.Properties.Contains("class")) {
routedCommandName = string.IsNullOrEmpty(codon.Properties["link"]) ? codon.Properties["class"] : codon.Properties["link"];
routedCommandText = "Menu item \"" + codon.Properties["label"] + "\"";
}
var routedCommand = CommandManager.GetRoutedUICommand(routedCommandName);
if(routedCommand == null) {
routedCommand = CommandManager.RegisterRoutedUICommand(routedCommandName, routedCommandText);
if(routedCommand != null) {
this.Command = routedCommand;
} else
{
Console.WriteLine(routedCommandName);
}
this.Command = routedCommand;
if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) {
var commandBindingInfoName = "MenuCommandBinding_" + routedCommandName + "_" + codon.AddIn.Name + "_" + CommandManager.DefaultContextName;
var commandBindingInfo = CommandManager.GetCommandBindingInfo(commandBindingInfoName);
// Register input bindings update handler
BindingsUpdatedHandler gesturesUpdateHandler = delegate {
var updatedGestures = CommandManager.FindInputGestures(null, null, routedCommandName);
if(commandBindingInfo == null) {
commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.AddIn = codon.AddIn;
commandBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
commandBindingInfo.CommandInstance = CommandWrapper.GetCommand(codon, caller, createCommand);
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.IsLazy = true;
commandBindingInfo.Name = commandBindingInfoName;
CommandManager.RegisterCommandBinding(commandBindingInfo);
}
}
this.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
};
if(codon.Properties.Contains("shortcut")) {
var inputBindingInfoName = "MenuInputBinding_" + routedCommandName + "_" + codon.AddIn.Name + "_" + CommandManager.DefaultContextName;
var inputBindingInfo = CommandManager.GetInputBindingInfo(inputBindingInfoName);
if(inputBindingInfo == null) {
var shortcut = codon.Properties["shortcut"];
inputBindingInfo = new InputBindingInfo();
inputBindingInfo.AddIn = codon.AddIn;
inputBindingInfo.Categories.AddRange(CommandManager.RegisterInputBindingCategories("Menu Items"));
inputBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromInvariantString(codon.Properties["gestures"]);
inputBindingInfo.Name = inputBindingInfoName;
CommandManager.RegisterInputBinding(inputBindingInfo);
}
BindingsUpdatedHandler gesturesUpdateHandler = delegate {
var updatedGestures = CommandManager.FindInputGestures(null, null, null, null, routedCommandName);
this.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
};
gesturesUpdateHandler.Invoke();
CommandManager.RegisterClassInputBindingsUpdateHandler(CommandManager.DefaultContextName, gesturesUpdateHandler);
}
gesturesUpdateHandler.Invoke();
CommandManager.RegisterClassInputBindingsUpdateHandler(CommandManager.DefaultContextName, gesturesUpdateHandler);
}
}
}

13
src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs

@ -94,7 +94,10 @@ namespace ICSharpCode.Core.Presentation @@ -94,7 +94,10 @@ namespace ICSharpCode.Core.Presentation
public static IList CreateMenuItems(UIElement inputBindingOwner, object owner, string addInTreePath)
{
return ExpandMenuBuilders(CreateUnexpandedMenuItems(inputBindingOwner, AddInTree.BuildItems<MenuItemDescriptor>(addInTreePath, owner, false)));
var menuItemDescriptors = AddInTree.BuildItems<MenuItemDescriptor>(addInTreePath, owner, false);
var menuItems = CreateUnexpandedMenuItems(inputBindingOwner, menuItemDescriptors);
return ExpandMenuBuilders(menuItems);
}
sealed class MenuItemBuilderPlaceholder
@ -198,13 +201,5 @@ namespace ICSharpCode.Core.Presentation @@ -198,13 +201,5 @@ namespace ICSharpCode.Core.Presentation
// HACK: find a better way to allow the host app to process link commands
public static Converter<string, ICommand> LinkCommandCreator { get; set; }
/// <summary>
/// Creates an KeyGesture for a shortcut.
/// </summary>
public static KeyGesture ParseShortcut(string text)
{
return (KeyGesture)new KeyGestureConverter().ConvertFromInvariantString(text.Replace(',', '+').Replace('|', '+'));
}
}
}

21
src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs

@ -48,20 +48,13 @@ namespace ICSharpCode.Core.Presentation @@ -48,20 +48,13 @@ namespace ICSharpCode.Core.Presentation
this.Command = routedCommand;
if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) {
var commandBindingInfoName = "MenuCommandBinding_" + routedCommandName + "_" + codon.AddIn.Name + "_" + CommandManager.DefaultContextName;
var commandBindingInfo = CommandManager.GetCommandBindingInfo(commandBindingInfoName);
if(commandBindingInfo == null) {
commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.AddIn = codon.AddIn;
commandBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
commandBindingInfo.CommandInstance = CommandWrapper.GetCommand(codon, caller, createCommand);
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.IsLazy = true;
commandBindingInfo.Name = commandBindingInfoName;
CommandManager.RegisterCommandBinding(commandBindingInfo);
}
var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.AddIn = codon.AddIn;
commandBindingInfo.OwnerTypeName = CommandManager.DefaultContextName;
commandBindingInfo.CommandInstance = CommandWrapper.GetCommand(codon, caller, createCommand);
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.IsLazy = true;
CommandManager.RegisterCommandBinding(commandBindingInfo);
}
if (codon.Properties.Contains("icon")) {

16
src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs

@ -76,15 +76,15 @@ namespace ICSharpCode.Core.WinForms @@ -76,15 +76,15 @@ namespace ICSharpCode.Core.WinForms
UpdateText();
GesturePlaceHolderRegistry.RegisterPlaceHolder(codon.Properties["class"], StringParser.Parse(codon.Properties["label"]));
GesturePlaceHolderRegistry.RegisterUpdateHandler(codon.Properties["class"], delegate {
ShortcutKeys = GesturePlaceHolderRegistry.GetGestures(codon.Properties["class"])[0];
});
GesturePlaceHolderRegistry.InvokeUpdateHandlers(codon.Properties["class"]);
// GesturePlaceHolderRegistry.RegisterPlaceHolder(codon.Properties["class"], StringParser.Parse(codon.Properties["label"]));
// GesturePlaceHolderRegistry.RegisterUpdateHandler(codon.Properties["class"], delegate {
// ShortcutKeys = GesturePlaceHolderRegistry.GetGestures(codon.Properties["class"])[0];
// });
// GesturePlaceHolderRegistry.InvokeUpdateHandlers(codon.Properties["class"]);
if (codon.Properties.Contains("shortcut")) {
GesturePlaceHolderRegistry.InvokeUpdateHandlers(codon.Properties["class"]);
}
// if (codon.Properties.Contains("shortcut")) {
// GesturePlaceHolderRegistry.InvokeUpdateHandlers(codon.Properties["class"]);
// }
}
public MenuCommand(string label, EventHandler handler) : this(label)

Loading…
Cancel
Save