From 87dee204446fdb9753410bda928cc7e819e41442 Mon Sep 17 00:00:00 2001 From: Sergej Andrejev Date: Wed, 3 Jun 2009 14:16:32 +0000 Subject: [PATCH 01/51] Add ShortcutsManagement options panel git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4214 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- AddIns/ICSharpCode.SharpDevelop.addin | 319 +++++++--- data/schemas/AddIn.xsd | 516 +++++++++------- doc/technotes/ConditionList.html | 33 +- doc/technotes/DoozerList.html | 264 ++++++-- .../Boo/BooBinding/Project/BooBinding.addin | 2 +- .../FSharpBinding/Project/FSharpBinding.addin | 2 +- .../AvalonEdit.AddIn/Src/CodeEditor.cs | 12 +- .../HexEditor/Project/HexEditor.addin | 2 +- .../XmlEditor/Project/XmlEditor.addin | 24 +- .../CodeCoverage/Project/CodeCoverage.addin | 2 +- .../Project/Debugger.AddIn.addin | 14 +- .../Misc/HtmlHelp2/Project/HtmlHelp2.addin | 10 +- .../Project/Gui/SearchAndReplaceDialog.cs | 18 +- .../Project/SearchAndReplace.addin | 40 +- .../ShortcutsManagement.sln | 23 + .../ShortcutsManagement.suo | Bin 0 -> 51712 bytes .../ShortcutsManagement/App.xaml | 8 + .../ShortcutsManagement/App.xaml.cs | 11 + .../Properties/AssemblyInfo.cs | 55 ++ .../Properties/Resources.Designer.cs | 63 ++ .../Properties/Resources.resx | 117 ++++ .../Properties/Settings.Designer.cs | 26 + .../Properties/Settings.settings | 7 + .../ShortcutsManagement/Resources/Thumbs.db | Bin 0 -> 4608 bytes .../Resources/key_enter.png | Bin 0 -> 1056 bytes .../Resources/key_enter_pressed.png | Bin 0 -> 1296 bytes .../ShortcutsManagement.addin | 19 + .../ShortcutsManagement.csproj | 156 +++++ .../ShortcutsManagement.csproj.user | 6 + .../Src/Converters/GesturesListConverter.cs | 27 + .../Src/Converters/ShortcutsTreeConverter.cs | 25 + .../Src/Converters/TypeNameConverter.cs | 19 + .../ShortcutsManagement/Src/Data/AddIn.cs | 84 +++ .../ShortcutsManagement/Src/Data/Shortcut.cs | 90 +++ .../Src/Data/ShortcutCategory.cs | 101 ++++ .../Src/Data/ShortcutsProvider.cs | 116 ++++ .../ShortcutsManagementOptionsPanel.xaml | 171 ++++++ .../ShortcutsManagementOptionsPanel.xaml.cs | 84 +++ .../Src/Extensions/TextBlockBehavior.cs | 83 +++ .../Src/Extensions/TreeViewExtensions.cs | 80 +++ .../ShortcutsManagement/Themes/Generic.xaml | 5 + .../ShortcutsManagement/Thumbs.db | Bin 0 -> 3584 bytes .../ShortcutsManagement/Window1.xaml | 10 + .../ShortcutsManagement/Window1.xaml.cs | 15 + src/AddIns/Misc/UnitTesting/UnitTesting.addin | 2 +- .../Project/Src/Commands/AutostartCommands.cs | 15 +- .../Project/Src/Commands/MenuItemBuilders.cs | 45 +- .../Project/Src/Commands/ToolsCommands.cs | 23 + .../Gui/Workbench/Layouts/AvalonPadContent.cs | 10 + .../Layouts/AvalonWorkbenchWindow.cs | 12 + .../Project/Src/Gui/Workbench/WpfWorkbench.cs | 17 + .../Project/Src/Internal/Doozers/PadDoozer.cs | 2 +- src/Main/Core/Project/ICSharpCode.Core.csproj | 11 + .../Core/Project/Src/AddInTree/AddIn/AddIn.cs | 8 + .../Command/CommandBindingDescriptor.cs | 75 +++ .../Command/CommandBindingDoozer.cs | 52 ++ .../Command/GesturesPlaceHolderDescriptor.cs | 26 + .../Command/GesturesPlaceHolderDoozer.cs | 43 ++ .../Command/InputBindingDescriptor.cs | 44 ++ .../Command/InputBindingDoozer.cs | 35 ++ .../Command/RoutedUICommandDescriptor.cs | 39 ++ .../Command/RoutedUICommandDoozer.cs | 35 ++ .../DefaultDoozers/MenuItem/MenuItemDoozer.cs | 2 +- .../Core/Project/Src/AddInTree/AddInTree.cs | 4 + .../BaseGesturesPlaceHolderRegistry.cs | 174 ++++++ .../CommandsService/CommandBindingInfo.cs | 185 ++++++ .../CommandsService/CommandsRegistry.cs | 568 ++++++++++++++++++ .../CommandsService/CommandsService.cs | 72 +++ .../GesturePlaceHolderRegistry.cs | 82 +++ .../CommandsService/InputBindingInfo.cs | 90 +++ .../InputGestureCollectionConverter.cs | 103 ++++ .../CommandsService/ManagedCommandBinding.cs | 35 ++ .../CommandsService/ManagedInputBinding.cs | 24 + .../CommandsService/WpfCommandWrapper.cs | 44 ++ .../ICSharpCode.Core.Presentation.csproj | 10 + .../Menu/MenuCommand.cs | 28 +- .../ToolBar/ToolBarButton.cs | 7 +- .../GesturePlaceHolderRegistry.cs | 82 +++ .../KeysCollectionConverter.cs | 114 ++++ .../ICSharpCode.Core.WinForms.csproj | 3 + .../Menu/MenuCommand.cs | 26 +- src/SharpDevelop.sln | 280 ++++----- 82 files changed, 4510 insertions(+), 576 deletions(-) create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.sln create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/App.xaml create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/App.xaml.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/AssemblyInfo.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Resources.Designer.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Resources.resx create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Settings.Designer.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Settings.settings create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/key_enter.png create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/key_enter_pressed.png create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.addin create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj.user create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/ShortcutsTreeConverter.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/TypeNameConverter.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Themes/Generic.xaml create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Thumbs.db create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDescriptor.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDoozer.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/GesturesPlaceHolderDescriptor.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/GesturesPlaceHolderDoozer.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDescriptor.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDoozer.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/RoutedUICommandDescriptor.cs create mode 100644 src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/RoutedUICommandDoozer.cs create mode 100644 src/Main/Core/Project/Src/Services/CommandsService/BaseGesturesPlaceHolderRegistry.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/GesturePlaceHolderRegistry.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/InputGestureCollectionConverter.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/ManagedCommandBinding.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/ManagedInputBinding.cs create mode 100644 src/Main/ICSharpCode.Core.Presentation/CommandsService/WpfCommandWrapper.cs create mode 100644 src/Main/ICSharpCode.Core.WinForms/CommandsService/GesturePlaceHolderRegistry.cs create mode 100644 src/Main/ICSharpCode.Core.WinForms/CommandsService/KeysCollectionConverter.cs diff --git a/AddIns/ICSharpCode.SharpDevelop.addin b/AddIns/ICSharpCode.SharpDevelop.addin index ef128c60cf..33bdb4f80a 100644 --- a/AddIns/ICSharpCode.SharpDevelop.addin +++ b/AddIns/ICSharpCode.SharpDevelop.addin @@ -51,6 +51,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -73,7 +162,7 @@ category = "Main" title = "${res:MainWindow.Windows.ProjectScoutLabel}" icon = "PadIcons.ProjectBrowser" - shortcut = "Control|Alt|L" + shortcut = "Ctrl+Alt+L" class = "ICSharpCode.SharpDevelop.Project.ProjectBrowserPad" defaultPosition = "Left" /> @@ -81,7 +170,7 @@ category = "Main" title = "${res:MainWindow.Windows.ClassScoutLabel}" icon = "PadIcons.ClassBrowser" - shortcut = "Control|Shift|C" + shortcut = "Ctrl+Shift+C" class = "ICSharpCode.SharpDevelop.Gui.ClassBrowser.ClassBrowserPad" defaultPosition = "Right" /> @@ -89,14 +178,14 @@ category = "Main" title = "${res:MainWindow.Windows.ToolbarLabel}" icon = "PadIcons.Toolbar" - shortcut = "Control|Alt|X" + shortcut = "Ctrl+Alt+X" class = "ICSharpCode.SharpDevelop.Gui.ToolsPad" defaultPosition = "Left" /> @@ -112,7 +201,7 @@ category = "Main" title = "${res:MainWindow.Windows.OutputWindow}" icon = "PadIcons.Output" - shortcut = "Control|Alt|O" + shortcut = "Ctrl+Alt+O" class = "ICSharpCode.SharpDevelop.Gui.CompilerMessageView" defaultPosition = "Bottom" /> @@ -128,7 +217,7 @@ category = "Tools" title = "${res:MainWindow.Windows.FileScoutLabel}" icon = "PadIcons.FileBrowser" - shortcut = "Control|Alt|F" + shortcut = "Ctrl+Alt+F" class = "ICSharpCode.SharpDevelop.Gui.FileScout" defaultPosition = "Left, Hidden" /> @@ -181,17 +270,20 @@ + class = "ICSharpCode.SharpDevelop.Project.Commands.ShowPropertiesForNode" + command = "SDProjectCommands.ShowSelectedProjectBrowserNodeProperties" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.ToggleShowAll" + command = "SDProjectCommands.ShowHiddenFilesInProjectBrowser" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.RefreshProjectBrowser" + command = "SDProjectCommands.RefreshProjectBrowser" /> @@ -207,33 +299,41 @@ label = "${res:XML.MainMenu.BuildMenu.BuildSolution}" shortcut = "F8" icon = "Icons.16x16.BuildCombine" - class = "ICSharpCode.SharpDevelop.Project.Commands.Build"/> + class = "ICSharpCode.SharpDevelop.Project.Commands.Build" + command = "SDBuildCommands.Build" /> + shortcut = "Alt+F8" + class = "ICSharpCode.SharpDevelop.Project.Commands.Rebuild" + command = "SDBuildCommands.Rebuild" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.Clean" + command = "SDBuildCommands.Clean" /> + + class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewProjectToSolution" + command = "SDProjectCommands.AddNewProjectToSolution" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.AddExitingProjectToSolution" + command = "SDProjectCommands.AddExitingProjectToSolution" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.AddExistingItemToSolution" + command = "SDProjectCommands.AddExistingItemToSolution" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewSolutionFolderToSolution" + command = "SDProjectCommands.AddNewSolutionFolderToSolution" /> @@ -242,7 +342,8 @@ label = "${res:XML.MainMenu.EditMenu.Paste}" icon = "Icons.16x16.PasteIcon" loadclasslazy = "false" - class = "ICSharpCode.SharpDevelop.Project.Commands.PasteProjectBrowserNode"/> + class = "ICSharpCode.SharpDevelop.Project.Commands.PasteProjectBrowserNode" + command = "" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.ShowPropertiesForNode" + command = "SDProjectCommands.ShowSelectedProjectBrowserNodeProperties" /> @@ -278,13 +380,16 @@ + class = "ICSharpCode.SharpDevelop.Project.Commands.BuildProject" + command = "SDBuildCommands.BuildProject" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.RebuildProject" + command = "SDBuildCommands.RebuildProject" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.CleanProject" + command = "SDBuildCommands.CleanProject" /> @@ -315,7 +420,8 @@ + class = "ICSharpCode.SharpDevelop.Project.Commands.ShowPropertiesForNode" + command = "SDProjectCommands.ShowSelectedProjectBrowserNodeProperties" /> @@ -436,7 +542,8 @@ + class = "ICSharpCode.SharpDevelop.Project.Commands.ShowPropertiesForNode" + command = "SDProjectCommands.ShowSelectedProjectBrowserNodeProperties" /> @@ -477,7 +584,8 @@ type = "Item" icon = "Icons.16x16.PasteIcon" loadclasslazy = "false" - class = "ICSharpCode.SharpDevelop.Project.Commands.PasteProjectBrowserNode"/> + class = "ICSharpCode.SharpDevelop.Project.Commands.PasteProjectBrowserNode" + /> + class = "ICSharpCode.SharpDevelop.Project.Commands.ShowPropertiesForNode" + command = "SDProjectCommands.ShowSelectedProjectBrowserNodeProperties" /> @@ -817,40 +926,40 @@ + command = "ApplicationCommands.Cut"/> + command = "ApplicationCommands.Copy"/> + command = "ApplicationCommands.Paste"/> + command = "ApplicationCommands.Delete"/> + command = "ApplicationCommands.Undo"/> + command = "ApplicationCommands.Redo"/> + class = "ICSharpCode.SharpDevelop.Project.Commands.Build" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.Rebuild" /> @@ -867,14 +976,16 @@ + class = "ICSharpCode.SharpDevelop.Project.Commands.Execute" + /> + class = "ICSharpCode.SharpDevelop.Project.Commands.ExecuteWithoutDebugger" + /> @@ -1134,13 +1245,13 @@ @@ -1149,13 +1260,13 @@ @@ -1164,13 +1275,13 @@ @@ -1189,7 +1300,7 @@ @@ -1203,7 +1314,7 @@ @@ -1212,7 +1323,7 @@ + shortcut = "Ctrl+Z" + command = "ApplicationCommands.Undo"/> + shortcut = "Ctrl+Y" + command = "ApplicationCommands.Redo"/> + shortcut = "Ctrl+X" + command = "ApplicationCommands.Cut"/> + shortcut = "Ctrl+C" + command = "ApplicationCommands.Copy"/> + shortcut = "Ctrl+V" + command = "ApplicationCommands.Paste"/> + command = "ApplicationCommands.Delete"/> @@ -1297,7 +1408,7 @@ label = "${res:XML.MainMenu.ToolMenu.InsColor}" class = "ICSharpCode.SharpDevelop.DefaultEditor.Commands.ShowColorDialog"/> @@ -1305,8 +1416,8 @@ + shortcut = "Ctrl+A" + command = "ApplicationCommands.SelectAll"/> @@ -1386,28 +1497,35 @@ label = "${res:XML.MainMenu.BuildMenu.BuildSolution}" shortcut = "F8" icon = "Icons.16x16.BuildCombine" - class = "ICSharpCode.SharpDevelop.Project.Commands.Build"/> + class = "ICSharpCode.SharpDevelop.Project.Commands.Build" + command = "SDBuildCommands.BuildSolution" + /> + shortcut = "Alt+F8" + class = "ICSharpCode.SharpDevelop.Project.Commands.Rebuild" + command = "SDBuildCommands.RebuildSolution" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.Clean" + command = "SDBuildCommands.CleanSolution" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.BuildProject" + command = "SDBuildCommands.BuildProject" /> + shortcut = "Alt+F9" + class = "ICSharpCode.SharpDevelop.Project.Commands.RebuildProject" + command = "SDBuildCommands.RebuildProject" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.CleanProject" + command = "SDBuildCommands.CleanProject" /> @@ -1417,21 +1535,28 @@ label="${res:XML.MainMenu.BuildMenu.AbortBuild}" shortcut="Pause" class="ICSharpCode.SharpDevelop.Project.Commands.AbortBuild" - loadclasslazy="false"/> + loadclasslazy="false" + command="SDBuildCommands.AbortBuild" /> - + - + + class = "ICSharpCode.SharpDevelop.Project.Commands.EditConfigurationsCommand" + command = "SDBuildCommands.EditConfigurationsCommand" /> @@ -1443,7 +1568,9 @@ label = "${res:XML.MainMenu.RunMenu.Run}" icon = "Icons.16x16.RunProgramIcon" shortcut = "F5" - class = "ICSharpCode.SharpDevelop.Project.Commands.Execute"/> + class = "ICSharpCode.SharpDevelop.Project.Commands.Execute" + command = "SDDebugCommands.Execute" + /> @@ -1454,8 +1581,9 @@ + shortcut = "Ctrl+F5" + class = "ICSharpCode.SharpDevelop.Project.Commands.ExecuteWithoutDebugger" + command = "SDDebugCommands.ExecuteWithoutDebugger" /> @@ -1465,7 +1593,8 @@ + class = "ICSharpCode.SharpDevelop.Project.Commands.StopDebuggingCommand" + command = "SDDebugCommands.StopDebugging" /> @@ -1473,7 +1602,8 @@ + class = "ICSharpCode.SharpDevelop.Project.Commands.AttachToProcessCommand" + command = "SDDebugCommands.AttachToProcess" /> @@ -1481,7 +1611,8 @@ + class = "ICSharpCode.SharpDevelop.Project.Commands.DetachFromProcessCommand" + command = "SDDebugCommands.DetachFromProcess" /> @@ -1491,15 +1622,17 @@ + shortcut = "Ctrl+Alt+B" + class = "ICSharpCode.SharpDevelop.Project.Commands.BreakDebuggingCommand" + command = "SDDebugCommands.BreakDebugging" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.ContinueDebuggingCommand" + command = "SDDebugCommands.ContinueDebugging" /> @@ -1510,17 +1643,20 @@ label = "${res:XML.MainMenu.DebugMenu.StepOver}" icon = "Icons.16x16.Debug.StepOver" shortcut = "F10" - class = "ICSharpCode.SharpDevelop.Project.Commands.StepDebuggingCommand"/> + class = "ICSharpCode.SharpDevelop.Project.Commands.StepDebuggingCommand" + command = "SDDebugCommands.StepOver" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.StepDebuggingCommand" + command = "SDDebugCommands.StepInto" /> + class = "ICSharpCode.SharpDevelop.Project.Commands.StepOutDebuggingCommand" + command = "SDDebugCommands.StepOut" /> @@ -1534,7 +1670,8 @@ label = "${res:XML.MainMenu.DebugMenu.ToggleBreakpoint}" shortcut = "F7" icon = "Bookmarks.Breakpoint" - class = "ICSharpCode.SharpDevelop.Project.Commands.ToggleBreakpointCommand"/> + class = "ICSharpCode.SharpDevelop.Project.Commands.ToggleBreakpointCommand" + command = "SDDebugCommands.ToggleBreakpoint" /> @@ -1613,11 +1750,11 @@ @@ -1634,7 +1771,7 @@ + command = "SDWindowCommands.SplitView"/> @@ -1904,7 +2041,7 @@ class= "ICSharpCode.SharpDevelop.DefaultEditor.Commands.CommentRegion"/> diff --git a/data/schemas/AddIn.xsd b/data/schemas/AddIn.xsd index f702fea82b..ddbd89248e 100644 --- a/data/schemas/AddIn.xsd +++ b/data/schemas/AddIn.xsd @@ -114,24 +114,27 @@ + - + + + - + @@ -184,24 +187,27 @@ + - + + + - + @@ -264,8 +270,8 @@ - The fully qualified type name of the class to create an instace of. - + The fully qualified type name of the class to create an instace of. + @@ -285,16 +291,16 @@ - Name of the ICodeCompletionBinding class (normally deriving from DefaultCodeCompletionBinding). - + Name of the ICodeCompletionBinding class (normally deriving from DefaultCodeCompletionBinding). + - List of semicolon-separated entries of the file extensions handled by the binding. - If no extensions attribute is specified, the binding is activated in all files. - + List of semicolon-separated entries of the file extensions handled by the binding. + If no extensions attribute is specified, the binding is activated in all files. + @@ -307,36 +313,81 @@ + + + + + + + Name of routed UI command which triggers this binding + + + + + + + Class implementing System.Window.Input.ICommand or + ICSharpCode.Core class. CanExecute and Executed methods + are used to handle raised event + + + + + + + Use lazy loading. If addin containing binded command is + not loaded yet load asseblies referenced in add-in + + + + + + + + + + + + + + + + + + Creates descriptor containing information about command binding + + + - The name of the MSBuild meta data. - + The name of the MSBuild meta data. + - The display name of the property. - + The display name of the property. + - The description text for the property. - + The description text for the property. + - Boolean property specifying whether the custom tool should be run when the property value is changed - by the user. Default: false. - + Boolean property specifying whether the custom tool should be run when the property value is changed + by the user. Default: false. + @@ -355,23 +406,23 @@ - ID used to identify the custom tool. - + ID used to identify the custom tool. + - Name of the ICustomTool class. - + Name of the ICustomTool class. + - Regular expression that specifies the file names for which the custom tool - can be used. Example: "\.res(x|ources)$" - + Regular expression that specifies the file names for which the custom tool + can be used. Example: "\.res(x|ources)$" + @@ -390,43 +441,43 @@ - Name of the IDebugger class. - + Name of the IDebugger class. + - Specifies if the debugger supports the 'Start' command. Default: true - + Specifies if the debugger supports the 'Start' command. Default: true + - Specifies if the debugger supports the 'StartWithoutDebugger' command. Default: true - + Specifies if the debugger supports the 'StartWithoutDebugger' command. Default: true + - Specifies if the debugger supports the 'Stop' (kill running process) command. Default: true - + Specifies if the debugger supports the 'Stop' (kill running process) command. Default: true + - Specifies if the debugger supports stepping. Default: false - + Specifies if the debugger supports stepping. Default: false + - Specifies if the debugger supports execution control (break, resume). Default: false - + Specifies if the debugger supports execution control (break, resume). Default: false + @@ -439,47 +490,14 @@ - - - - - - - - - - - - - Name of the IDialogPanel class. Optional if the page has subpages. - - - - - - - Caption of the dialog panel. - - - - - - - - - - Creates DefaultDialogPanelDescriptor objects that are used in option dialogs. - - - - Path relative to the directory which contains the .addin file defining the codon. - + Path relative to the directory which contains the .addin file defining the codon. + @@ -498,22 +516,22 @@ - Name of the IDisplayBinding or ISecondaryDisplayBinding class. - + Name of the IDisplayBinding or ISecondaryDisplayBinding class. + - Title of the display binding to use in the "Open With" dialog. - + Title of the display binding to use in the "Open With" dialog. + - Type of the display binding (either "Primary" or "Secondary"). Default: "Primary". - + Type of the display binding (either "Primary" or "Secondary"). Default: "Primary". + @@ -525,9 +543,9 @@ - Regular expression that specifies the file names for which the display binding - will be used. Example: "\.res(x|ources)$" - + Regular expression that specifies the file names for which the display binding + will be used. Example: "\.res(x|ources)$" + @@ -549,16 +567,16 @@ - Comma-separated list of keyboard shortcuts that activate the edit action. - E.g. "Control|C,Control|Insert" - + Comma-separated list of keyboard shortcuts that activate the edit action. + E.g. "Control|C,Control|Insert" + - Name of the IEditAction class. - + Name of the IEditAction class. + @@ -577,15 +595,15 @@ - The name of the file filter entry. - + The name of the file filter entry. + - The extensions associated with this file filter entry. - + The extensions associated with this file filter entry. + @@ -604,24 +622,24 @@ - The name of a bitmap resource in the resource service. - + The name of a bitmap resource in the resource service. + - This attribute is specified when a project icon association should be created. - It specifies the language of the project types that use the icon. - + This attribute is specified when a project icon association should be created. + It specifies the language of the project types that use the icon. + - This attribute is specified when a file icon association should be created. - It specifies the semicolon-separated list of file types that use the icon. - + This attribute is specified when a file icon association should be created. + It specifies the semicolon-separated list of file types that use the icon. + @@ -641,18 +659,18 @@ - When this attribute is used, the include doozer builds the item that is at the - addin tree location specified by this attribute. - + When this attribute is used, the include doozer builds the item that is at the + addin tree location specified by this attribute. + - When this attribute is used, the include doozer builds all items inside the - path addin tree location specified by this attribute and returns an - IBuildItemsModifier which includes all items in the output list. - + When this attribute is used, the include doozer builds all items inside the + path addin tree location specified by this attribute and returns an + IBuildItemsModifier which includes all items in the output list. + @@ -667,35 +685,62 @@ + + + + + + + Name of routed UI command which is triggered by this binding + + + + + + + Gesture which triggers this binding + + + + + + + + + + Creates descriptor containing information about input binding + + + - Project type GUID of the project used by MsBuild. - + Project type GUID of the project used by MsBuild. + - Semicolon-separated list of file extensions that are compilable files in the project. (e.g. ".boo") - + Semicolon-separated list of file extensions that are compilable files in the project. (e.g. ".boo") + - File extension of project files. (e.g. ".booproj") - + File extension of project files. (e.g. ".booproj") + - Name of the ILanguageBinding class. - + Name of the ILanguageBinding class. + @@ -720,18 +765,18 @@ - Label of the menu item. - + Label of the menu item. + - This attribute must be one of these values: - Separator, CheckBox, Item=Command, Menu (=with subitems), - Builder (=class implementing ISubmenuBuilder). - Default: Command. - + This attribute must be one of these values: + Separator, CheckBox, Item=Command, Menu (=with subitems), + Builder (=class implementing ISubmenuBuilder). + Default: Command. + @@ -747,39 +792,48 @@ - Only for the type "Item"/"Command". - When set to false, the command class is loaded - immediately instead of the usual lazy-loading. - + Only for the type "Item"/"Command". + When set to false, the command class is loaded + immediately instead of the usual lazy-loading. + - Icon of the menu item. - + Icon of the menu item. + - Command class that is run when item is clicked. - + Command class that is run when item is clicked. + + + + + + + A WPF routed command that is executed when item is clicked. + Currently, this property is supported only for WPF Menus. + Only one of the "class" and "command" attributes can be used on a menu entry. + - Only for the type "Item"/"Command". Opens a webpage instead of running a command when - clicking the item. - + Only for the type "Item"/"Command". Opens a webpage instead of running a command when + clicking the item. + - Shortcut that activates the command (e.g. "Control|S"). - + Shortcut that activates the command (e.g. "Control|S"). + @@ -792,49 +846,82 @@ + + + + + + + + + + + + + Name of the IOptionPanel class. Optional if the page has subpages. + + + + + + + Caption of the dialog panel. + + + + + + + + + + Creates DefaultOptionPanelDescriptor objects that are used in option dialogs. + + + - IPadContent class that is loaded when the pad content is shown for the first time. - + IPadContent class that is loaded when the pad content is shown for the first time. + - Title of the pad that is shown in the user interface. - Should be a resource string, e.g. "${res:AddIns.HtmlHelp2.Contents}" - + Title of the pad that is shown in the user interface. + Should be a resource string, e.g. "${res:AddIns.HtmlHelp2.Contents}" + - Specifies the name of the icon resource used for the pad. - Pad icon resources must be registered with the ResourceService before the - workbench is loaded! - + Specifies the name of the icon resource used for the pad. + Pad icon resources must be registered with the ResourceService before the + workbench is loaded! + - Category of the pad. It is possible to create menu items that automatically - contain show commands for all pads in a certain category. - Pads in the category "Main" will show up in the "View" menu, the category - "Tools" in the "View -> Tools" menu, the category "Debugger" in the - "View -> Debugger" menu. - + Category of the pad. It is possible to create menu items that automatically + contain show commands for all pads in a certain category. + Pads in the category "Main" will show up in the "View" menu, the category + "Tools" in the "View -> Tools" menu, the category "Debugger" in the + "View -> Debugger" menu. + - Shortcut that activates the 'Show pad' command (e.g. "Control|Alt|T"). - + Shortcut that activates the 'Show pad' command (e.g. "Control|Alt|T"). + @@ -853,22 +940,22 @@ - Semicolon-separated list of file extensions for which the parser is used. (e.g. ".boo") - + Semicolon-separated list of file extensions for which the parser is used. (e.g. ".boo") + - File extension of project files. (e.g. ".booproj") - + File extension of project files. (e.g. ".booproj") + - Name of the IParser class. - + Name of the IParser class. + @@ -887,8 +974,8 @@ - Name of the ProjectContentRegistry class. - + Name of the ProjectContentRegistry class. + @@ -901,50 +988,57 @@ - + - + - Specifies the name of the protocol the extension handles. (e.g. 'ms-help' or 'startpage') - + Routed UI command name + - + - Name of the ISchemeExtension class (normally deriving from DefaultSchemeExtension). - + Routed UI command displayed name + - + - Creates browser scheme extensions that can intercept calls on one protocol. + Creates descriptor containing information about routed UI command - + - + - The string to return. - + Specifies the name of the protocol the extension handles. (e.g. 'ms-help' or 'startpage') + + + + + + + Name of the ISchemeExtension class (normally deriving from DefaultSchemeExtension). + - + - Creates a string. + Creates browser scheme extensions that can intercept calls on one protocol. @@ -954,22 +1048,22 @@ - Name of the language for which the syntax mode is used. - + Name of the language for which the syntax mode is used. + - Semicolon-separated list of file extensions for which the syntax mode is used. - + Semicolon-separated list of file extensions for which the syntax mode is used. + - Fully qualified name of the resource file. - + Fully qualified name of the resource file. + @@ -983,22 +1077,42 @@ + + + + + + + The string to return. + + + + + + + + + + Creates a string. + + + - Name of the IMSBuildAdditionalLogger class. - + Name of the IMSBuildAdditionalLogger class. + - Specifies the name of the MSBuild task that must be running for - this logger to be active. - + Specifies the name of the MSBuild task that must be running for + this logger to be active. + @@ -1024,23 +1138,23 @@ - Label of the tool bar item. - + Label of the tool bar item. + - Icon of the tool bar item. - + Icon of the tool bar item. + - This attribute must be one of these values: - Separator, CheckBox, Item, ComboBox, DropDownButton - + This attribute must be one of these values: + Separator, CheckBox, Item, ComboBox, DropDownButton + @@ -1055,24 +1169,24 @@ - Only for the type "Item". When set to false, the command class is loaded - immediately instead of the usual lazy-loading. - + Only for the type "Item". When set to false, the command class is loaded + immediately instead of the usual lazy-loading. + - Tooltip of the tool bar item. - + Tooltip of the tool bar item. + - Command class that is run when item is clicked; or class that manages - the ComboBox/DropDownButton. Required for everything except "Separator". - + Command class that is run when item is clicked; or class that manages + the ComboBox/DropDownButton. Required for everything except "Separator". + diff --git a/doc/technotes/ConditionList.html b/doc/technotes/ConditionList.html index 7db94b07c3..0933d6ca96 100644 --- a/doc/technotes/ConditionList.html +++ b/doc/technotes/ConditionList.html @@ -5,7 +5,7 @@

Condition List

This file was generated by the tool 'BuildAddinDocumentation'. -It is based on SharpDevelop 3.0.0.3062.

+It is based on SharpDevelop 4.0.0.4126.

ActiveContentExtension

@@ -176,7 +178,7 @@ It is based on SharpDevelop 3.0.0.3062.

comparisonType: The mode of the comparison: a field of the System.StringComparison enumeration. The default is - 'InvariantCultureIgnoreCase'. + 'OrdinalIgnoreCase'. @@ -213,7 +215,7 @@ It is based on SharpDevelop 3.0.0.3062.

comparisonType: The mode of the comparison: a field of the System.StringComparison enumeration. The default is - 'InvariantCultureIgnoreCase'. + 'OrdinalIgnoreCase'. @@ -492,4 +494,29 @@ It is based on SharpDevelop 3.0.0.3062.


             <Condition name="WindowOpen" openwindow="*">

+
+

WriteableProject

+

+ Tests if the caller project is writable. If caller is not an IProject it tests + Project.CurrentProject. +

+ + + + +
Condition name: + ICSharpCode.SharpDevelop.WriteableProjectConditionEvaluator
+
+
+

WriteableSolution

+

+ Description of WriteableSolutionEvaluator. +

+ + + + +
Condition name: + ICSharpCode.SharpDevelop.WriteableSolutionConditionEvaluator
+
diff --git a/doc/technotes/DoozerList.html b/doc/technotes/DoozerList.html index e60e8ce1a4..a6d34b1dfe 100644 --- a/doc/technotes/DoozerList.html +++ b/doc/technotes/DoozerList.html @@ -5,28 +5,31 @@

Doozer List

This file was generated by the tool 'BuildAddinDocumentation'. -It is based on SharpDevelop 3.0.0.3062.

+It is based on SharpDevelop 4.0.0.4126.

@@ -70,7 +73,7 @@ It is based on SharpDevelop 3.0.0.3062.

+ @@ -103,6 +106,54 @@ It is based on SharpDevelop 3.0.0.3062.

Doozer name: - ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.CodeCompletionBindingDoozerICSharpCode.SharpDevelop.Editor.CodeCompletionBindingDoozer

Attributes:

+
+

CommandBinding

+

+ Creates descriptor containing information about command binding +

+ + + + + + + + + + + + + + + + + + + + + + + + +
Doozer name: + ICSharpCode.Core.CommandBindingDoozer

Attributes:

command: + required + Name of routed UI command which triggers this binding +
class: + required + Class implementing System.Window.Input.ICommand or + ICSharpCode.Core class. CanExecute and Executed methods + are used to handle raised event +
lazy: + optional + Use lazy loading. If addin containing binded command is + not loaded yet load asseblies referenced in add-in +

Usage: + Only in /SharpDevelop/Workbench/CommandBindings
Returns: + + CommandBindingDescriptor object +
+

CustomProperty

@@ -275,50 +326,6 @@ It is based on SharpDevelop 3.0.0.3062.

-
-

DialogPanel

-

- Creates DefaultDialogPanelDescriptor objects that are used in option dialogs. -

- - - - - - - - - - - - - - - - - - - - - - -
Doozer name: - ICSharpCode.SharpDevelop.DialogPanelDoozer

Attributes:

class: - - Name of the IDialogPanel class. Optional if the page has subpages. -
label: - required - Caption of the dialog panel. -

Children: - - In the SharpDevelop options, option pages can have subpages by specifying them - as children in the AddInTree. -
Usage: - In /SharpDevelop/BackendBindings/ProjectOptions/ and /SharpDevelop/Dialogs/OptionsDialog
Returns: - - A DefaultDialogPanelDescriptor object. -
-

Directory

@@ -590,6 +597,44 @@ It is based on SharpDevelop 3.0.0.3062.

+
+

InputBinding

+

+ Creates descriptor containing information about input binding +

+ + + + + + + + + + + + + + + + + + + + +
Doozer name: + ICSharpCode.Core.InputBindingDoozer

Attributes:

command: + required + Name of routed UI command which is triggered by this binding +
gesture: + required + Gesture which triggers this binding +

Usage: + Only in /SharpDevelop/Workbench/InputBindings
Returns: + + InputBindingDescriptor object +
+

LanguageBinding

@@ -693,6 +738,15 @@ It is based on SharpDevelop 3.0.0.3062.

Command class that is run when item is clicked. + + command: + optional + + A WPF routed command that is executed when item is clicked. + Currently, this property is supported only for WPF Menus. + Only one of the "class" and "command" attributes can be used on a menu entry. + + link: optional @@ -722,7 +776,7 @@ It is based on SharpDevelop 3.0.0.3062.

Returns: - Any ToolStrip* object, depending on the type attribute. + A MenuItemDescriptor object. @@ -731,6 +785,50 @@ It is based on SharpDevelop 3.0.0.3062.

+
+

OptionPanel

+

+ Creates DefaultOptionPanelDescriptor objects that are used in option dialogs. +

+ + + + + + + + + + + + + + + + + + + + + + +
Doozer name: + ICSharpCode.SharpDevelop.OptionPanelDoozer

Attributes:

class: + + Name of the IOptionPanel class. Optional if the page has subpages. +
label: + required + Caption of the dialog panel. +

Children: + + In the SharpDevelop options, option pages can have subpages by specifying them + as children in the AddInTree. +
Usage: + In /SharpDevelop/BackendBindings/ProjectOptions/ and /SharpDevelop/Dialogs/OptionsDialog
Returns: + + A DefaultOptionPanelDescriptor object. +
+

Pad

@@ -878,66 +976,77 @@ It is based on SharpDevelop 3.0.0.3062.

-

SchemeExtension

+

RoutedUICommand

- Creates browser scheme extensions that can intercept calls on one protocol. + Creates descriptor containing information about routed UI command

+ - - +
Doozer name: - ICSharpCode.SharpDevelop.BrowserDisplayBinding.SchemeExtensionDoozerICSharpCode.Core.RoutedUICommandDoozer

Attributes:

scheme: + name: required - Specifies the name of the protocol the extension handles. (e.g. 'ms-help' or 'startpage') + Routed UI command name
class: + text: required - Name of the ISchemeExtension class (normally deriving from DefaultSchemeExtension). + Routed UI command displayed name

Usage: - Only in /SharpDevelop/Views/Browser/SchemeExtensionsOnly in /SharpDevelop/Workbench/CommandBindings
Returns: - An SchemeExtensionDescriptor object that exposes the protocol name and ISchemeExtension object (lazy-loading). + RoutedUICommandDescriptor object
-

String

+

SchemeExtension

- Creates a string. + Creates browser scheme extensions that can intercept calls on one protocol.

+ - + + + + + + +
Doozer name: - ICSharpCode.Core.StringDoozerICSharpCode.SharpDevelop.BrowserDisplayBinding.SchemeExtensionDoozer

Attributes:

text: + scheme: required - The string to return. + Specifies the name of the protocol the extension handles. (e.g. 'ms-help' or 'startpage') +
class: + required + Name of the ISchemeExtension class (normally deriving from DefaultSchemeExtension).

Usage: + Only in /SharpDevelop/Views/Browser/SchemeExtensions
Returns: - The string specified by 'text', passed through the StringParser. + An SchemeExtensionDescriptor object that exposes the protocol name and ISchemeExtension object (lazy-loading).
@@ -989,6 +1098,33 @@ It is based on SharpDevelop 3.0.0.3062.

+
+

String

+

+ Creates a string. +

+ + + + + + + + + + + + + +
Doozer name: + ICSharpCode.Core.StringDoozer

Attributes:

text: + required + The string to return. +

Returns: + + The string specified by 'text', passed through the StringParser. +
+

TaskBoundAdditionalLogger

diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin b/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin index 611081376f..db6bb8596a 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin @@ -164,7 +164,7 @@ category = "Main" title = "${res:ICSharpCode.BooInterpreter}" icon = "Boo.ProjectIcon" - shortcut = "Control|Shift|B" + shortcut = "Ctrl+Shift+B" class = "Grunwald.BooBinding.InteractiveInterpreterPad" defaultPosition = "Bottom, Hidden" /> diff --git a/src/AddIns/BackendBindings/FSharp/FSharpBinding/Project/FSharpBinding.addin b/src/AddIns/BackendBindings/FSharp/FSharpBinding/Project/FSharpBinding.addin index 5b7215928d..75b343f28b 100644 --- a/src/AddIns/BackendBindings/FSharp/FSharpBinding/Project/FSharpBinding.addin +++ b/src/AddIns/BackendBindings/FSharp/FSharpBinding/Project/FSharpBinding.addin @@ -109,7 +109,7 @@ diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs index f9c699c9f4..4a0760826f 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs @@ -117,7 +117,13 @@ namespace ICSharpCode.AvalonEdit.AddIn public CodeEditor() { - this.CommandBindings.Add(new CommandBinding(SharpDevelopRoutedCommands.SplitView, OnSplitView)); + var contextName = this.GetType().FullName; + CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, this, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, contextName, this)); + CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, this, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, contextName, this)); + CommandsRegistry.RegisterCommandBinding(contextName, this, "SDWindowCommands.SplitView", OnSplitView, OnCanSplitView); + + CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, this); + CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, this); textMarkerService = new TextMarkerService(this); iconBarManager = new IconBarManager(); @@ -198,6 +204,10 @@ namespace ICSharpCode.AvalonEdit.AddIn primaryTextEditor.Save(stream); } + void OnCanSplitView(object sender, CanExecuteRoutedEventArgs e) + { + e.CanExecute = true; + } void OnSplitView(object sender, ExecutedRoutedEventArgs e) { if (secondaryTextEditor == null) { diff --git a/src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.addin b/src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.addin index b52412207d..f7760dc214 100644 --- a/src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.addin +++ b/src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.addin @@ -40,7 +40,7 @@ + shortcut = "Ctrl+Shift+V" /> @@ -81,7 +81,7 @@ + shortcut="Ctrl+Shift+T"/> - - + + @@ -203,17 +203,17 @@ diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin index 646be89dae..4fba1c0984 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin @@ -73,7 +73,7 @@ category = "Debugger" title = "${res:MainWindow.Windows.Debug.Breakpoints}" icon = "PadIcons.BreakPoints" - shortcut = "Control|Alt|P" + shortcut = "Ctrl+Alt+P" class = "ICSharpCode.SharpDevelop.Gui.Pads.BreakPointsPad" defaultPosition = "Bottom, Hidden" /> @@ -81,7 +81,7 @@ category = "Debugger" title = "${res:MainWindow.Windows.Debug.CallStack}" icon = "PadIcons.CallStack" - shortcut = "Control|Alt|C" + shortcut = "Ctrl+Alt+C" class = "ICSharpCode.SharpDevelop.Gui.Pads.CallStackPad" defaultPosition = "Bottom, Hidden" /> @@ -89,7 +89,7 @@ category = "Debugger" title = "${res:MainWindow.Windows.Debug.Modules}" icon = "PadIcons.LoadedModules" - shortcut = "Control|Alt|U" + shortcut = "Ctrl+Alt+U" class = "ICSharpCode.SharpDevelop.Gui.Pads.LoadedModulesPad" defaultPosition = "Bottom, Hidden" /> @@ -97,7 +97,7 @@ category = "Debugger" title = "${res:MainWindow.Windows.Debug.Threads}" icon = "PadIcons.Threads" - shortcut = "Control|Alt|H" + shortcut = "Ctrl+Alt+H" class = "ICSharpCode.SharpDevelop.Gui.Pads.RunningThreadsPad" defaultPosition = "Bottom, Hidden" /> @@ -105,7 +105,7 @@ category = "Debugger" title = "${res:MainWindow.Windows.Debug.LocalVariables}" icon = "PadIcons.LocalVariables" - shortcut = "Control|Alt|V" + shortcut = "Ctrl+Alt+V" class = "ICSharpCode.SharpDevelop.Gui.Pads.LocalVarPad" defaultPosition = "Bottom, Hidden" /> @@ -113,7 +113,7 @@ category = "Debugger" title = "${res:MainWindow.Windows.Debug.Console}" icon = "PadIcons.Output" - shortcut = "Control|Alt|N" + shortcut = "Ctrl+Alt+N" class = "ICSharpCode.SharpDevelop.Gui.Pads.ConsolePad" defaultPosition = "Bottom, Hidden" /> @@ -121,7 +121,7 @@ category = "Debugger" title = "${res:MainWindow.Windows.Debug.Watch}" icon = "PadIcons.LocalVariables" - shortcut = "Control|Alt|W" + shortcut = "Ctrl+Alt+W" class = "ICSharpCode.SharpDevelop.Gui.Pads.WatchPad" defaultPosition = "Bottom, Hidden" /> diff --git a/src/AddIns/Misc/HtmlHelp2/Project/HtmlHelp2.addin b/src/AddIns/Misc/HtmlHelp2/Project/HtmlHelp2.addin index 9901a37ff7..8b2ebb1989 100644 --- a/src/AddIns/Misc/HtmlHelp2/Project/HtmlHelp2.addin +++ b/src/AddIns/Misc/HtmlHelp2/Project/HtmlHelp2.addin @@ -67,24 +67,24 @@ insertafter = "HtmlHelp2Separator2" label = "${res:AddIns.HtmlHelp2.Contents}" icon = "HtmlHelp2.16x16.Toc" - shortcut = "Control|Alt|F1" + shortcut = "Ctrl+Alt+F1" class = "HtmlHelp2.ShowTocMenuCommand"/> @@ -92,7 +92,7 @@ insertbefore = "TocPadCommand" label = "${res:AddIns.HtmlHelp2.DynamicHelp}" icon = "HtmlHelp2.16x16.DynamicHelp" - shortcut = "Control|F1" + shortcut = "Ctrl+F1" class = "HtmlHelp2.ShowDynamicHelpMenuCommand"/> diff --git a/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchAndReplaceDialog.cs b/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchAndReplaceDialog.cs index 0e83d92e64..8995109ba0 100644 --- a/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchAndReplaceDialog.cs +++ b/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchAndReplaceDialog.cs @@ -87,8 +87,16 @@ namespace SearchAndReplace SetSearchAndReplaceMode(); FormLocationHelper.Apply(this, "ICSharpCode.SharpDevelop.Gui.SearchAndReplaceDialog.Location", false); - searchKeyboardShortcut = GetKeyboardShortcut(SearchMenuAddInPath, "Find"); - replaceKeyboardShortcut = GetKeyboardShortcut(SearchMenuAddInPath, "Replace"); + // Register shortcuts in "search & replace" dialog + GesturePlaceHolderRegistry.RegisterUpdateHandler("SDSearchAndReplace.Find", delegate { + searchKeyboardShortcut = GesturePlaceHolderRegistry.GetGestures("SDSearchAndReplace.Find")[0]; + }); + GesturePlaceHolderRegistry.RegisterUpdateHandler("SDSearchAndReplace.Replace", delegate { + replaceKeyboardShortcut = GesturePlaceHolderRegistry.GetGestures("SDSearchAndReplace.Find")[0]; + }); + + GesturePlaceHolderRegistry.InvokeUpdateHandlers("SDSearchAndReplace.Find"); + GesturePlaceHolderRegistry.InvokeUpdateHandlers("SDSearchAndReplace.FindReplace"); } protected override void OnClosing(System.ComponentModel.CancelEventArgs e) @@ -144,17 +152,17 @@ namespace SearchAndReplace /// Gets the keyboard shortcut for the menu item with the given addin tree /// path and given codon id. /// - Keys GetKeyboardShortcut(string path, string id) + Keys[] GetKeyboardShortcut(string path, string id) { AddInTreeNode node = AddInTree.GetTreeNode(path); if (node != null) { foreach (Codon codon in node.Codons) { if (codon.Id == id) { - return MenuCommand.ParseShortcut(codon.Properties["shortcut"]); + return (Keys[])new KeysCollectionConverter().ConvertFromInvariantString(codon.Properties["shortcut"]); } } } - return Keys.None; + return new Keys[] { Keys.None }; } } } diff --git a/src/AddIns/Misc/SearchAndReplace/Project/SearchAndReplace.addin b/src/AddIns/Misc/SearchAndReplace/Project/SearchAndReplace.addin index 66ff3dcbbd..7c11629894 100644 --- a/src/AddIns/Misc/SearchAndReplace/Project/SearchAndReplace.addin +++ b/src/AddIns/Misc/SearchAndReplace/Project/SearchAndReplace.addin @@ -11,30 +11,56 @@ + + + + + + + + + + + + + + + + + + + + + + + shortcut = "Ctrl+F" + class = "SearchAndReplace.Find" + command="SDSearchAndReplace.Find" /> + class = "SearchAndReplace.FindNext" + command="SDSearchAndReplace.FindNext" /> + shortcut = "Ctrl+F3" + class = "SearchAndReplace.FindNextSelected" + command="SDSearchAndReplace.FindNextSelected" /> + shortcut = "Ctrl+R" + class = "SearchAndReplace.Replace" + command="SDSearchAndReplace.Replace" /> diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.sln b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.sln new file mode 100644 index 0000000000..b68e9ed658 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.sln @@ -0,0 +1,23 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShortcutsManagement", "ShortcutsManagement\ShortcutsManagement.csproj", "{CF2FF1D1-A5FE-4848-936A-E2DFBE154562}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug in SharpDevelop|Any CPU = Debug in SharpDevelop|Any CPU + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF2FF1D1-A5FE-4848-936A-E2DFBE154562}.Debug in SharpDevelop|Any CPU.ActiveCfg = Debug in SharpDevelop|Any CPU + {CF2FF1D1-A5FE-4848-936A-E2DFBE154562}.Debug in SharpDevelop|Any CPU.Build.0 = Debug in SharpDevelop|Any CPU + {CF2FF1D1-A5FE-4848-936A-E2DFBE154562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF2FF1D1-A5FE-4848-936A-E2DFBE154562}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF2FF1D1-A5FE-4848-936A-E2DFBE154562}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF2FF1D1-A5FE-4848-936A-E2DFBE154562}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo new file mode 100644 index 0000000000000000000000000000000000000000..8e13b9c93a269146a31f9a57691071e24e275521 GIT binary patch literal 51712 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 literal 0 HcmV?d00001 diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/App.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/App.xaml new file mode 100644 index 0000000000..2580950ff6 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/App.xaml @@ -0,0 +1,8 @@ + + + + + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/App.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/App.xaml.cs new file mode 100644 index 0000000000..a456dce54f --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/App.xaml.cs @@ -0,0 +1,11 @@ +using System.Windows; + +namespace ICSharpCode.ShortcutsManagement +{ + ///

+ /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/AssemblyInfo.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..1b7cb88293 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ShortcutsManagement")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Nexum Insurance Technologies")] +[assembly: AssemblyProduct("ShortcutsManagement")] +[assembly: AssemblyCopyright("Copyright © Nexum Insurance Technologies 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Resources.Designer.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..04cdec7e18 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.3082 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ICSharpCode.ShortcutsManagement.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ICSharpCode.ShortcutsManagement.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Resources.resx b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Resources.resx new file mode 100644 index 0000000000..af7dbebbac --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Settings.Designer.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Settings.Designer.cs new file mode 100644 index 0000000000..f2395b7165 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.3082 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ICSharpCode.ShortcutsManagement.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Settings.settings b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Settings.settings new file mode 100644 index 0000000000..033d7a5e9e --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..0aa333449aa3aa7515dabf3ac9fc0c1a7e503cd5 GIT binary patch literal 4608 zcmeHK2~ZSA6z$m?mTO@TWIdK+O+ruv0}(Gg2q0Jz4iy0v6j+c$5mYp26qPHr2&fQ6 zNYogQBrdod3Sv+|LNoy-3M+)LTq=pW3%aZaO#UDm%NUDTl~g6gpLz3pdVWv;*T4JE zbX_g0^jDuYU;P^g-8I*p;Fsino#WHPmN^!2oLSUOCm9#@ZL zz~*o`TDm+#F56I_&0!NS!N|~tLe-#BHQ3rrZT8<5yd1F@FlPj0%mk5G7@39PmBc*4 zsNgN(@Q`36@R3GmXlOFQpb%CFMkbReWWsB(-VDzXg+6r5|LN z&dEQ|@wlQeo4jIeyoM&1XE@48IR34--!XsB#`gUwc2nm%eBkKhJkQ0`YvH2B-b;K| z1_lL-LPA$X$E;hwA$H@Y?K^fRBqk-NWbEFvH#6(geftj`{^H1&M~@vpaY|ZHSX6xa zOv#0c%BqXi-_?A7wf?7T*BcsTH{@;Y9i3e_Z{6-z_VnI=pz2dUd_?fV5cw&s=geN> z#R6U=3WZFe6TC3e1^}5wp&DD!^k=)%1ELH}thX`PbJ7pypVu&*?4jVSSbIg2YxbU8 zs3fQjG8-PT_%~wqoY)_{ZXhi(2Eikp^*$xk$QnWnYN=eL20PyFl7F=KM~~5MWglG&D{BgS0ybyzRn$9nSr*_sv_&kiFdAAwwPPxZX(OyJrtWgU%2?f z{%iJvHnx}=OnLv>E-Lc=ty=LTnexE^Jywb z%U>iDR)&dh;+*p#;2Y637QH$I8 zIO4~KJs#(#NG%)P)8aGl=7P*NGq2O)#tf-JpVxibR^!z>TlmFE<{?F=$>Xde?f0GB zF2A@fLLRZvzdo(WXSuK2^y}Rn)m@H?6M3E&4mkfjwL|oI6^?kTik2DHA1*x?>>OB9 zB=tz~ez^O`G{;HPcHe&WA8^D8ieJy=iEw1nR7Z+)OLDbLls@65;%JYX`|XC= zsH^boI{$_!?*;ibwK8GoScYuj&-25-eP;!2t&_);+B(IAlg+XWo#bPdkL!IuR(_9K zr$;F(Dt^(QDU;`D+qjmwIxBH{EixrDT{k(c)ridhM#i8zxPCFJ-Cbc%hoSigYkb}eg~*n!nyze literal 0 HcmV?d00001 diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/key_enter.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/key_enter.png new file mode 100644 index 0000000000000000000000000000000000000000..0182ca646ed38c48cbc3a911bb51dbabb9fb5915 GIT binary patch literal 1056 zcmV+*1mF9KP)GvogL9-U4HcXxNU&1Q2gNs@m|961O$5rw(za2v`P>jAIHdd<#v;<@j9<*W7qDJ8ob zj1Ro*dsneC1P}y4Ul9AKbro^{G0&xzArT=A!&2b(I`_@eO$$3Y@_N8Hy%)IMZ@1gn z-`~g4(NSN2lv2Q4EMEywIB*^xAF;W)2`MGQFhsN21T&-6YI##YMCA$e11BPkj*en= zbrqMFmx$vSV`F1rW;7ZNuQ5xR5WoupHn^RhFbr{UaDa=83p_tRBaUOQ{8l>4DPaAO zgW9vOk6{2FII3UjHslQ`v5}k*4X3LA|zI zUrCbW%h}o4$Mf^^KMSN^naNnST8$fx#%8C}@do_ba&vQYcXf632Y}DaoG*m}0U`rU9fVo_s;}Oc@?C av;Gge$(Iw&cy25J0000Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGXbpQYZbpg<9qoDu*02p*dSaefwW^{L9a%BKeVQFr3 zE>1;MAa*k@Gd8K`;w1n81XW2yK~z{rwU^IJR8bVi`$0j!Yt+J$2q^|i#ErNRMO?TL zcdl#~h?oc>B1jt%352qme%e+BL=Zs)F+l{gOq)zI#4?;A5k%+@C>OW$xx6#n87H5` zYv9Y9dGp@6pYuKE-gn=@1ONUxBDYqHZi>3knKM zQ&W>^X=yR7t*xfLz1?(lbl4+mYil!QWo4$Qs0g^PqMRTAj!KYMB_$2*VrlzbWCnv1{0z};aVqjpv0Iu6gMV0^ok`A%7v}86nHvxDV6u^5rJQj;3MV7$05Hu&v2f)_WR-gbenvlR~ zVPV0_g`g+2AO42}3(WnMl@%)*OhJI499jxo0B&PrBhVgLY;JBgtE;PKZEejS0Re)t zXen?(0k|&6S+LaD*l5<**OLMQC$tpwf|da&0RI-?klc_-C*=I6hK2@fD`JX~p}OFf zfj$5LclNswh2+A!qSvB#qIpqF^g;Adv?%&fUte!K8v%hExWGWArKKr-01(c|eb4-+ zAsI(2Dk@BEZLR6*>ayzW>`Xpn=zbnRtn=I3+g8kRT+lK|4BH3VhydWiegLv_a&o@Z z)z#VN!9Ie})oLR)lPy`h0P29ZR${<@{q`fWpGUcq9@@ zKI>W60U(H523*i-sB3{vLjc@qsBY{Fpt!g=-q+V>Hx@ir0nk2hU7!>=p^K0X?loJ= zN(ca@6acnmdwz0drxWKH&a)fOOX@&%AN9A|K(TQ1iH zErmXSyv$4}6mpx*I;T%V;Q1|sKlBACFE5W{KYKYXgSw!l0D^K*DzeQa&7K$l@LR5X z;0sV$Ss5pDErYt?LJ$yJDUlA&&bOwf##C2V+ug8ckCR%CeFG3!ceG@X34)-yB@<{P zvnRPP)LpVV$+eslfL>n*s;a8u0QC3wTNm6?=;}y4bt9U-A$14WO{r6Y`@R5TVVt1c zq!0vBCxBBB%A#`L4|Fq10{rg)-17qnNgY4yde5BJ?Y5h>`#zBVZr}p(9S6Oh+L6I; z`2ieey_S`2hxtubIwjpBK{JVrGf7s~UwL_XZzT44KLGweBdYKkhNcNZO%ms_h{ydO zKV;8)A8)%SMcJYYqKl$DFTfQ!=8LXo5a;=yfw-RgxSu$uy|~0@oLwKtbnsL1{j39U z$qUK=*F<5_b + + + + + + + + + + + + + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj new file mode 100644 index 0000000000..c4b85c436d --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj @@ -0,0 +1,156 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {CF2FF1D1-A5FE-4848-936A-E2DFBE154562} + WinExe + Properties + ICSharpCode.ShortcutsManagement + ICSharpCode.ShortcutsManagement + v3.5 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + ..\..\..\..\..\AddIns\AddIns\Misc\ShortcutsManagement\ + DEBUG;TRACE + full + AnyCPU + true + GlobalSuppressions.cs + prompt + + + + False + ..\..\..\..\..\bin\ICSharpCode.Core.dll + + + False + ..\..\..\..\..\bin\ICSharpCode.SharpDevelop.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + 3.0 + + + 3.0 + + + 3.0 + + + 3.0 + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + Window1.xaml + Code + + + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + ShortcutsManagementOptionsPanel.xaml + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + Always + + + + + \ No newline at end of file diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj.user b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj.user new file mode 100644 index 0000000000..fa85230431 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj.user @@ -0,0 +1,6 @@ + + + Program + C:\VSC\SharpDevelop40\SharpDevelop\bin\SharpDevelop.exe + + \ No newline at end of file diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs new file mode 100644 index 0000000000..0137209f1c --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Globalization; +using System.Windows.Data; + +namespace ICSharpCode.ShortcutsManagement +{ + public class GesturesListConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is IEnumerable && (targetType == typeof(string) || targetType.IsSubclassOf(typeof(string)))) + { + var enumerableValue = (IEnumerable)value; + return string.Join(" | ", enumerableValue.ToArray()); + } + + return value.ToString(); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException("Reverse convertion is not implemented:"); + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/ShortcutsTreeConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/ShortcutsTreeConverter.cs new file mode 100644 index 0000000000..3255d1466f --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/ShortcutsTreeConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Windows.Data; + +namespace ICSharpCode.ShortcutsManagement +{ + public class ShortcutsTreeConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + var items = new List(); + items.AddRange(((IEnumerable)values[0]).Cast()); + items.AddRange(((IEnumerable)values[1]).Cast()); + + return items; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new System.NotImplementedException(); + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/TypeNameConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/TypeNameConverter.cs new file mode 100644 index 0000000000..eba1046599 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/TypeNameConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace ICSharpCode.ShortcutsManagement +{ + class TypeNameConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value.GetType().Name; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new System.NotImplementedException(); + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs new file mode 100644 index 0000000000..a4fa2d85b2 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/AddIn.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using System.ComponentModel; + +namespace ICSharpCode.ShortcutsManagement +{ + /// + /// Add-in where shortcuts were registered + /// + public class AddIn : INotifyPropertyChanged + { + private string name; + + /// + /// Add-in name + /// + /// Dependency property + /// + public string Name + { + get + { + return name; + } + set + { + if (name != value) + { + name = value; + InvokePropertyChanged("Name"); + } + } + } + + private bool isVisible; + + /// + /// Is category visible in shortcuts tree + /// + /// Dependency property + /// + public bool IsVisible + { + get + { + return isVisible; + } + set + { + if (isVisible != value) + { + isVisible = value; + InvokePropertyChanged("IsVisible"); + } + } + } + + public List Categories + { + get; + private set; + } + + public AddIn(string addInName) + { + IsVisible = true; + Name = addInName; + Categories = new List(); + } + + /// + /// Invoke dependency property changed event + /// + /// Name of dependency property from this classs + private void InvokePropertyChanged(string propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs new file mode 100644 index 0000000000..91278bd297 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.ComponentModel; + +namespace ICSharpCode.ShortcutsManagement +{ + /// + /// Shortcut + /// + public class Shortcut : INotifyPropertyChanged + { + /// + /// List of keyboard gestures which will invoke provided action + /// + public List Gestures + { + get; + private set; + } + + private string name; + + /// + /// Shortcut action name + /// + public string Name + { + get + { + return name; + } + set + { + if(name != value) + { + name = value; + InvokePropertyChanged("Name"); + } + } + } + + private bool isVisible; + + /// + /// Is category visible in shortcuts tree + /// + /// Dependency property + /// + public bool IsVisible + { + get + { + return isVisible; + } + set + { + if(isVisible != value) + { + isVisible = value; + InvokePropertyChanged("IsVisible"); + } + } + } + + /// + /// Create new shortcut + /// + /// Shortcut action name + /// Gestures + public Shortcut(string shortcutName, List gestures) + { + IsVisible = true; + Name = shortcutName; + Gestures = gestures ?? new List(); + } + + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Invoke dependency property changed event + /// + /// Name of dependency property from this classs + private void InvokePropertyChanged(string propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs new file mode 100644 index 0000000000..8c1a6e14e5 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutCategory.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.ComponentModel; + +namespace ICSharpCode.ShortcutsManagement +{ + /// + /// Shortcut category + /// + public class ShortcutCategory : INotifyPropertyChanged + { + private string name; + + /// + /// Category name + /// + /// Dependency property + /// + public string Name + { + get + { + return name; + } + set + { + if (name != value) + { + name = value; + InvokePropertyChanged("Name"); + } + } + } + + private bool isVisible; + + /// + /// Is category visible in shortcuts tree + /// + /// Dependency property + /// + public bool IsVisible + { + get + { + return isVisible; + } + set + { + if (isVisible != value) + { + isVisible = value; + InvokePropertyChanged("IsVisible"); + } + } + } + + /// + /// Sub cateories + /// + public List SubCategories + { + get; + private set; + } + + /// + /// Shortcuts assigned to this category + /// + public List Shortcuts + { + get; + private set; + } + + /// + /// Create new category + /// + /// Category name + public ShortcutCategory(string categoryName) + { + IsVisible = true; + Shortcuts = new List(); + SubCategories = new List(); + Name = categoryName; + } + + /// + /// Invoke dependency property changed event + /// + /// Name of dependency property from this classs + private void InvokePropertyChanged(string propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs new file mode 100644 index 0000000000..c66c65ff1e --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace ICSharpCode.ShortcutsManagement +{ + internal class ShortcutsProvider + { + private readonly ObservableCollection addins = new ObservableCollection(); + + /// + /// Get list of add-ins containing shortcuts + /// + /// List of add-ins + public ObservableCollection GetAddIns() + { + return addins; + } + + /// + /// Filter addins, child categories and shortcuts where item name + /// contains filter string + /// + /// Filter string + public void Filter(string filterString) + { + foreach (var addIn in addins) + { + var addInNameContainsFilterString = addIn.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0; + + var subCategoryIsVisible = false; + foreach (var category in addIn.Categories) + { + if(Filter(category, filterString, addInNameContainsFilterString ? (bool?) true : null)) + { + subCategoryIsVisible = true; + } + } + + addIn.IsVisible = addInNameContainsFilterString || subCategoryIsVisible; + } + } + + /// + /// Filter category and child elements where item name contains + /// filter string + /// + /// Category to filter + /// Filter string + /// If set to true all sub elements are expanded + /// + private static bool Filter(ShortcutCategory category, string filterString, bool? forseMatch) + { + if(category.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0) + { + forseMatch = true; + } + + var isSubElementVisible = false; + foreach (var subCategory in category.SubCategories) + { + if(Filter(subCategory, filterString, forseMatch)) + { + isSubElementVisible = true; + } + } + + foreach (var shortcut in category.Shortcuts) + { + if ((forseMatch.HasValue && forseMatch.Value) || shortcut.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0) + { + shortcut.IsVisible = true; + isSubElementVisible = true; + } + else + { + shortcut.IsVisible = false; + } + } + + return category.IsVisible = (forseMatch.HasValue && forseMatch.Value) || isSubElementVisible; + } + + public ShortcutsProvider() + { + // Test data + addins.Add(new AddIn("SharpDevelop")); + addins[0].Categories.Add(new ShortcutCategory("Editing")); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Copy", new List { "Ctrl+C" })); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Paste", new List { "Ctrl+V", "Ctrl+Insert" })); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Cut", new List { "Ctrl+X" })); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Undo", new List { "Ctrl+Z" })); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Redo", new List { "Ctrl+Y" })); + addins[0].Categories.Add(new ShortcutCategory("Building")); + addins[0].Categories[1].Shortcuts.Add(new Shortcut("Build", new List { "Ctrl+Shift+B" })); + addins[0].Categories[1].Shortcuts.Add(new Shortcut("Run", new List { "F5" })); + addins[0].Categories[1].Shortcuts.Add(new Shortcut("Run without debuger", new List { "Ctrl+F5" })); + addins[0].Categories[1].Shortcuts.Add(new Shortcut("Attach debuger", new List { "Ctrl+F8" })); + addins[0].Categories.Add(new ShortcutCategory("Uncategorized")); + addins[0].Categories[2].Shortcuts.Add(new Shortcut("Attach debuger", new List { "Ctrl+F8" })); + + + addins.Add(new AddIn("Search & replace")); + addins[1].Categories.Add(new ShortcutCategory("Uncategorized")); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick find", new List { "Ctrl+F" })); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick replace", new List { "Ctrl+H" })); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find in files", new List { "Ctrl+Shift+F" })); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Replace in files", new List { "Ctrl+Shift+H" })); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find symbol", null)); + + addins.Add(new AddIn("Unspecified")); + addins[2].Categories.Add(new ShortcutCategory("Uncategorized")); + addins[2].Categories[0].Shortcuts.Add(new Shortcut("Test regex expression", null)); + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml new file mode 100644 index 0000000000..a421114824 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml @@ -0,0 +1,171 @@ + + + + + + + + + ..\..\Resources\key_enter.png + ..\..\Resources\key_enter_pressed.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs new file mode 100644 index 0000000000..fe19e3ed2b --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using ICSharpCode.SharpDevelop; + +namespace ICSharpCode.ShortcutsManagement +{ + /// + /// This panel is used in SharpDevelop options window to manage shortcuts + /// + public partial class ShortcutsManagementOptionsPanel : UserControl, IOptionPanel + { + public ShortcutsManagementOptionsPanel() + { + InitializeComponent(); + + } + + private void shortcutEntry_MouseDown(object sender, MouseButtonEventArgs e) + { + if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2) + { + MessageBox.Show("Changing shortcut"); + } + } + + /// + /// Filter shortcuts tree view. Display only matching shortcuts + /// + /// + /// + private void searchTextBox_KeyUp(object sender, KeyEventArgs e) + { + var receiver = ((ShortcutsProvider) Resources["ShortcutsReceiver"]); + receiver.Filter(searchTextBox.Text); + + if (!string.IsNullOrEmpty(searchTextBox.Text)) + { + // Select first visible shortcut + var selectedAddIn = receiver.GetAddIns().FirstOrDefault(a => a.IsVisible); + if (selectedAddIn != null) + { + var selectedCategory = selectedAddIn.Categories.FirstOrDefault(c => c.IsVisible); + if (selectedCategory != null) + { + var selectedShortcut = selectedCategory.Shortcuts.FirstOrDefault(s => s.IsVisible); + if (selectedShortcut != null) + { + shortcutsTreeView.SelectItem(new List { selectedAddIn, selectedCategory, selectedShortcut }); + } + } + } + } + else + { + shortcutsTreeView.SetExpandAll(false); + } + } + + public void LoadOptions() + { + } + + public bool SaveOptions() + { + return true; + } + + public object Owner + { + get; set; + } + + public object Control + { + get + { + return this; + } + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs new file mode 100644 index 0000000000..44f68e3e86 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs @@ -0,0 +1,83 @@ +using System.Text.RegularExpressions; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; + +namespace ICSharpCode.ShortcutsManagement +{ + /// + /// TextBlockBehavior.SearchedText attached property + /// + public static class TextBlockBehavior + { + /// + /// Get attached property value + /// + /// Attached property host + /// Attached property value + public static string GetSearchedText(TextBlock textBlock) + { + return (string)textBlock.GetValue(SearchedTextProperty); + } + + /// + /// Set attached property value + /// + /// Attached property host + /// New attached property value + public static void SetSearchedText(TextBlock textBlock, string value) + { + textBlock.SetValue(SearchedTextProperty, value); + } + + public static readonly DependencyProperty SearchedTextProperty = + DependencyProperty.RegisterAttached( + "SearchedText", + typeof(string), + typeof(TextBlockBehavior), + new UIPropertyMetadata(null, OnSearchedTextChanged)); + + /// + /// On SearchedText changed highlight text in TextBlock which matches + /// attached property value + /// + /// + /// + private static void OnSearchedTextChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e) + { + var textBlock = (TextBlock) depObj; + + var textBlockText = textBlock.Text; + textBlock.Inlines.Clear(); + + var matches = Regex.Matches(textBlockText, @"(.*)(" + Regex.Escape((string)e.NewValue) + @")(.*)", RegexOptions.IgnoreCase); + if (matches.Count > 0) + { + foreach (Match match in matches) + { + var matchedTextPrefix = match.Groups[1].Value; + if (!string.IsNullOrEmpty(matchedTextPrefix)) + { + textBlock.Inlines.Add(new Run(matchedTextPrefix)); + } + + var matchedText = match.Groups[2].Value; + if (!string.IsNullOrEmpty(matchedText)) + { + textBlock.Inlines.Add(new Bold(new Run(matchedText))); + } + + var matchedTextSuffix = match.Groups[3].Value; + if (!string.IsNullOrEmpty(matchedTextSuffix)) + { + textBlock.Inlines.Add(new Run(matchedTextSuffix)); + } + } + } + else + { + textBlock.Inlines.Add(new Run(textBlockText)); + } + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs new file mode 100644 index 0000000000..5b0de181a2 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; + +namespace ICSharpCode.ShortcutsManagement +{ + /// + /// TreeView extention methods + /// + public static class TreeViewExtensions + { + /// + /// Expand TreeView items according to provided path and select element + /// on the lowest level + /// + /// TreeView or TreeViewItem + /// Path to the selected item + public static void SelectItem(this ItemsControl parentContainer, List path) + { + var head = path.First(); + var tail = path.GetRange(1, path.Count - 1); + var itemContainer = parentContainer.ItemContainerGenerator.ContainerFromItem(head) as TreeViewItem; + + if (itemContainer != null && itemContainer.Items.Count == 0) + { + itemContainer.IsSelected = true; + + var selectMethod = typeof(TreeViewItem).GetMethod("Select", BindingFlags.NonPublic | BindingFlags.Instance); + selectMethod.Invoke(itemContainer, new object[] { true }); + } + else if (itemContainer != null) + { + itemContainer.IsExpanded = true; + + if (itemContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated) + { + itemContainer.ItemContainerGenerator.StatusChanged += delegate + { + SelectItem(itemContainer, tail); + }; + } + else + { + SelectItem(itemContainer, tail); + } + } + } + + /// + /// Expand/Collapse all tree view items + /// + /// TreeView or TreeViewItem + /// True - expand, False - collapse + public static void SetExpandAll(this ItemsControl parentContainer, bool value) + { + foreach (Object item in parentContainer.Items) + { + var currentContainer = parentContainer.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem; + if (currentContainer != null && currentContainer.Items.Count > 0) + { + currentContainer.IsExpanded = value; + if (currentContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated) + { + currentContainer.ItemContainerGenerator.StatusChanged += delegate + { + SetExpandAll(currentContainer, value); + }; + } + else + { + SetExpandAll(currentContainer, value); + } + } + } + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Themes/Generic.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Themes/Generic.xaml new file mode 100644 index 0000000000..8e69621a35 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Themes/Generic.xaml @@ -0,0 +1,5 @@ + + + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Thumbs.db b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..9d0c65b4aaadc95e2dfd95dcd071aa86ace388b2 GIT binary patch literal 3584 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*3Bx2!nwD0|OI~0pkDr|NlQkkbwcn90fxt z1pWfu3W`4vW&uVbD>OcbkQYXsN;Sr0E8 zaOgB(^iN*-_#`7UP`&|_*nq$gLXl0fFfcKK><5)aAevZ%1fcdiGb93ioyd>_425)J zH6y7L0G5Ivdtm@c3MW$#C}W3HmUIc2-5{D&-Jm!Fg&inPVEG?Z=CcDa2M}`tF&7YX z12GQ}^8zs+5c2~uunGW|{h+dA6b#J}0L3XN4X^+s|No8u4;Tcz+&tYF7#SHE5`d85 z|7`|m24*HE5CQ@gAY$cUWo2Pu42X5EGFQ5)l;v8N$d6)WgEc$;!$p!pqGoLNfS&fI*N0SWYQ0Gb%AK2{JMZGX6ip zAP;mtE6}wd2SWiP6VQ!p>>Qk2+&~3efjN|snVE@&8RTl9>RO;Y1B)Q5kfNa@n{Z$v zyHcTuQRBpg9Li1`4~hm|{Gei-RMf=DB_=K*DW$5WuA!-AVrph?VQJ;;;_Bw^;pr6| z5*ijB5gC=7lA4yDk(pIoQd(ACQCZd8(%RPE(b+X=@|3C5rq7r;YtiB*OP4KQv2xX> z&0Dr^+rDGxu0w~996fgY#K}{aE?>EN?fQ+Iw;n!v{N(Ag=PzEq`uOSdm#^Qx|M>X} z>z(JGL-`{vmgtrq9L1*V<3BCp|FxsBZr97#DyCV zaw;1KeGpA5y2vG_V)9V+BgkuDpAqM=CbE16_ZY%ow-|Vs8G(_F!7G#c%#F_V0T2PP=>Byg(MSZyj=x zF---G3MDL`+@CqDH~rE3So%MMbVc@WdH)Z6du2Y|i}HN#H|>#1$d29{lQs)~5Bb8@ zpqSr!PkMWYR>rm+%<@Kg_A}QtKRni$`!KgM;qrvrQSs6KHrHM~IsVM;!>SFzhvs

na>aoh~O>yxuz zGl{LpJ;>txg%7&x?%bTj*SSLf_vPsNkEa+O*c5&|eE7bQ-OYz{c}>0ddV73Ko0w|( z@9Z46l=i@_(`wA_iJ69}&dyLs5wcvL_TkLzKj}d06JD?XE1e%RCF;y1f1M3Ks$Te; zu}o6F%~n%#^0Vdfoa?a+hubFIvshY^K4JG_F>8qi_G#=fbLO#G zGW@>@%S6P|0>GLAl=BjxSPw{pbK<$PK`VfDeKtcXutgCMBtfl + + + + + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs new file mode 100644 index 0000000000..2a8c63544a --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Window1.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows; + +namespace ICSharpCode.ShortcutsManagement +{ + ///

+ /// Interaction logic for Window1.xaml + /// + public partial class Window1 : Window + { + public Window1() + { + InitializeComponent(); + } + } +} diff --git a/src/AddIns/Misc/UnitTesting/UnitTesting.addin b/src/AddIns/Misc/UnitTesting/UnitTesting.addin index f3338c1780..95d351153d 100644 --- a/src/AddIns/Misc/UnitTesting/UnitTesting.addin +++ b/src/AddIns/Misc/UnitTesting/UnitTesting.addin @@ -21,7 +21,7 @@ category = "Tools" title = "${res:ICSharpCode.NUnitPad.NUnitPadContent.PadName}" icon = "PadIcons.NUnitTest" - shortcut = "Control|Alt|T" + shortcut = "Ctrl+Alt+T" class = "ICSharpCode.UnitTesting.UnitTestsPad" defaultPosition = "Right, Hidden" /> diff --git a/src/Main/Base/Project/Src/Commands/AutostartCommands.cs b/src/Main/Base/Project/Src/Commands/AutostartCommands.cs index 77f4410495..a833e9db06 100644 --- a/src/Main/Base/Project/Src/Commands/AutostartCommands.cs +++ b/src/Main/Base/Project/Src/Commands/AutostartCommands.cs @@ -125,14 +125,25 @@ namespace ICSharpCode.SharpDevelop.Commands //WorkbenchSingleton.MainForm.Focus(); // windows.forms focus workaround ParserService.StartParserThread(); - + + // Register gesture place holders + var placeHolderDescriptors = AddInTree.BuildItems("/SharpDevelop/Workbench/GesturePlaceHolder", this, false); + foreach(var desc in placeHolderDescriptors) { + BaseGesturesPlaceHolderRegistry.RegisterPlaceHolder(desc.Name, desc.Text); + + if(!string.IsNullOrEmpty(desc.Gestures)) { + BaseGesturesPlaceHolderRegistry.AddGestures(desc.Name, desc.Gestures.Split(new []{'|'})); + } + } + // finally run the workbench window ... //Application.AddMessageFilter(new FormKeyHandler()); //Application.Run(WorkbenchSingleton.MainForm); + App application = new App(); System.Windows.Forms.Integration.WindowsFormsHost.EnableWindowsFormsInterop(); application.Run(WorkbenchSingleton.MainWindow); - + // save the workbench memento in the ide properties try { PropertyService.Set(workbenchMemento, WorkbenchSingleton.Workbench.CreateMemento()); diff --git a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs index b0f7403433..251b151887 100644 --- a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs +++ b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading; using System.Windows; +using System.Windows.Input; using System.Windows.Controls; using ICSharpCode.Core; @@ -455,6 +456,8 @@ namespace ICSharpCode.SharpDevelop.Commands get; } + public List bindingsAssigned = new List(); + public ICollection BuildItems(Codon codon, object owner) { ArrayList list = new ArrayList(); @@ -465,15 +468,43 @@ namespace ICSharpCode.SharpDevelop.Commands if (!string.IsNullOrEmpty(padContent.Icon)) { item.Icon = PresentationResourceService.GetPixelSnappedImage(padContent.Icon); } - 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); + + var routedCommandName = "SDViewCommands.ShowView_" + padContent.Class; + var routedCommandText = "Show view " + MenuService.ConvertLabel(StringParser.Parse(padContent.Title)); + + // TODO: fix this hack + if(!bindingsAssigned.Contains(routedCommandName)) { + // Dynamicaly create routed UI command to loaded pad and bindings for it + CommandsRegistry.RegisterRoutedUICommand(routedCommandName, routedCommandText); + CommandsRegistry.LoadCommand(routedCommandName, new BringPadToFrontCommand(padContent)); + CommandsRegistry.RegisterCommandBinding(CommandsRegistry.DefaultContext, null, routedCommandName, routedCommandName, null, false); + + // If pad have shortcut specified add input binding + if (!string.IsNullOrEmpty(padContent.Shortcut)) { + var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(padContent.Shortcut); + foreach(InputGesture gesture in gestures) { + CommandsRegistry.RegisterInputBinding(CommandsRegistry.DefaultContext, null, routedCommandName, gesture); + } + } + + bindingsAssigned.Add(routedCommandName); } + CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContext, null); + CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContext, null); + + item.InputGestureText = padContent.Shortcut; + item.Command = CommandsRegistry.GetRoutedUICommand(routedCommandName); + +// 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); } } diff --git a/src/Main/Base/Project/Src/Commands/ToolsCommands.cs b/src/Main/Base/Project/Src/Commands/ToolsCommands.cs index d0524a2719..00d6c9b273 100644 --- a/src/Main/Base/Project/Src/Commands/ToolsCommands.cs +++ b/src/Main/Base/Project/Src/Commands/ToolsCommands.cs @@ -8,10 +8,33 @@ using System; using System.Windows.Forms; using ICSharpCode.Core; +using ICSharpCode.Core.Presentation; using ICSharpCode.SharpDevelop.Gui; +using System.Windows.Input; namespace ICSharpCode.SharpDevelop.Commands { + public class TestCommand : System.Windows.Input.ICommand + { + public event EventHandler CanExecuteChanged + { + add {} + remove {} + } + + public void Execute(object parameter) + { + CommandsRegistry.GetRoutedUICommand("SDBuildCommands.BuildSolution").Execute(parameter, WorkbenchSingleton.MainWindow); + + System.Windows.MessageBox.Show("test"); + } + + public bool CanExecute(object parameter) + { + return true; + } + } + public class OptionsCommand : AbstractMenuCommand { public static bool? ShowTabbedOptions(string dialogTitle, AddInTreeNode node) diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs index 28cbbf02b2..710745bef2 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs @@ -10,6 +10,7 @@ using System; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; +using System.Windows.Input; using AvalonDock; using ICSharpCode.Core; @@ -85,6 +86,15 @@ namespace ICSharpCode.SharpDevelop.Gui if (padInstance != null) { this.SetContent(padInstance.Control, padInstance); placeholder = null; + + var contextName = padInstance.GetType().FullName; + + CommandsRegistry.LoadContext(contextName, (UIElement)Content); + + CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, contextName, null)); + CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, contextName, null)); + CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null); + CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null); } } } diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs index 863791ce7e..3dd774d97f 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs @@ -91,6 +91,18 @@ namespace ICSharpCode.SharpDevelop.Gui } oldActiveViewContent = newActiveViewContent; CommandManager.InvalidateRequerySuggested(); + + if (newActiveViewContent != null) { + string contextName = newActiveViewContent.GetType().FullName; + + CommandsRegistry.LoadContext(contextName, (UIElement)Content); + + + CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, contextName, null)); + CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, contextName, null)); + CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null); + CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null); + } } sealed class ViewContentCollection : Collection diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs index 972218278c..a8e5c9a48f 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs @@ -80,6 +80,23 @@ namespace ICSharpCode.SharpDevelop.Gui } } + CommandsRegistry.DefaultContext = this.GetType().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"); + + // Register context and load all commands from addin + CommandsRegistry.LoadAddinCommands(AddInTree.AddIns.FirstOrDefault(a => a.Name == "SharpDevelop")); + + CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContext, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, CommandsRegistry.DefaultContext, null)); + CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContext, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, CommandsRegistry.DefaultContext, null)); + CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContext, null); + CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContext, null); + mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath); toolBars = ToolBarService.CreateToolBars(this, "/SharpDevelop/Workbench/ToolBar"); diff --git a/src/Main/Base/Project/Src/Internal/Doozers/PadDoozer.cs b/src/Main/Base/Project/Src/Internal/Doozers/PadDoozer.cs index 28bdb80af3..1b864a2509 100644 --- a/src/Main/Base/Project/Src/Internal/Doozers/PadDoozer.cs +++ b/src/Main/Base/Project/Src/Internal/Doozers/PadDoozer.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.SharpDevelop /// "View -> Debugger" menu. /// /// - /// Shortcut that activates the 'Show pad' command (e.g. "Control|Alt|T"). + /// Shortcut that activates the 'Show pad' command (e.g. "Ctrl+Alt+T"). /// /// Only in /Workspace/Parser /// diff --git a/src/Main/Core/Project/ICSharpCode.Core.csproj b/src/Main/Core/Project/ICSharpCode.Core.csproj index 8b2bac3fd0..4d108b5153 100644 --- a/src/Main/Core/Project/ICSharpCode.Core.csproj +++ b/src/Main/Core/Project/ICSharpCode.Core.csproj @@ -60,6 +60,14 @@ + + + + + + + + @@ -86,6 +94,7 @@ + @@ -122,7 +131,9 @@ + + Src\AddInTree\AddIn\AddIn.xsd diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs index adfd53e913..39a937617c 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs @@ -54,6 +54,13 @@ namespace ICSharpCode.Core } bool dependenciesLoaded; + + /// + /// Specifies whether all add-in dependencies and referenced assemblies are loaded + /// + public bool DependenciesLoaded { + get { return dependenciesLoaded; } + } void LoadDependencies() { @@ -236,6 +243,7 @@ namespace ICSharpCode.Core throw new AddInLoadException("Import node requires ONE attribute."); } string pathName = reader.GetAttribute(0); + ExtensionPath extensionPath = addIn.GetExtensionPath(pathName); if (!reader.IsEmptyElement) { ExtensionPath.SetUp(extensionPath, reader, "Path"); diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDescriptor.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDescriptor.cs new file mode 100644 index 0000000000..6f0043d1f4 --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDescriptor.cs @@ -0,0 +1,75 @@ +using System; + +namespace ICSharpCode.Core +{ + /// + /// Stores information about command binding loaded from add-in tree + /// + public class CommandBindingDescriptor + { + /// + /// Codon used to create this descriptor + /// + public Codon Codon { + get; private set; + } + + /// + /// Full name of the command class which will be executed when this + /// binding is triggered + /// + public string Class { + get; private set; + } + + /// + /// Full name of routed UI command which will trigger this binding + /// + public string Command { + get; private set; + } + + /// + /// Full name of context class. + /// + /// UI element in which this binding will be valid + /// + public string Context { + get; private set; + } + + /// + /// Gestures. + /// + /// Optional, if provided input bindings in the same context will be created + /// + public string Gestures { + get; private set; + } + + /// + /// Lazy loading + /// + /// If true add-in referenced assemblies are loaded when command is invoked. + /// Otherwise command can't be invoked until addin is loaded + /// + public bool Lazy { + get { + return Codon.Properties["lazy"] == "1" || Codon.Properties["lazy"] == "true"; + } + } + + /// + /// Constructor + /// + /// Reference to codon used to create this descriptor + public CommandBindingDescriptor(Codon codon) + { + Codon = codon; + Class = Codon.Properties["class"]; + Command = Codon.Properties["command"]; + Context = Codon.Properties["context"]; + Gestures = Codon.Properties["gestures"]; + } + } +} diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDoozer.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDoozer.cs new file mode 100644 index 0000000000..2c9e9bc7cf --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDoozer.cs @@ -0,0 +1,52 @@ +using System; + +namespace ICSharpCode.Core +{ + /// + /// Name of routed UI command which triggers this binding. + /// + /// Routed UI command details are specified in path '/SharpDevelop/Workbench/RoutedUICommands' + /// + /// + /// Class implementing System.Window.Input.ICommand or + /// ICSharpCode.Core class. CanExecute and Executed methods + /// are used to handle raised event + /// + /// + /// Specified binding owner + /// + /// If context is not specified binding is applied to default context + /// + /// + /// Use lazy loading. If addin containing binded command is + /// not loaded yet, load asseblies referenced in add-in and then + /// invoke command + /// + /// + /// Create input bindings in the same context which will trigger specified routed UI command + /// + /// Only in /SharpDevelop/Workbench/CommandBindings + /// + /// CommandBindingDescriptor object + /// + /// + /// Creates descriptor containing information about command binding + /// + public class CommandBindingDoozer : IDoozer + { + /// + public bool HandleConditions { + get { + return false; + } + } + + /// + /// Builds CommandBindingDescriptor + /// + public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems) + { + return new CommandBindingDescriptor(codon); + } + } +} diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/GesturesPlaceHolderDescriptor.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/GesturesPlaceHolderDescriptor.cs new file mode 100644 index 0000000000..51a8d498af --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/GesturesPlaceHolderDescriptor.cs @@ -0,0 +1,26 @@ +using System; + +namespace ICSharpCode.Core +{ + public class GesturesPlaceHolderDescriptor + { + public string Name { + get; private set; + } + + public string Text { + get; private set; + } + + public string Gestures { + get; private set; + } + + public GesturesPlaceHolderDescriptor(Codon codon) + { + Name = codon.Properties["name"]; + Text = codon.Properties["text"]; + Gestures = codon.Properties["gestures"]; + } + } +} diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/GesturesPlaceHolderDoozer.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/GesturesPlaceHolderDoozer.cs new file mode 100644 index 0000000000..1733f6d932 --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/GesturesPlaceHolderDoozer.cs @@ -0,0 +1,43 @@ +using System; + +namespace ICSharpCode.Core +{ + /// + /// Place holder name. This name should be unique application wide + /// + /// + /// Text displayed to use + /// + /// + /// Use lazy loading. If addin containing binded command is + /// not loaded yet, load asseblies referenced in add-in and then + /// invoke command + /// + /// + /// Keys which will invoke command + /// + /// Only in /SharpDevelop/Workbench/CommandBindings + /// + /// GesturesPlaceHolder object + /// + /// + /// Creates descriptor containing information about command binding + /// + public class GesturesPlaceHolderDoozer : IDoozer + { + /// + public bool HandleConditions { + get { + return false; + } + } + + /// + /// Builds GesturesPlaceHolderDoozer + /// + public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems) + { + return new GesturesPlaceHolderDescriptor(codon); + } + } +} diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDescriptor.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDescriptor.cs new file mode 100644 index 0000000000..e71a3e00e9 --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDescriptor.cs @@ -0,0 +1,44 @@ +using System; + +namespace ICSharpCode.Core +{ + /// + /// Stores information about input binding loaded from add-in tree + /// + public class InputBindingDescriptor + { + /// + /// Full name of routed UI command which will be invoked when this binding is triggered + /// + public string Command { + get; private set; + } + + /// + /// Full name of context class. + /// + /// UI element in which this binding will be valid + /// + public string Context { + get; private set; + } + + /// + /// Description of gesture which will trigger this bindin + /// + public string Gesture { + get; private set; + } + + /// + /// Constructor + /// + /// Reference to codon used to create this descriptor + public InputBindingDescriptor(Codon codon) + { + Command = codon.Properties["command"]; + Context = codon.Properties["context"]; + Gesture = codon.Properties["gesture"]; + } + } +} diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDoozer.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDoozer.cs new file mode 100644 index 0000000000..973eab3f17 --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDoozer.cs @@ -0,0 +1,35 @@ +using System; + +namespace ICSharpCode.Core +{ + /// + /// Name of routed UI command which is triggered by this binding + /// + /// + /// Gesture which triggers this binding + /// + /// Only in /SharpDevelop/Workbench/InputBindings + /// + /// InputBindingDescriptor object + /// + /// + /// Creates descriptor containing information about input binding + /// + public class InputBindingDoozer : IDoozer + { + /// + public bool HandleConditions { + get { + return true; + } + } + + /// + /// Builds InputBindingDescriptor + /// + public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems) + { + return new InputBindingDescriptor(codon); + } + } +} diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/RoutedUICommandDescriptor.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/RoutedUICommandDescriptor.cs new file mode 100644 index 0000000000..60a52e9c38 --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/RoutedUICommandDescriptor.cs @@ -0,0 +1,39 @@ +using System; + +namespace ICSharpCode.Core +{ + /// + /// Stores information about routed UI command loaded from add-in tree + /// + public class RoutedUICommandDescriptor + { + private Codon codon; + + /// + /// Text presented to user + /// + public string Text { + get { + return codon.Properties["text"]; + } + } + + /// + /// Routed command name + /// + public string Name { + get { + return codon.Properties["name"]; + } + } + + /// + /// Constructor + /// + /// Reference to codon used to create this descriptor + public RoutedUICommandDescriptor(Codon codon) + { + this.codon = codon; + } + } +} diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/RoutedUICommandDoozer.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/RoutedUICommandDoozer.cs new file mode 100644 index 0000000000..caa795e3f9 --- /dev/null +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/RoutedUICommandDoozer.cs @@ -0,0 +1,35 @@ +using System; + +namespace ICSharpCode.Core +{ + /// + /// Routed UI command name + /// + /// + /// Routed UI command displayed name + /// + /// Only in /SharpDevelop/Workbench/CommandBindings + /// + /// RoutedUICommandDescriptor object + /// + /// + /// Creates descriptor containing information about routed UI command + /// + public class RoutedUICommandDoozer : IDoozer + { + /// + public bool HandleConditions { + get { + return false; + } + } + + /// + /// Builds RoutedUICommandDescriptor + /// + public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems) + { + return new RoutedUICommandDescriptor(codon); + } + } +} diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuItemDoozer.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuItemDoozer.cs index 0516393e40..577db80770 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuItemDoozer.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuItemDoozer.cs @@ -43,7 +43,7 @@ namespace ICSharpCode.Core /// clicking the item. /// /// - /// Shortcut that activates the command (e.g. "Control|S"). + /// Shortcut that activates the command (e.g. "Ctrl+S"). /// /// /// If "type" is "Menu", the item can have sub-menuitems. diff --git a/src/Main/Core/Project/Src/AddInTree/AddInTree.cs b/src/Main/Core/Project/Src/AddInTree/AddInTree.cs index c31e94c323..e8ecd7b19d 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddInTree.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddInTree.cs @@ -33,6 +33,10 @@ namespace ICSharpCode.Core doozers.Add("MenuItem", new MenuItemDoozer()); doozers.Add("ToolbarItem", new ToolbarItemDoozer()); doozers.Add("Include", new IncludeDoozer()); + doozers.Add("InputBinding", new InputBindingDoozer()); + doozers.Add("CommandBinding", new CommandBindingDoozer()); + doozers.Add("RoutedUICommand", new RoutedUICommandDoozer()); + doozers.Add("GesturesPlaceHolder", new GesturesPlaceHolderDoozer()); conditionEvaluators.Add("Compare", new CompareConditionEvaluator()); conditionEvaluators.Add("Ownerstate", new OwnerStateConditionEvaluator()); diff --git a/src/Main/Core/Project/Src/Services/CommandsService/BaseGesturesPlaceHolderRegistry.cs b/src/Main/Core/Project/Src/Services/CommandsService/BaseGesturesPlaceHolderRegistry.cs new file mode 100644 index 0000000000..c59bf5b2fa --- /dev/null +++ b/src/Main/Core/Project/Src/Services/CommandsService/BaseGesturesPlaceHolderRegistry.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using ICSharpCode.Core; + +namespace ICSharpCode.Core +{ + public delegate void GesturesPlaceHolderUpdate(); + + /// + /// Stores gestures place holders + /// + /// Through this class one can register a handler which which would be + /// called when gestures associated with place holder name are updated + /// + public static class BaseGesturesPlaceHolderRegistry + { + private static Dictionary gesturePlaceHolders = new Dictionary(); + + private static Dictionary commandTexts = new Dictionary(); + private static Dictionary> registeredKeys = new Dictionary>(); + private static Dictionary> commandKeysUpdateHandlers = new Dictionary>(); + + /// + /// Register a place holder + /// + /// Place holder name. Unique application wide + /// Place holder text visible to user + public static void RegisterPlaceHolder(string placeHolderName, string placeHolderText) { + gesturePlaceHolders.Add(placeHolderName, new GesturesPlaceHolderInfo(placeHolderName, placeHolderText)); + } + + /// + /// Get gestures assigned to place holder + /// + /// Use KeysCollectionConverter or InputGestureCollectionConverter + /// to convert returned value representation to required format + /// + /// Place holder name + /// Array of gestures + public static string[] GetGestures(string placeHolderName) { + if(!gesturePlaceHolders.ContainsKey(placeHolderName) || gesturePlaceHolders[placeHolderName].Gestures.Count == 0) { + return new string[] { }; + } + + return gesturePlaceHolders[placeHolderName].Gestures.ToArray(); + } + + /// + /// Add gestures to place holder + /// + /// Use KeysCollectionConverter or InputGestureCollectionConverter + /// to convert gestures to string representation + /// + /// Place holder name + /// Added gestures + public static void AddGestures(string placeHolderName, IEnumerable gestures) { + if(!gesturePlaceHolders.ContainsKey(placeHolderName)) { + throw new ApplicationException("No gestures place holder with name '" + placeHolderName + "' is registered"); + } + + foreach(string gesture in gestures) { + if(!gesturePlaceHolders[placeHolderName].Gestures.Contains(gesture)) { + gesturePlaceHolders[placeHolderName].Gestures.Add(gesture); + } + } + } + + /// + /// Remove gestures from place holder + /// + /// Use KeysCollectionConverter or InputGestureCollectionConverter + /// to convert gestures to string representation + /// + /// Null argumens are igonred and all gestures which specify + /// provided parameters are removed + /// + /// + /// + public static void RemoveGestures(string placeHolderName, IEnumerable gestures) { + if(gesturePlaceHolders.ContainsKey(placeHolderName)) { + if(gestures == null) { + gesturePlaceHolders[placeHolderName].Gestures.Clear(); + } else { + for(int i = gesturePlaceHolders[placeHolderName].Gestures.Count - 1; i >= 0; i--) { + foreach(string gesture in gestures) { + if(gesturePlaceHolders[placeHolderName].Gestures[i] == gesture) { + gesturePlaceHolders[placeHolderName].Gestures.RemoveAt(i); + } + } + } + } + } + } + + /// + /// Register update handler which will trigger when gestures in + /// place holder are updated + /// + /// Place holder name + /// Handler which handles place holder gestures update + public static void RegisterUpdateHandler(string placeHolderName, GesturesPlaceHolderUpdate handler) { + if(!commandKeysUpdateHandlers.ContainsKey(placeHolderName)) { + commandKeysUpdateHandlers.Add(placeHolderName, new List()); + } + + commandKeysUpdateHandlers[placeHolderName].Add(new WeakReference(handler)); + } + + /// + /// Invoke delegates which handle gestures update in place holder + /// + /// If place holder is not provided all registered handlers are invoked + /// + /// + public static void InvokeUpdateHandlers(string placeHolderName) { + if(placeHolderName == null) { + foreach(var handlers in commandKeysUpdateHandlers) { + foreach(var handler in handlers.Value) { + if(handler != null && handler.Target != null) { + ((GesturesPlaceHolderUpdate)handler.Target).Invoke(); + } + } + } + } else { + if(commandKeysUpdateHandlers.ContainsKey(placeHolderName)) { + foreach(var handler in commandKeysUpdateHandlers[placeHolderName]) { + if(handler != null && handler.Target != null) { + ((GesturesPlaceHolderUpdate)handler.Target).Invoke(); + } + } + } + } + } + + /// + /// Intername representation of place holders + /// + class GesturesPlaceHolderInfo + { + /// + /// Place hollder name + /// + public string Name { + get; private set; + } + + /// + /// Place holder text visible to user + /// + public string Text { + get; private set; + } + + /// + /// Collection of gestures assigned to this place holder + /// + public List Gestures { + get; private set; + } + + /// + /// Constructor + /// + /// Place holder name + /// Place holder text visible to user + public GesturesPlaceHolderInfo(string name, string text) { + Name = name; + Text = text; + Gestures = new List(); + } + + } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs new file mode 100644 index 0000000000..bfca7ba074 --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs @@ -0,0 +1,185 @@ +using System; +using System.Windows; +using System.Windows.Input; + +namespace ICSharpCode.Core.Presentation +{ + /// + /// Stores details about command binding + /// + public class CommandBindingInfo + { + private UIElement contextInstance; + + /// + /// Constructor + /// + /// Context full name + /// Name of routed UI command which triggers this binding + /// Command full name + /// Add-in where command is registered + /// Lazy load command + public CommandBindingInfo(string contextName, string routedCommandName, string className, AddIn addIn, bool isLazy) { + RoutedCommandName = routedCommandName; + ContextName = contextName; + ClassName = className; + IsLazy = isLazy; + AddIn = addIn; + } + + public CommandBindingInfo(string contextName, UIElement contextInstance, string routedCommandName, string className, AddIn addIn, bool isLazy) { + RoutedCommandName = routedCommandName; + ContextName = contextName; + ClassName = className; + IsLazy = isLazy; + AddIn = addIn; + this.contextInstance = contextInstance; + } + + public CommandBindingInfo(string contextName, string routedCommandName, ExecutedRoutedEventHandler executedHandler, CanExecuteRoutedEventHandler canExecuteHandler) { + RoutedCommandName = routedCommandName; + ContextName = contextName; + this.executedEventHandler = executedHandler; + this.canExecutedEventHandler = canExecuteHandler; + } + + public CommandBindingInfo(string contextName, UIElement contextInstance, string routedCommandName, ExecutedRoutedEventHandler executedHandler, CanExecuteRoutedEventHandler canExecuteHandler) { + RoutedCommandName = routedCommandName; + ContextName = contextName; + this.executedEventHandler = executedHandler; + this.canExecutedEventHandler = canExecuteHandler; + this.contextInstance = contextInstance; + } + + /// + /// Routed command name + /// + /// Described binding is triggered by this routed command + /// + /// + public string RoutedCommandName { + get; private set; + } + + /// + /// Routed command instance + /// + /// Described binding is triggered by this routed command + /// + /// + public RoutedUICommand RoutedCommand { + get { + return CommandsRegistry.GetRoutedUICommand(RoutedCommandName); + } + } + + /// + /// Add-in to which binded command belongs + /// + public AddIn AddIn { + get; private set; + } + + /// + /// Binded command full name + /// + /// This command is invoke when this binding is triggered + /// + /// + public string ClassName { + get; private set; + } + + /// + /// Binded command instance + /// + /// This command is invoke when this binding is triggered. If this value is equal + /// to null then add-in is not loaded yet, see IsLazy attribute + /// for details + /// + /// + public System.Windows.Input.ICommand Class { + get { + if(AddIn != null && (AddIn.DependenciesLoaded || IsLazy)) { + CommandsRegistry.LoadAddinCommands(AddIn); + } + + System.Windows.Input.ICommand command; + CommandsRegistry.commands.TryGetValue(ClassName, out command); + + return command; + } + } + + /// + /// Context class full name + /// + /// Described binding will be valid in this context + /// + public string ContextName{ + get; private set; + } + + /// + /// Context class instance + /// + /// Described binding will be valid in this context + /// + public UIElement Context { + get { + if(contextInstance != null) { + return contextInstance; + } else { + UIElement context; + CommandsRegistry.contexts.TryGetValue(ContextName, out context); + + return context; + } + } + } + + /// + /// Lazy load + /// + /// If lazy load is enabled then all add-in references are loaded when this + /// command is invoked. Otherwice if add-in is not loaded and IsLazy is set + /// to false then this binding can't be triggered until add-in is loaded. + /// + public bool IsLazy{ + get; private set; + } + + private ExecutedRoutedEventHandler executedEventHandler; + public void ExecutedEventHandler(object sender, ExecutedRoutedEventArgs e) { + if(executedEventHandler != null) { + executedEventHandler.Invoke(sender, e); + } else { + if(IsLazy && Class == null) { + AddIn.LoadRuntimeAssemblies(); + + var command = (ICommand)AddIn.CreateObject(ClassName); + CommandsRegistry.LoadCommand(ClassName, command); + } + + if(Class != null) { + Class.Execute(e.Parameter); + } + } + } + + private CanExecuteRoutedEventHandler canExecutedEventHandler; + public void CanExecuteEventHandler(object sender, CanExecuteRoutedEventArgs e) { + if(canExecutedEventHandler != null) { + canExecutedEventHandler.Invoke(sender, e); + } else { + if(IsLazy && Class == null) { + e.CanExecute = true; + } else if(Class == null) { + e.CanExecute = false; + } else { + e.CanExecute = Class.CanExecute(e.Parameter); + } + } + } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs new file mode 100644 index 0000000000..cefd146e7e --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs @@ -0,0 +1,568 @@ +using System; +using System.Collections.Generic; +using System.Windows.Input; +using System.Windows; +using ICSharpCode.Core; +using System.Threading; + +namespace ICSharpCode.Core.Presentation +{ + public delegate void BindingsUpdatedHandler(); + + /// + /// Global registry to store and access commands, command bindings and input bindings + /// + public static class CommandsRegistry + { + /// + /// This element is used to represent null key in dictionary + /// + private static UIElement NullUIElement = new UIElement(); + + /// + /// Default application context. + /// + /// This should be set to the root UI element + /// + public static string DefaultContext { + get; set; + } + + private static List commandBindings = new List(); + private static List inputBidnings = new List(); + + private static Dictionary routedCommands = new Dictionary(); + internal static Dictionary commands = new Dictionary(); + internal static Dictionary contexts = new Dictionary(); + + private static Dictionary>> commandBindingsUpdateHandlers = new Dictionary>>(); + private static Dictionary>> inputBindingsUpdateHandlers = new Dictionary>>(); + + /// + /// Get reference to routed UI command by name + /// + /// Routed command name + /// Routed command instance + public static RoutedUICommand GetRoutedUICommand(string routedCommandName) { + if(routedCommands.ContainsKey(routedCommandName)) { + return routedCommands[routedCommandName]; + } + + return null; + } + + /// + /// Checks whether routed UI command registered + /// + /// Routed command name + /// Returns value specifting whether routed UI command is registered + public static bool IsRoutedUICommandRegistered(string routedCommandName) { + return GetRoutedUICommand(routedCommandName) != null; + } + + /// + /// Register new routed command in the global registry + /// + /// Routed command name should be unique in SharpDevelop scope. + /// Use "." to organize commands into groups + /// + /// Routed command name + /// Short text describing command functionality + public static void RegisterRoutedUICommand(string routedCommandName, string text) { + var routedCommand = new RoutedUICommand(text, routedCommandName, typeof(CommandsRegistry)); + + if(!routedCommands.ContainsKey(routedCommandName)) { + routedCommands.Add(routedCommandName, routedCommand); + } else { + var test = routedCommands[routedCommandName]; + throw new IndexOutOfRangeException("Routed UI command with name " + routedCommandName + " is already registered"); + } + } + + /// + /// Register existing routed command in the global registry + /// + /// Routed command then can be accessed + /// Routed command name should be uniq in SharpDevelop scope. + /// Use "." to organize commands into groups + /// + /// Existing routed command + public static void RegisterRoutedUICommand(RoutedUICommand existingRoutedUICommand) { + string routedCommandName = existingRoutedUICommand.OwnerType.Name + "." + existingRoutedUICommand.Name; + + if(!routedCommands.ContainsKey(routedCommandName)) { + routedCommands.Add(existingRoutedUICommand.OwnerType.Name + "." + existingRoutedUICommand.Name, existingRoutedUICommand); + } else { + throw new IndexOutOfRangeException("Routed UI command with name " + routedCommandName + " is already registered"); + } + } + + /// + /// Remove routed command from global registry + /// + /// Routed command name + public static void UnregisterRoutedUICommand(string routedCommandName) { + if(routedCommands.ContainsKey(routedCommandName)) { + routedCommands.Remove(routedCommandName); + } + } + + /// + /// Register input binding in context + /// + /// Registering input binding means that when specified gesture is met in specified + /// context routed command is invoked + /// + /// Context class full name + /// Context class instance. If instance is provided this input binding only applies to provided UI element + /// Routed UI command invoked on gesture run + /// Gesture + public static void RegisterInputBinding(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) { + var inputBindingInfo = new InputBindingInfo(contextName, contextInstance, routedCommandName, gesture); + inputBidnings.Add(inputBindingInfo); + } + + /// + /// Remove input bindings which satisfy provided arguments + /// + /// Null arguments are ignored + /// + /// Context class full name + /// Unregister binding assigned to specific context instance + /// Routed UI command name + /// Gesture + public static void UnregisterInputBindings(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) { + for(int i = inputBidnings.Count - 1; i >= 0; i--) { + if((contextName == null || inputBidnings[i].ContextName == contextName) + && (contextInstance == null || inputBidnings[i].Context == null || inputBidnings[i].Context == contextInstance) + && (routedCommandName == null || inputBidnings[i].RoutedCommandName == routedCommandName) + && (gesture == null || inputBidnings[i].Gesture == gesture)) { + inputBidnings.RemoveAt(i); + } + } + } + + /// + /// Register delegate which will be invoked on change in input bindings in specified context + /// + /// Context class full name + /// Register update handler which will trigger only if input bindings registered for this object where triggered + /// Update handler delegate + public static void RegisterInputBindingUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) { + if(contextInstance == null) { + contextInstance = NullUIElement; + } + + if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) { + inputBindingsUpdateHandlers.Add(contextName, new Dictionary>()); + } + + if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { + inputBindingsUpdateHandlers[contextName].Add(contextInstance, new List()); + } + + inputBindingsUpdateHandlers[contextName][contextInstance].Add(handler); + } + + /// + /// Remove input bindings update handler + /// + /// Context class full name + /// Unregister update handler which was triggered only if input bindings registered for specific instance where updated + /// Update handler delegate + public static void UnregisterInputBindingUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) { + if(contextInstance == null) { + contextInstance = NullUIElement; + } + if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) { + if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { + for(int i = inputBindingsUpdateHandlers[contextName][contextInstance].Count - 1; i >= 0; i++) { + if(inputBindingsUpdateHandlers[contextName][contextInstance][i] == handler) { + inputBindingsUpdateHandlers[contextName][contextInstance].RemoveAt(i); + } + } + } + } + } + + + /// + /// Invoke registered input bindings update handlers registered in specified context + /// + /// Context class full name + public static void InvokeInputBindingUpdateHandlers(string contextName, UIElement contextInstance) { + if(contextInstance == null) { + contextInstance = NullUIElement; + } + + if(contextName != null) { + if(inputBindingsUpdateHandlers.ContainsKey(contextName)) { + if(contextInstance == NullUIElement) { + foreach(var instanceHandlers in inputBindingsUpdateHandlers[contextName]) { + foreach(var handler in instanceHandlers.Value) { + if(handler != null) { + ((BindingsUpdatedHandler)handler).Invoke(); + } + } + } + } + } else if(inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { + foreach(var handler in inputBindingsUpdateHandlers[contextName][contextInstance]) { + if(handler != null) { + ((BindingsUpdatedHandler)handler).Invoke(); + } + } + } + } else { + foreach(var contextHandlers in inputBindingsUpdateHandlers) { + foreach(var instanceHandlers in contextHandlers.Value) { + foreach(var handler in instanceHandlers.Value) { + if(handler != null) { + ((BindingsUpdatedHandler)handler).Invoke(); + } + } + } + } + } + } + + /// + /// Remove all managed input bindings from input bindings collection + /// + /// + public static void RemoveManagedInputBindings(InputBindingCollection inputBindingCollection) { + for(int i = inputBindingCollection.Count - 1; i >= 0; i--) { + if(inputBindingCollection[i] is ManagedInputBinding) { + inputBindingCollection.RemoveAt(i); + } + } + } + + /// + /// Register command binding + /// + /// Registering command binding means that when provided routed command is invoked + /// in specified context event is routed to specified command (implementing ICommand class) + /// + /// Context class full name + /// Register update handler which is triggered only if input bindings registered for specific instance are updated + /// Routed UI command name + /// Command full name to which invokation event is routed + /// Add-in in which hosts the command + /// Load add-in referenced assemblies on command invocation + public static void RegisterCommandBinding(string contextName, UIElement contextInstance, string routedCommandName, string className, AddIn addIn, bool isLazy) { + var commandBindingInfo = new CommandBindingInfo(contextName, contextInstance, routedCommandName, className, addIn, isLazy); + commandBindings.Add(commandBindingInfo); + } + + /// + /// Register command binding which when triggered provided delegates are invoked + /// + /// Context class full name + /// Register update handler which is triggered only if input bindings registered for specific instance are updated + /// Routed UI command name + /// Delegate which is called when binding is triggered + /// Delegate which is called to check whether executedEventHandler can be invoked + public static void RegisterCommandBinding(string contextName, UIElement contextInstance, string routedCommandName, ExecutedRoutedEventHandler executedEventHandler, CanExecuteRoutedEventHandler canExecuteEventHandler) { + var commandBindingInfo = new CommandBindingInfo(contextName, contextInstance, routedCommandName, executedEventHandler, canExecuteEventHandler); + commandBindings.Add(commandBindingInfo); + } + + /// + /// Remove all command bindings which satisfy provided parameters + /// + /// Null arguments are ignored + /// + /// Context class full name + /// Unregister update handler which was triggered only if command bindings registered for specific instance where updated + /// Routed UI command name + /// Command full name to which invokation event is routed + public static void UnregisterCommandBindings(string contextName, UIElement contextInstance, string routedCommandName, string className) { + for(int i = commandBindings.Count - 1; i >= 0; i--) { + if((contextName == null || commandBindings[i].ContextName == contextName) + && (contextInstance == null || commandBindings[i].Context == null || commandBindings[i].Context == contextInstance) + && (routedCommandName == null || commandBindings[i].RoutedCommandName == routedCommandName) + && (className == null || commandBindings[i].ClassName == className)) { + inputBidnings.RemoveAt(i); + } + } + } + + /// + /// Register delegate which will be invoked on any chage in command bindings of specified context + /// + /// Context class full name + /// Register update handler which is triggered only if input bindings registered for specific instance are updated + /// Update handler delegate + public static void RegisterCommandBindingsUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) { + if(contextInstance == null) { + contextInstance = NullUIElement; + } + if(!commandBindingsUpdateHandlers.ContainsKey(contextName)) { + commandBindingsUpdateHandlers.Add(contextName, new Dictionary>()); + } + + if(!commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { + commandBindingsUpdateHandlers[contextName].Add(contextInstance, new List()); + } + + commandBindingsUpdateHandlers[contextName][contextInstance].Add(handler); + } + + /// + /// Remove handler command bindings update handler + /// + /// Context class full name + /// Unregister update handler which was triggered only if input bindings registered for specific instance were updated + /// Update handler delegate + public static void UnregisterCommandBindingsUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) { + if(contextInstance == null) { + contextInstance = NullUIElement; + } + if(commandBindingsUpdateHandlers.ContainsKey(contextName)) { + if(commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { + for(int i = commandBindingsUpdateHandlers[contextName][contextInstance].Count - 1; i >= 0; i--) { + if(commandBindingsUpdateHandlers[contextName][contextInstance][i] == handler) { + commandBindingsUpdateHandlers[contextName][contextInstance].RemoveAt(i); + } + } + } + } + } + + /// + /// Invoke registered command bindings update handlers registered in specified context + /// + /// Context class full name + /// Invoke update handlers which handle update only in specifyc context + public static void InvokeCommandBindingUpdateHandlers(string contextName, UIElement contextInstance) { + if(contextInstance == null) { + contextInstance = NullUIElement; + } + + if(contextName != null) { + if(commandBindingsUpdateHandlers.ContainsKey(contextName)) { + if(contextInstance == NullUIElement) { + foreach(var instanceHandlers in commandBindingsUpdateHandlers[contextName]) { + foreach(var handler in instanceHandlers.Value) { + if(handler != null) { + ((BindingsUpdatedHandler)handler).Invoke(); + } + } + } + } else if(commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { + foreach(var handler in commandBindingsUpdateHandlers[contextName][contextInstance]) { + if(handler != null) { + ((BindingsUpdatedHandler)handler).Invoke(); + } + } + } + } + } else { + foreach(var contextHandlers in commandBindingsUpdateHandlers) { + foreach(var instanceHandlers in contextHandlers.Value) { + foreach(var handler in instanceHandlers.Value) { + if(handler != null) { + ((BindingsUpdatedHandler)handler).Invoke(); + } + } + } + } + } + } + + /// + /// Remove all managed command bindungs from command bindings collection + /// + /// + public static void RemoveManagedCommandBindings(CommandBindingCollection commandBindingsCollection) { + for(int i = commandBindingsCollection.Count - 1; i >= 0; i--) { + if(commandBindingsCollection[i] is ManagedCommandBinding) { + commandBindingsCollection.RemoveAt(i); + } + } + } + + /// + /// Load all registered commands in addin + /// + /// Addin + public static void LoadAddinCommands(AddIn addIn) { + foreach(var binding in commandBindings) { + if(binding.AddIn != addIn) continue; + + if(!commands.ContainsKey(binding.ClassName)){ + var command = addIn.CreateObject(binding.ClassName); + var wpfCommand = command as System.Windows.Input.ICommand; + if(wpfCommand == null) { + wpfCommand = new WpfCommandWrapper((ICSharpCode.Core.ICommand)command); + } + + commands.Add(binding.ClassName, wpfCommand); + } + } + } + + /// + /// Load command + /// + /// Command name + /// Command instance + public static void LoadCommand(string commandName, object command) { + var wpfCommand = command as System.Windows.Input.ICommand; + if(wpfCommand == null) { + wpfCommand = new WpfCommandWrapper((ICSharpCode.Core.ICommand)command); + } + + if(!commands.ContainsKey(commandName)) { + commands.Add(commandName, wpfCommand); + } + } + + /// + /// Load context + /// + /// Context class full name + /// Context class instance + public static void LoadContext(string contextName, UIElement context) { + contexts[contextName] = context; + } + + + /// + /// Get list of all command bindings which satisfy provided parameters + /// + /// Null arguments are ignored + /// + /// Context class full name + /// Get command bindings assigned only to specific context + /// Context class full name + /// Context class full name + /// Collection of managed command bindings + public static CommandBindingCollection GetCommandBindings(string contextName, UIElement contextInstance, string routedCommandName, string className) { + var bindings = new CommandBindingCollection(); + + foreach(var binding in commandBindings) { + if((contextName == null || binding.ContextName == contextName) + && (contextInstance == null || binding.Context == null || binding.Context == contextInstance) + && (routedCommandName == null || binding.RoutedCommandName == routedCommandName) + && (className == null || binding.ClassName == className)) { + + var managedCommandBinding = new ManagedCommandBinding(binding.RoutedCommand); + managedCommandBinding.CanExecute += binding.CanExecuteEventHandler; + managedCommandBinding.Executed += binding.ExecutedEventHandler; + + bindings.Add(managedCommandBinding); + } + } + + return bindings; + } + + /// + /// Get list of all input bindings which satisfy provided parameters + /// + /// Null arguments are ignored + /// + /// Context class full name + /// Get input bindings assigned only to specific context + /// Routed UI command name + /// Gesture + public static InputBindingCollection GetInputBindings(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) { + var bindings = new InputBindingCollection(); + + foreach(var binding in inputBidnings) { + if((contextName == null || binding.ContextName == contextName) + && (contextInstance == null || binding.Context == null || binding.Context == contextInstance) + && (routedCommandName == null || binding.RoutedCommandName == routedCommandName) + && (gesture == null || binding.Gesture == gesture)) { + + bindings.Add(new ManagedInputBinding(binding.RoutedCommand, binding.Gesture)); + } + } + + return bindings; + } + + /// + /// Get list of input gestures from all input bindings which satisfy provided parameters + /// + /// Null arguments are ignored + /// + /// Context class full name + /// Get gestures assigned only to specific context + /// Routed UI command name + /// Gesture + public static InputGestureCollection GetInputGestures(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) { + var bindings = GetInputBindings(contextName, contextInstance, routedCommandName, gesture); + var gestures = new InputGestureCollection(); + + foreach(InputBinding binding in bindings) { + gestures.Add(binding.Gesture); + } + + return gestures; + } + + /// + /// Create default BindingUpdateHandler which will update command bindings in specified context + /// + /// Collection which should be updated with latest bindings + /// Context name which was used to register command bindings + /// Reference to instance which is used to find command bindings registered in specific context instance + /// Bindings updated handler + public static BindingsUpdatedHandler CreateCommandBindingUpdateHandler(CommandBindingCollection bindingsCollection, string contextName, UIElement contextInstance) { + return new CommonCommandBindingUpdateDelegate(bindingsCollection, contextName, contextInstance).UpdateCommandBinding; + } + + /// + /// Create default BindingUpdateHandler which will update input bindings in specified context + /// + /// Collection which should be updated with latest bindings + /// Context name which was used to register input bindings + /// Reference to instance which is used to find command bindings registered in specific context instance + /// Bindings updated handler + public static BindingsUpdatedHandler CreateInputBindingUpdateHandler(InputBindingCollection bindingsCollection, string contextName, UIElement contextInstance) { + return new CommonInputBindingUpdateDelegate(bindingsCollection, contextName, contextInstance).UpdateInputBinding; + } + + class CommonCommandBindingUpdateDelegate + { + CommandBindingCollection bindingsCollection; + string contextName; + UIElement contextInstance; + + public CommonCommandBindingUpdateDelegate(CommandBindingCollection bindingsCollection, string contextName, UIElement contextInstance) { + this.bindingsCollection = bindingsCollection; + this.contextName = contextName; + this.contextInstance = contextInstance; + } + + public void UpdateCommandBinding() { + var newBindings = CommandsRegistry.GetCommandBindings(contextName, contextInstance, null, null); + CommandsRegistry.RemoveManagedCommandBindings(bindingsCollection); + bindingsCollection.AddRange(newBindings); + } + } + + + class CommonInputBindingUpdateDelegate + { + InputBindingCollection bindingsCollection; + string contextName; + UIElement contextInstance; + + public CommonInputBindingUpdateDelegate(InputBindingCollection bindingsCollection, string contextName, UIElement contextInstance) { + this.bindingsCollection = bindingsCollection; + this.contextName = contextName; + this.contextInstance = contextInstance; + } + + public void UpdateInputBinding() { + var newBindings = CommandsRegistry.GetInputBindings(contextName, contextInstance, null, null); + CommandsRegistry.RemoveManagedInputBindings(bindingsCollection); + bindingsCollection.AddRange(newBindings); + } + } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs new file mode 100644 index 0000000000..26821428a7 --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs @@ -0,0 +1,72 @@ +using System; +using System.Reflection; +using System.Windows.Input; +using System.Windows.Documents; +using ICSharpCode.Core; + +namespace ICSharpCode.Core.Presentation +{ + /// + /// Description of CommandsService. + /// + public static class CommandsService + { + public static void RegisterRoutedCommands(Type type) { + var typeProperties = type.GetProperties(BindingFlags.Static | BindingFlags.Public); + foreach(var property in typeProperties) { + var command = (RoutedUICommand)property.GetValue(null, null); + CommandsRegistry.RegisterRoutedUICommand(command); + } + } + + public static void RegisterBuiltInRoutedUICommands() { + RegisterRoutedCommands(typeof(ApplicationCommands)); + RegisterRoutedCommands(typeof(ComponentCommands)); + RegisterRoutedCommands(typeof(MediaCommands)); + RegisterRoutedCommands(typeof(NavigationCommands)); + RegisterRoutedCommands(typeof(EditingCommands)); + } + + public static void RegisterRoutedUICommands(object caller, string path) + { + var descriptors = AddInTree.BuildItems(path, caller, false); + foreach(var desc in descriptors) { + CommandsRegistry.RegisterRoutedUICommand(desc.Name, desc.Text); + } + } + + public static void RegisterCommandBindings(object caller, string path) + { + var descriptors = AddInTree.BuildItems(path, caller, false); + foreach(var desc in descriptors) { + var contextName = !string.IsNullOrEmpty(desc.Context) ? desc.Context : CommandsRegistry.DefaultContext; + + // If routed with such name is not registered register routed command with text same as name + if(CommandsRegistry.GetRoutedUICommand(desc.Command) == null) { + CommandsRegistry.RegisterRoutedUICommand(desc.Command, desc.Command); + } + + CommandsRegistry.RegisterCommandBinding(contextName, null, desc.Command, desc.Class, desc.Codon.AddIn, desc.Lazy); + + // If gestures are provided register input binding in the same context + if(!string.IsNullOrEmpty(desc.Gestures)) { + var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures); + foreach(InputGesture gesture in gestures) { + CommandsRegistry.RegisterInputBinding(contextName, null, desc.Command, gesture); + } + } + } + } + + public static void RegisterInputBindings(object caller, string path) + { + var descriptors = AddInTree.BuildItems(path, caller, false); + foreach(var desc in descriptors) { + var contextName = !string.IsNullOrEmpty(desc.Context) ? desc.Context : CommandsRegistry.DefaultContext; + + var gesture = (KeyGesture)new KeyGestureConverter().ConvertFromInvariantString(desc.Gesture); + CommandsRegistry.RegisterInputBinding(contextName, null, desc.Command, gesture); + } + } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/GesturePlaceHolderRegistry.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/GesturePlaceHolderRegistry.cs new file mode 100644 index 0000000000..00d81a46a4 --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/GesturePlaceHolderRegistry.cs @@ -0,0 +1,82 @@ +using System; +using System.Windows.Input; +using System.Collections.Generic; +using ICSharpCode.Core; + +namespace ICSharpCode.Core.Presentation +{ + /// + /// Stores gestures place holders + /// + /// Through this class one can register a handler which which would be + /// called when gestures associated with place holder name are updated + /// + public static class GesturePlaceHolderRegistry + { + /// + /// Register a place holder + /// + /// Place holder name. Unique application wide + /// Place holder text visible to user + public static void RegisterPlaceHolder(string placeHolderName, string placeHolderText) { + BaseGesturesPlaceHolderRegistry.RegisterPlaceHolder(placeHolderName, placeHolderText); + } + + /// + /// Get gestures assigned to place holder + /// + /// Place holder name + /// Collection of gestures + public static InputGestureCollection GetGestures(string placeHolderName) { + var serializesGesturesColection = BaseGesturesPlaceHolderRegistry.GetGestures(placeHolderName); + var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFrom(serializesGesturesColection); + + return gestures; + } + + /// + /// Add gestures to place holder + /// + /// Place holder name + /// Added gestures + public static void AddGestures(string placeHolderName, InputGestureCollection gestures) { + var serializedGestures = (string[])new InputGestureCollectionConverter().ConvertTo(gestures, typeof(string[])); + + BaseGesturesPlaceHolderRegistry.AddGestures(placeHolderName, serializedGestures); + } + + /// + /// Remove gestures from place holder + /// + /// Null argumens are igonred and all gestures which specify + /// provided parameters are removed + /// + /// Place holder name + /// Removed gestures + public static void RemoveGestures(string placeHolderName, InputGestureCollection gestures) { + var serializedGestures = (string[])new InputGestureCollectionConverter().ConvertTo(gestures, typeof(string[])); + + BaseGesturesPlaceHolderRegistry.RemoveGestures(placeHolderName, serializedGestures); + } + + /// + /// Register update handler which will trigger when gestures in + /// place holder are updated + /// + /// Place holder name + /// Handler which handles place holder gestures update + public static void RegisterUpdateHandler(string placeHolderName, GesturesPlaceHolderUpdate handler) { + BaseGesturesPlaceHolderRegistry.RegisterUpdateHandler(placeHolderName, handler); + } + + /// + /// Invoke delegates which handle gestures update in place holder + /// + /// If place holder is not provided all registered handlers are invoked + /// + /// + public static void InvokeUpdateHandler(string placeHolderName) { + BaseGesturesPlaceHolderRegistry.InvokeUpdateHandlers(placeHolderName); + } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs new file mode 100644 index 0000000000..229aaaaf1d --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs @@ -0,0 +1,90 @@ +using System; +using System.Windows; +using System.Windows.Input; + +namespace ICSharpCode.Core.Presentation +{ + /// + /// Stores details about input binding + /// + public class InputBindingInfo + { + private UIElement contextInstance; + + /// + /// Constructor + /// + /// Context full name + /// Name of routed UI command which is triggered by this binding + /// Gesture which triggers this binding + public InputBindingInfo(string contextName, string routedCommandName, InputGesture gesture) { + ContextName = contextName; + RoutedCommandName = routedCommandName; + Gesture = gesture; + } + + public InputBindingInfo(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) { + ContextName = contextName; + RoutedCommandName = routedCommandName; + Gesture = gesture; + this.contextInstance = contextInstance; + } + + + /// + /// Context class full name + /// + /// Described binding will be valid in this context + /// + public string ContextName { + get; set; + } + + /// + /// Context class instance + /// + /// Described binding will be valid in this context + /// + public UIElement Context { + get { + if(contextInstance != null) { + return contextInstance; + } else { + UIElement context; + CommandsRegistry.contexts.TryGetValue(ContextName, out context); + + return context; + } + } + } + + /// + /// Routed command name + /// + /// Described binding triggers this routed command + /// + /// + public string RoutedCommandName { + get; set; + } + + /// + /// Routed command instance + /// + /// Described binding triggers this routed command + /// + /// + public RoutedUICommand RoutedCommand { + get { + return CommandsRegistry.GetRoutedUICommand(RoutedCommandName); + } + } + + /// + /// Gesture which triggers this binding + /// + public InputGesture Gesture { + get; set; + } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputGestureCollectionConverter.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputGestureCollectionConverter.cs new file mode 100644 index 0000000000..de9ea52b41 --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputGestureCollectionConverter.cs @@ -0,0 +1,103 @@ +using System; +using System.Windows.Input; +using System.ComponentModel; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using System.Globalization; + +namespace ICSharpCode.Core.Presentation +{ + /// + /// Converts input gesture from text representation to object and vice versa + /// + /// Will be able to convert mouse and key gestures and handle gestures collections + /// + public class InputGestureCollectionConverter : TypeConverter + { + /// + /// Returns a value indicating whether this converter can convert an object in the + /// specified source type to the native type of the converter. + /// + /// Type descriptor context + /// Source type + /// Array of keys + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { + if (sourceType == typeof(string)) { + return true; + } + + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Returns a value indicating whether this converter can convert a + /// specified object to the specified destination type. + /// + /// An ITypeDescriptorContext that provides a format context, which can be used to extract additional information about the environment this converter is being invoked from. This parameter or properties of this parameter can be a null reference + /// Convertion destination type + /// Destination object + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { + if (destinationType == typeof(string)) { + return true; + } + + return base.CanConvertTo(context, destinationType); + } + + /// + /// Convert from object to input gesture collection + /// + /// An ITypeDescriptorContext that provides a format context, which can be used to extract additional information about the environment this converter is being invoked from. This parameter or properties of this parameter can be a null reference + /// Locale information which can influence convertion + /// Input gesture collection + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { + if (value is string) { + var gestures = new InputGestureCollection(); + var serializedGestures = Regex.Split((string)value, @"\s*\|\s*"); + + foreach(var serializedGesture in serializedGestures) { + if(string.IsNullOrEmpty(serializedGesture)) continue; + + gestures.Add((InputGesture)new KeyGestureConverter().ConvertFromString(context, culture, serializedGesture)); + } + + return gestures; + } + + return base.ConvertFrom(context, culture, value); + } + + /// + /// Converts the input gesture collection to the specified destination type + /// + /// An ITypeDescriptorContext that provides a format context, which can be used to extract additional information about the environment this converter is being invoked from. This parameter or properties of this parameter can be a null reference + /// Locale information which can influence convertion + /// Input gesture collection + /// Convertion destination type + /// + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { + if(destinationType == typeof(string)) { + var sb = new StringBuilder(); + var gesturesCollection = (InputGestureCollection)value; + foreach(var gesture in gesturesCollection) { + string serializedGesture; + if (gesture is KeyGesture) { + serializedGesture = (string)new KeyGestureConverter().ConvertTo(context, culture, gesture, typeof(string)); + } else if (gesture is MouseGesture) { + serializedGesture = (string)new KeyGestureConverter().ConvertTo(context, culture, gesture, typeof(string)); + } else { + continue; + } + + sb.AppendFormat("{0} | ", serializedGesture); + } + + return sb.Length >= 3 ? sb.ToString(0, sb.Length - 3) : sb.ToString(); + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } +} \ No newline at end of file diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/ManagedCommandBinding.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/ManagedCommandBinding.cs new file mode 100644 index 0000000000..cf9ea7e9d5 --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/ManagedCommandBinding.cs @@ -0,0 +1,35 @@ +using System; +using System.Windows.Input; + +namespace ICSharpCode.Core.Presentation +{ + /// + /// ManagedCommandBinding is used to distinguish command bindings managed + /// by CommandsRegistry from other command bindings not managed by CommandsRegistry + /// + /// If command binding is not managed then CommandsRegistry ignores it when + /// performing any action + /// + public class ManagedCommandBinding : System.Windows.Input.CommandBinding + { + /// + public ManagedCommandBinding() + : base() + { } + + /// + public ManagedCommandBinding(System.Windows.Input.ICommand command) + : base(command) + { } + + /// + public ManagedCommandBinding(System.Windows.Input.ICommand command, System.Windows.Input.ExecutedRoutedEventHandler executed) + : base(command, executed) + { } + + /// + public ManagedCommandBinding(System.Windows.Input.ICommand command, System.Windows.Input.ExecutedRoutedEventHandler executed, System.Windows.Input.CanExecuteRoutedEventHandler canExecute) + : base(command, executed, canExecute) + { } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/ManagedInputBinding.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/ManagedInputBinding.cs new file mode 100644 index 0000000000..792de1e83d --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/ManagedInputBinding.cs @@ -0,0 +1,24 @@ +using System; +using System.Windows.Input; + +namespace ICSharpCode.Core.Presentation +{ + /// + /// ManagedKeyBinding is used to distinguish input bindings managed + /// by CommandsRegistry from other input bindings not managed by CommandsRegistry. + /// + /// If input binding is not managed then CommansRegistry ignores it when + /// performing any action + /// + public class ManagedInputBinding : System.Windows.Input.InputBinding + { + /// + public ManagedInputBinding() : base() + { } + + /// + public ManagedInputBinding(System.Windows.Input.ICommand command, System.Windows.Input.InputGesture gesture) + : base(command, gesture) + { } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/WpfCommandWrapper.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/WpfCommandWrapper.cs new file mode 100644 index 0000000000..c44e0be41a --- /dev/null +++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/WpfCommandWrapper.cs @@ -0,0 +1,44 @@ +using System; +using System.Windows.Input; +using ICSharpCode.Core; + +namespace ICSharpCode.Core.Presentation +{ + /// + /// Wraps SharpDevelop's native command inside WPF command + /// + public class WpfCommandWrapper : System.Windows.Input.ICommand + { + ICommand command; + + /// + /// Constructor + /// + /// SharpDevelop native command + public WpfCommandWrapper(ICommand command) + { + this.command = command; + } + + /// + /// Not used because SharpDevelop's native command implementation + /// doesn't support it + /// + public event EventHandler CanExecuteChanged { + add { } + remove { } + } + + /// + public void Execute(object parameter) + { + command.Run(); + } + + /// + public bool CanExecute(object parameter) + { + return true; + } + } +} diff --git a/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj b/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj index 1e112abff5..594e5eca3d 100644 --- a/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj +++ b/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj @@ -67,6 +67,15 @@ Properties\GlobalAssemblyInfo.cs + + + + + + + + + @@ -95,6 +104,7 @@ False + diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs index c9514275b0..29f1138f5e 100644 --- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs +++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs @@ -118,13 +118,29 @@ namespace ICSharpCode.Core.Presentation { public MenuCommand(UIElement inputBindingOwner, Codon codon, object caller, bool createCommand) : base(codon, caller) { - this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); - if (!string.IsNullOrEmpty(codon.Properties["shortcut"])) { - KeyGesture kg = MenuService.ParseShortcut(codon.Properties["shortcut"]); - if (inputBindingOwner != null) { - inputBindingOwner.InputBindings.Add(new InputBinding(this.Command, kg)); + if(!string.IsNullOrEmpty(codon.Properties["command"])) { + var routedCommandName = codon.Properties["command"]; + var routedCommand = CommandsRegistry.GetRoutedUICommand(routedCommandName); + + if(routedCommand == null) { + MessageService.ShowError("Routed command with name '" + routedCommandName + "' not registered"); + } else { + this.Command = routedCommand; + + var gestures = CommandsRegistry.GetInputGestures(CommandsRegistry.DefaultContext, null, routedCommand.Name, null); + var gesturesString = (string)new InputGestureCollectionConverter().ConvertToInvariantString(gestures); + this.InputGestureText = gesturesString; + } + } else { + this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); + if (!string.IsNullOrEmpty(codon.Properties["shortcut"])) { + KeyGesture kg = MenuService.ParseShortcut(codon.Properties["shortcut"]); + if (inputBindingOwner != null) { + inputBindingOwner.InputBindings.Add(new InputBinding(this.Command, kg)); + } + + this.InputGestureText = kg.GetDisplayStringForCulture(Thread.CurrentThread.CurrentUICulture); } - this.InputGestureText = kg.GetDisplayStringForCulture(Thread.CurrentThread.CurrentUICulture); } } } diff --git a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs index b320ee44a9..0b65dc7948 100644 --- a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs +++ b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs @@ -26,7 +26,12 @@ namespace ICSharpCode.Core.Presentation this.codon = codon; this.caller = caller; - this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); + + if(!string.IsNullOrEmpty(codon.Properties["command"])) { + this.Command = CommandsRegistry.GetRoutedUICommand(codon.Properties["command"]); + } else { + this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); + } if (codon.Properties.Contains("icon")) { var image = PresentationResourceService.GetImage(StringParser.Parse(codon.Properties["icon"])); diff --git a/src/Main/ICSharpCode.Core.WinForms/CommandsService/GesturePlaceHolderRegistry.cs b/src/Main/ICSharpCode.Core.WinForms/CommandsService/GesturePlaceHolderRegistry.cs new file mode 100644 index 0000000000..2cae2a1a57 --- /dev/null +++ b/src/Main/ICSharpCode.Core.WinForms/CommandsService/GesturePlaceHolderRegistry.cs @@ -0,0 +1,82 @@ +using System; +using System.Windows.Forms; +using System.Collections.Generic; +using ICSharpCode.Core; + +namespace ICSharpCode.Core.WinForms +{ + /// + /// Stores gestures place holders + /// + /// Through this class one can register a handler which which would be + /// called when gestures associated with place holder name are updated + /// + public static class GesturePlaceHolderRegistry + { + /// + /// Register a place holder + /// + /// Place holder name. Unique application wide + /// Place holder text visible to user + public static void RegisterPlaceHolder(string placeHolderName, string placeHolderText) { + BaseGesturesPlaceHolderRegistry.RegisterPlaceHolder(placeHolderName, placeHolderText); + } + + /// + /// Get gestures assigned to place holder + /// + /// Place holder name + /// Array of keys + public static Keys[] GetGestures(string placeHolderName) { + var serializesGesturesColection = BaseGesturesPlaceHolderRegistry.GetGestures(placeHolderName); + var gestures = (Keys[])new KeysCollectionConverter().ConvertFrom(serializesGesturesColection); + + return gestures; + } + + /// + /// Add gestures to place holder + /// + /// Place holder name + /// Added gestures + public static void AddGestures(string placeHolderName, IEnumerable gestures) { + var serializedGestures = (string[])new KeysCollectionConverter().ConvertTo(gestures, typeof(string[])); + + BaseGesturesPlaceHolderRegistry.AddGestures(placeHolderName, serializedGestures); + } + + /// + /// Remove gestures from place holder + /// + /// Null argumens are igonred and all gestures which specify + /// provided parameters are removed + /// + /// Place holder name + /// Gestures + public static void RemoveGestures(string placeHolderName, IEnumerable gestures) { + var serializedGestures = (string[])new KeysCollectionConverter().ConvertTo(gestures, typeof(string[])); + + BaseGesturesPlaceHolderRegistry.RemoveGestures(placeHolderName, serializedGestures); + } + + /// + /// Register update handler which will trigger when gestures in + /// place holder are updated + /// + /// Place holder name + /// Handler which handles place holder gestures update + public static void RegisterUpdateHandler(string placeHolderName, GesturesPlaceHolderUpdate handler) { + BaseGesturesPlaceHolderRegistry.RegisterUpdateHandler(placeHolderName, handler); + } + + /// + /// Invoke delegates which handle gestures update in place holder + /// + /// If place holder is not provided all registered handlers are invoked + /// + /// + public static void InvokeUpdateHandlers(string placeHolderName) { + BaseGesturesPlaceHolderRegistry.InvokeUpdateHandlers(placeHolderName); + } + } +} diff --git a/src/Main/ICSharpCode.Core.WinForms/CommandsService/KeysCollectionConverter.cs b/src/Main/ICSharpCode.Core.WinForms/CommandsService/KeysCollectionConverter.cs new file mode 100644 index 0000000000..08c927018e --- /dev/null +++ b/src/Main/ICSharpCode.Core.WinForms/CommandsService/KeysCollectionConverter.cs @@ -0,0 +1,114 @@ +using System; +using System.Windows.Forms; +using System.ComponentModel; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using System.Globalization; + +namespace ICSharpCode.Core.WinForms +{ + /// + /// Converts objects of different types to array of keys and + /// convert enumerable back to objects of different type + /// + public class KeysCollectionConverter : TypeConverter + { + /// + /// Returns a value indicating whether this converter can convert an object in the + /// specified source type to the native type of the converter. + /// + /// Type descriptor context + /// Source type + /// Array of keys + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { + if (sourceType == typeof(string)) { + return true; + } if (sourceType == typeof(string[])) { + return true; + } + + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Returns a value indicating whether this converter can convert a + /// specified object to the specified destination type. + /// + /// An ITypeDescriptorContext that provides a format context, which can be used to extract additional information about the environment this converter is being invoked from. This parameter or properties of this parameter can be a null reference + /// Convertion destination type + /// Destination object + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { + if (destinationType == typeof(string) || destinationType == typeof(string[])) { + return true; + } + + return base.CanConvertTo(context, destinationType); + } + + /// + /// Convert from source object to array of keys + /// + /// An ITypeDescriptorContext that provides a format context, which can be used to extract additional information about the environment this converter is being invoked from. This parameter or properties of this parameter can be a null reference + /// Locale information which can influence convertion + /// Array of Keys + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { + if(value is string || value is string[]) { + var gestures = new List(); + + string[] serializedGestures; + if(value is string) { + serializedGestures = Regex.Split((string)value, @"\s*\|\s*"); + } else { + serializedGestures = (string[])value; + } + + foreach(var serializedGesture in serializedGestures) { + if(string.IsNullOrEmpty(serializedGesture)) continue; + + gestures.Add((Keys)new KeysConverter().ConvertFromInvariantString(serializedGesture)); + } + + return gestures.ToArray(); + } + + return base.ConvertFrom(context, culture, value); + } + + /// + /// Converts array of keys to the specified destination type + /// + /// An ITypeDescriptorContext that provides a format context, which can be used to extract additional information about the environment this converter is being invoked from. This parameter or properties of this parameter can be a null reference + /// Locale information which can influence convertion + /// Array of keys + /// Convertion destination type + /// + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { + if(destinationType == typeof(string) || destinationType == typeof(string[])) + { + if(value == null) return null; + + var keysCollection = (IEnumerable)value; + var serializedKeysCollection = new List(); + + foreach(var gesture in keysCollection) { + var serializedGesture = new KeysConverter().ConvertToInvariantString(gesture); + serializedKeysCollection.Add(serializedGesture); + } + + if(destinationType == typeof(string[])) { + return serializedKeysCollection.ToArray(); + } else if(destinationType == typeof(string)) { + var sb = new StringBuilder(); + foreach(var serializedGesture in serializedKeysCollection) { + sb.AppendFormat("{0} | ", serializedGesture); + } + + return sb.Length >= 3 ? sb.ToString(0, sb.Length - 3) : sb.ToString(); + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + } +} diff --git a/src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj b/src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj index efab108000..9286a679a5 100644 --- a/src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj +++ b/src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj @@ -50,6 +50,8 @@ Properties\GlobalAssemblyInfo.cs + + @@ -85,6 +87,7 @@ + diff --git a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs index 4148bcf36c..909b1bcc3f 100644 --- a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs +++ b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs @@ -8,6 +8,7 @@ using System; using System.Drawing; using System.Windows.Forms; +using System.Text.RegularExpressions; namespace ICSharpCode.Core.WinForms { @@ -63,22 +64,6 @@ namespace ICSharpCode.Core.WinForms } - public static Keys ParseShortcut(string shortcutString) - { - Keys shortCut = Keys.None; - if (shortcutString.Length > 0) { - try { - foreach (string key in shortcutString.Split('|')) { - shortCut |= (System.Windows.Forms.Keys)Enum.Parse(typeof(System.Windows.Forms.Keys), key); - } - } catch (Exception ex) { - MessageService.ShowError(ex); - return System.Windows.Forms.Keys.None; - } - } - return shortCut; - } - public MenuCommand(Codon codon, object caller, bool createCommand) { this.RightToLeft = RightToLeft.Inherit; @@ -90,8 +75,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"]); + if (codon.Properties.Contains("shortcut")) { - ShortcutKeys = ParseShortcut(codon.Properties["shortcut"]); + GesturePlaceHolderRegistry.InvokeUpdateHandlers(codon.Properties["class"]); } } diff --git a/src/SharpDevelop.sln b/src/SharpDevelop.sln index 85ee0e8ed6..093c97bb42 100644 --- a/src/SharpDevelop.sln +++ b/src/SharpDevelop.sln @@ -1,172 +1,172 @@  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 -# SharpDevelop 3.1.0.4094 +# SharpDevelop 3.1.0.4077 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Display Bindings", "Display Bindings", "{4EA396ED-64AD-4AD0-A67A-AB363F3E0C79}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowDesigner", "AddIns\DisplayBindings\WorkflowDesigner\Project\WorkflowDesigner.csproj", "{533F4684-DBA6-4518-B005-C84F22A2DD57}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRefactoring", "AddIns\Misc\SharpRefactoring\SharpRefactoring.csproj", "{3CA90546-3B4C-4663-9445-C4E9371750A7}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClassDiagram", "ClassDiagram", "{DB137F0B-9B62-4232-AE92-F7BE0280B8D3}" - ProjectSection(SolutionItems) = postProject - EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceAnalysis", "AddIns\Misc\SourceAnalysis\SourceAnalysis.csproj", "86CE7B3F-6273-4215-9E36-6184D98F854E" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Diagrams", "AddIns\DisplayBindings\ClassDiagram\DiagramRouter\Diagrams.csproj", "{0991423A-DBF6-4C89-B365-A1DF1EB32E42}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace", "AddIns\Misc\SearchAndReplace\Project\SearchAndReplace.csproj", "{9196DD8A-B4D4-4780-8742-C5762E547FC2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassDiagramAddin", "AddIns\DisplayBindings\ClassDiagram\ClassDiagramAddin\ClassDiagramAddin.csproj", "{5A1354DF-4989-4BB4-BC6B-D627C2E9FA13}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddinScout", "AddIns\Misc\AddinScout\Project\AddinScout.csproj", "{4B8F0F98-8BE1-402B-AA8B-C8D548577B38}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassCanvas", "AddIns\DisplayBindings\ClassDiagram\ClassCanvas\ClassCanvas.csproj", "{08F772A1-F0BE-433E-8B37-F6522953DB05}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartPage", "AddIns\Misc\StartPage\Project\StartPage.csproj", "{7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SettingsEditor", "AddIns\DisplayBindings\SettingsEditor\Project\SettingsEditor.csproj", "{85226AFB-CE71-4851-9A75-7EEC663A8E8A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegExpTk", "AddIns\Misc\RegExpTk\Project\RegExpTk.csproj", "{64A3E5E6-90BF-47F6-94DF-68C94B62C817}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IconEditor", "IconEditor", "{0D37CE59-B0EF-4F3C-B9EB-8557E53A448B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiletypeRegisterer", "AddIns\Misc\FiletypeRegisterer\Project\FiletypeRegisterer.csproj", "{D022A6CE-7438-41E8-AC64-F2DE18EC54C6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{6604365C-C702-4C10-9BA8-637F1E3D4D0D}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditorAddIn", "AddIns\DisplayBindings\IconEditor\IconEditorAddIn\IconEditorAddIn.csproj", "{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "AddIns\Misc\Debugger\Debugger.Core\Project\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditor", "AddIns\DisplayBindings\IconEditor\IconEditor\IconEditor.csproj", "{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.AddIn", "AddIns\Misc\Debugger\Debugger.AddIn\Project\Debugger.AddIn.csproj", "{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor", "AddIns\DisplayBindings\XmlEditor\Project\XmlEditor.csproj", "{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlHelp2", "AddIns\Misc\HtmlHelp2\Project\HtmlHelp2.csproj", "{918487B7-2153-4618-BBB3-344DBDDF2A2A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormsDesigner", "AddIns\DisplayBindings\FormsDesigner\Project\FormsDesigner.csproj", "{7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddInManager", "AddIns\Misc\AddInManager\Project\AddInManager.csproj", "{F93E52FD-DA66-4CE5-A0CB-BCD902811122}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceEditor", "AddIns\DisplayBindings\ResourceEditor\Project\ResourceEditor.csproj", "{CBC6C247-747B-4908-B09A-4D2E0F640B6B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PInvokeAddIn", "AddIns\Misc\PInvokeAddIn\Project\PInvokeAddIn.csproj", "{5EEB99CF-EA2B-4733-80A6-CE9192D68170}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HexEditor", "AddIns\DisplayBindings\HexEditor\Project\HexEditor.csproj", "{E618A9CD-A39F-4925-A538-E8A3FEF24E54}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCoverage", "AddIns\Misc\CodeCoverage\Project\CodeCoverage.csproj", "{08ce9972-283b-44f4-82fa-966f7dfa6b7a}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvalonEdit.AddIn", "AddIns\DisplayBindings\AvalonEdit.AddIn\AvalonEdit.AddIn.csproj", "{0162E499-42D0-409B-AA25-EED21F75336B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting", "AddIns\Misc\UnitTesting\UnitTesting.csproj", "{1F261725-6318-4434-A1B1-6C70CE4CD324}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Backends", "Backends", "{FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}" +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "HtmlHelp2JScriptGlobals", "AddIns\Misc\HtmlHelp2\JScriptGlobals\HtmlHelp2JScriptGlobals.vbproj", "{E54A5AD2-418D-4A85-BA5E-CD803DE38715}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SubversionAddIn", "AddIns\Misc\SubversionAddIn\Project\SubversionAddIn.csproj", "{17F4D7E0-6933-4C2E-8714-FD7E98D625D5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeAnalysis", "AddIns\Misc\CodeAnalysis\CodeAnalysis.csproj", "{3EAA45A9-735C-4AC7-A799-947B93EA449D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ComponentInspector", "ComponentInspector", "{BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixBinding", "AddIns\BackendBindings\WixBinding\Project\WixBinding.csproj", "{e1b288a2-08ee-4318-8bbb-8ab72c69e33e}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter", "AddIns\BackendBindings\Boo\NRefactoryToBooConverter\Project\NRefactoryToBooConverter.csproj", "{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector", "AddIns\Misc\ComponentInspector\ComponentInspector\ComponentInspector.csproj", "{000E4F64-5D0D-4EB1-B0BF-1A62ADBC6EAD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding", "AddIns\BackendBindings\Boo\BooBinding\Project\BooBinding.csproj", "{4AC2D5F1-F671-480C-A075-6BF62B3721B2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector.AddIn", "AddIns\Misc\ComponentInspector\ComponentInspector.AddIn\ComponentInspector.AddIn.csproj", "{869951D5-A0D6-4DC6-9F1D-E6B9A12AC446}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILAsmBinding", "AddIns\BackendBindings\ILAsmBinding\Project\ILAsmBinding.csproj", "{6e59af58-f635-459a-9a35-c9ac41c00339}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector.Core", "AddIns\Misc\ComponentInspector\ComponentInspector.Core\ComponentInspector.Core.csproj", "{E6F4983F-DE41-4AEC-88E7-1FA9AFB4E6FF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VBNetBinding", "AddIns\BackendBindings\VBNetBinding\Project\VBNetBinding.csproj", "{BF38FB72-B380-4196-AF8C-95749D726C61}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceToolkit", "AddIns\Misc\ResourceToolkit\Project\ResourceToolkit.csproj", "{461606BD-E824-4D0A-8CBA-01810B1F5E02}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBinding", "AddIns\BackendBindings\CSharpBinding\Project\CSharpBinding.csproj", "{1F1AC7CD-D154-45BB-8EAF-804CA8055F5A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReflectorAddIn", "AddIns\Misc\ReflectorAddIn\ReflectorAddIn\Project\ReflectorAddIn.csproj", "{8AA421C8-D7AF-4957-9F43-5135328ACB24}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Python", "Python", "{8CF9DB5A-A2F6-4A88-BABA-100912EAF6E8}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Backends", "Backends", "{FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Python.Build.Tasks", "AddIns\BackendBindings\Python\Python.Build.Tasks\Project\Python.Build.Tasks.csproj", "{D332F2D1-2CF1-43B7-903C-844BD5211A7E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PythonBinding", "AddIns\BackendBindings\Python\PythonBinding\Project\PythonBinding.csproj", "{8D732610-8FC6-43BA-94C9-7126FD7FE361}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlBinding", "AddIns\BackendBindings\XamlBinding\XamlBinding\XamlBinding.csproj", "{7C96B65D-28A5-4F28-A35B-8D83CE831EE8}" EndProject Project("{982E8BC1-ACD7-4dbf-96AB-B2CE67D6A008}") = "FSharpBinding", "AddIns\BackendBindings\FSharp\FSharpBinding\Project\FSharpBinding.fsproj", "{99BAE3A2-C40D-40D2-A7B4-EBB4798F36E4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlBinding", "AddIns\BackendBindings\XamlBinding\XamlBinding\XamlBinding.csproj", "{7C96B65D-28A5-4F28-A35B-8D83CE831EE8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Python", "Python", "{8CF9DB5A-A2F6-4A88-BABA-100912EAF6E8}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReflectorAddIn", "AddIns\Misc\ReflectorAddIn\ReflectorAddIn\Project\ReflectorAddIn.csproj", "{8AA421C8-D7AF-4957-9F43-5135328ACB24}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PythonBinding", "AddIns\BackendBindings\Python\PythonBinding\Project\PythonBinding.csproj", "{8D732610-8FC6-43BA-94C9-7126FD7FE361}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceToolkit", "AddIns\Misc\ResourceToolkit\Project\ResourceToolkit.csproj", "{461606BD-E824-4D0A-8CBA-01810B1F5E02}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Python.Build.Tasks", "AddIns\BackendBindings\Python\Python.Build.Tasks\Project\Python.Build.Tasks.csproj", "{D332F2D1-2CF1-43B7-903C-844BD5211A7E}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ComponentInspector", "ComponentInspector", "{BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C}" - ProjectSection(SolutionItems) = postProject - EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBinding", "AddIns\BackendBindings\CSharpBinding\Project\CSharpBinding.csproj", "{1F1AC7CD-D154-45BB-8EAF-804CA8055F5A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector.Core", "AddIns\Misc\ComponentInspector\ComponentInspector.Core\ComponentInspector.Core.csproj", "{E6F4983F-DE41-4AEC-88E7-1FA9AFB4E6FF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VBNetBinding", "AddIns\BackendBindings\VBNetBinding\Project\VBNetBinding.csproj", "{BF38FB72-B380-4196-AF8C-95749D726C61}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector.AddIn", "AddIns\Misc\ComponentInspector\ComponentInspector.AddIn\ComponentInspector.AddIn.csproj", "{869951D5-A0D6-4DC6-9F1D-E6B9A12AC446}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILAsmBinding", "AddIns\BackendBindings\ILAsmBinding\Project\ILAsmBinding.csproj", "{6e59af58-f635-459a-9a35-c9ac41c00339}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector", "AddIns\Misc\ComponentInspector\ComponentInspector\ComponentInspector.csproj", "{000E4F64-5D0D-4EB1-B0BF-1A62ADBC6EAD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding", "AddIns\BackendBindings\Boo\BooBinding\Project\BooBinding.csproj", "{4AC2D5F1-F671-480C-A075-6BF62B3721B2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeAnalysis", "AddIns\Misc\CodeAnalysis\CodeAnalysis.csproj", "{3EAA45A9-735C-4AC7-A799-947B93EA449D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter", "AddIns\BackendBindings\Boo\NRefactoryToBooConverter\Project\NRefactoryToBooConverter.csproj", "{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SubversionAddIn", "AddIns\Misc\SubversionAddIn\Project\SubversionAddIn.csproj", "{17F4D7E0-6933-4C2E-8714-FD7E98D625D5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixBinding", "AddIns\BackendBindings\WixBinding\Project\WixBinding.csproj", "{e1b288a2-08ee-4318-8bbb-8ab72c69e33e}" EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "HtmlHelp2JScriptGlobals", "AddIns\Misc\HtmlHelp2\JScriptGlobals\HtmlHelp2JScriptGlobals.vbproj", "{E54A5AD2-418D-4A85-BA5E-CD803DE38715}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Display Bindings", "Display Bindings", "{4EA396ED-64AD-4AD0-A67A-AB363F3E0C79}" + ProjectSection(SolutionItems) = postProject + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting", "AddIns\Misc\UnitTesting\UnitTesting.csproj", "{1F261725-6318-4434-A1B1-6C70CE4CD324}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvalonEdit.AddIn", "AddIns\DisplayBindings\AvalonEdit.AddIn\AvalonEdit.AddIn.csproj", "{0162E499-42D0-409B-AA25-EED21F75336B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCoverage", "AddIns\Misc\CodeCoverage\Project\CodeCoverage.csproj", "{08ce9972-283b-44f4-82fa-966f7dfa6b7a}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HexEditor", "AddIns\DisplayBindings\HexEditor\Project\HexEditor.csproj", "{E618A9CD-A39F-4925-A538-E8A3FEF24E54}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PInvokeAddIn", "AddIns\Misc\PInvokeAddIn\Project\PInvokeAddIn.csproj", "{5EEB99CF-EA2B-4733-80A6-CE9192D68170}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceEditor", "AddIns\DisplayBindings\ResourceEditor\Project\ResourceEditor.csproj", "{CBC6C247-747B-4908-B09A-4D2E0F640B6B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddInManager", "AddIns\Misc\AddInManager\Project\AddInManager.csproj", "{F93E52FD-DA66-4CE5-A0CB-BCD902811122}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormsDesigner", "AddIns\DisplayBindings\FormsDesigner\Project\FormsDesigner.csproj", "{7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlHelp2", "AddIns\Misc\HtmlHelp2\Project\HtmlHelp2.csproj", "{918487B7-2153-4618-BBB3-344DBDDF2A2A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor", "AddIns\DisplayBindings\XmlEditor\Project\XmlEditor.csproj", "{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{6604365C-C702-4C10-9BA8-637F1E3D4D0D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IconEditor", "IconEditor", "{0D37CE59-B0EF-4F3C-B9EB-8557E53A448B}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.AddIn", "AddIns\Misc\Debugger\Debugger.AddIn\Project\Debugger.AddIn.csproj", "{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "AddIns\Misc\Debugger\Debugger.Core\Project\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditor", "AddIns\DisplayBindings\IconEditor\IconEditor\IconEditor.csproj", "{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiletypeRegisterer", "AddIns\Misc\FiletypeRegisterer\Project\FiletypeRegisterer.csproj", "{D022A6CE-7438-41E8-AC64-F2DE18EC54C6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditorAddIn", "AddIns\DisplayBindings\IconEditor\IconEditorAddIn\IconEditorAddIn.csproj", "{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegExpTk", "AddIns\Misc\RegExpTk\Project\RegExpTk.csproj", "{64A3E5E6-90BF-47F6-94DF-68C94B62C817}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SettingsEditor", "AddIns\DisplayBindings\SettingsEditor\Project\SettingsEditor.csproj", "{85226AFB-CE71-4851-9A75-7EEC663A8E8A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartPage", "AddIns\Misc\StartPage\Project\StartPage.csproj", "{7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClassDiagram", "ClassDiagram", "{DB137F0B-9B62-4232-AE92-F7BE0280B8D3}" + ProjectSection(SolutionItems) = postProject + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddinScout", "AddIns\Misc\AddinScout\Project\AddinScout.csproj", "{4B8F0F98-8BE1-402B-AA8B-C8D548577B38}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassCanvas", "AddIns\DisplayBindings\ClassDiagram\ClassCanvas\ClassCanvas.csproj", "{08F772A1-F0BE-433E-8B37-F6522953DB05}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace", "AddIns\Misc\SearchAndReplace\Project\SearchAndReplace.csproj", "{9196DD8A-B4D4-4780-8742-C5762E547FC2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassDiagramAddin", "AddIns\DisplayBindings\ClassDiagram\ClassDiagramAddin\ClassDiagramAddin.csproj", "{5A1354DF-4989-4BB4-BC6B-D627C2E9FA13}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceAnalysis", "AddIns\Misc\SourceAnalysis\SourceAnalysis.csproj", "86CE7B3F-6273-4215-9E36-6184D98F854E" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Diagrams", "AddIns\DisplayBindings\ClassDiagram\DiagramRouter\Diagrams.csproj", "{0991423A-DBF6-4C89-B365-A1DF1EB32E42}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRefactoring", "AddIns\Misc\SharpRefactoring\SharpRefactoring.csproj", "{3CA90546-3B4C-4663-9445-C4E9371750A7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowDesigner", "AddIns\DisplayBindings\WorkflowDesigner\Project\WorkflowDesigner.csproj", "{533F4684-DBA6-4518-B005-C84F22A2DD57}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{9421EDF4-9769-4BE9-B5A6-C87DE221D73C}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TreeView", "Libraries\SharpTreeView\ICSharpCode.TreeView\ICSharpCode.TreeView.csproj", "{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvalonDock", "Libraries\AvalonDock\AvalonDock.csproj", "{2FF700C2-A38A-48BD-A637-8CAFD4FE6237}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aga.Controls", "Libraries\TreeViewAdv\Aga.Controls\Aga.Controls.csproj", "{E73BB233-D88B-44A7-A98F-D71EE158381D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.AvalonEdit", "Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj", "{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Build.Tasks", "Libraries\ICSharpCode.Build.Tasks\Project\ICSharpCode.Build.Tasks.csproj", "{4139CCF6-FB49-4A9D-B2CF-331E9EA3198D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor", "Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj", "{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Build.Tasks", "Libraries\ICSharpCode.Build.Tasks\Project\ICSharpCode.Build.Tasks.csproj", "{4139CCF6-FB49-4A9D-B2CF-331E9EA3198D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.AvalonEdit", "Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj", "{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aga.Controls", "Libraries\TreeViewAdv\Aga.Controls\Aga.Controls.csproj", "{E73BB233-D88B-44A7-A98F-D71EE158381D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvalonDock", "Libraries\AvalonDock\AvalonDock.csproj", "{2FF700C2-A38A-48BD-A637-8CAFD4FE6237}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TreeView", "Libraries\SharpTreeView\ICSharpCode.TreeView\ICSharpCode.TreeView.csproj", "{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{5A3EBEBA-0560-41C1-966B-23F7D03A5486}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.WinForms", "Main\ICSharpCode.Core.WinForms\ICSharpCode.Core.WinForms.csproj", "{857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.Presentation", "Main\ICSharpCode.Core.Presentation\ICSharpCode.Core.Presentation.csproj", "{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Widgets", "Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj", "{8035765F-D51F-4A0C-A746-2FD100E19419}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.BuildWorker", "Main\ICSharpCode.SharpDevelop.BuildWorker\ICSharpCode.SharpDevelop.BuildWorker.csproj", "{C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Sda", "Main\ICSharpCode.SharpDevelop.Sda\ICSharpCode.SharpDevelop.Sda.csproj", "{80318B5F-A25D-45AB-8A95-EF31D2370A4C}" +Project("{00000000-0000-0000-0000-000000000000}") = "Tools", "Tools\Tools.build", "B13EFF7F-7EA4-4B68-A375-D112105E9182" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartUp", "Main\StartUp\Project\StartUp.csproj", "{1152B71B-3C05-4598-B20D-823B5D40559E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartUp", "Main\StartUp\Project\StartUp.csproj", "{1152B71B-3C05-4598-B20D-823B5D40559E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}" EndProject -Project("{00000000-0000-0000-0000-000000000000}") = "Tools", "Tools\Tools.build", "B13EFF7F-7EA4-4B68-A375-D112105E9182" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Sda", "Main\ICSharpCode.SharpDevelop.Sda\ICSharpCode.SharpDevelop.Sda.csproj", "{80318B5F-A25D-45AB-8A95-EF31D2370A4C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.BuildWorker", "Main\ICSharpCode.SharpDevelop.BuildWorker\ICSharpCode.SharpDevelop.BuildWorker.csproj", "{C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Widgets", "Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj", "{8035765F-D51F-4A0C-A746-2FD100E19419}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.Presentation", "Main\ICSharpCode.Core.Presentation\ICSharpCode.Core.Presentation.csproj", "{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.WinForms", "Main\ICSharpCode.Core.WinForms\ICSharpCode.Core.WinForms.csproj", "{857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -420,74 +420,74 @@ Global {2FF700C2-A38A-48BD-A637-8CAFD4FE6237}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution - {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {0162E499-42D0-409B-AA25-EED21F75336B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {E618A9CD-A39F-4925-A538-E8A3FEF24E54} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {CBC6C247-747B-4908-B09A-4D2E0F640B6B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {6B717BD1-CD5E-498C-A42E-9E6A4584DC48} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {85226AFB-CE71-4851-9A75-7EEC663A8E8A} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {533F4684-DBA6-4518-B005-C84F22A2DD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {08F772A1-F0BE-433E-8B37-F6522953DB05} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} - {5A1354DF-4989-4BB4-BC6B-D627C2E9FA13} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} - {0991423A-DBF6-4C89-B365-A1DF1EB32E42} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} - {DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} - {DFB936AD-90EE-4B4F-941E-4F4A636F0D92} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} - {7C96B65D-28A5-4F28-A35B-8D83CE831EE8} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {99BAE3A2-C40D-40D2-A7B4-EBB4798F36E4} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {8CF9DB5A-A2F6-4A88-BABA-100912EAF6E8} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {1F1AC7CD-D154-45BB-8EAF-804CA8055F5A} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {BF38FB72-B380-4196-AF8C-95749D726C61} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {6e59af58-f635-459a-9a35-c9ac41c00339} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {DBCF20A1-BA13-4582-BFA9-74DE4D987B73} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {e1b288a2-08ee-4318-8bbb-8ab72c69e33e} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {8D732610-8FC6-43BA-94C9-7126FD7FE361} = {8CF9DB5A-A2F6-4A88-BABA-100912EAF6E8} - {D332F2D1-2CF1-43B7-903C-844BD5211A7E} = {8CF9DB5A-A2F6-4A88-BABA-100912EAF6E8} - {3CA90546-3B4C-4663-9445-C4E9371750A7} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - 86CE7B3F-6273-4215-9E36-6184D98F854E = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {9196DD8A-B4D4-4780-8742-C5762E547FC2} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {4B8F0F98-8BE1-402B-AA8B-C8D548577B38} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {64A3E5E6-90BF-47F6-94DF-68C94B62C817} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {D022A6CE-7438-41E8-AC64-F2DE18EC54C6} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {6604365C-C702-4C10-9BA8-637F1E3D4D0D} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {918487B7-2153-4618-BBB3-344DBDDF2A2A} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {F93E52FD-DA66-4CE5-A0CB-BCD902811122} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {5EEB99CF-EA2B-4733-80A6-CE9192D68170} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {08ce9972-283b-44f4-82fa-966f7dfa6b7a} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {1F261725-6318-4434-A1B1-6C70CE4CD324} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {E54A5AD2-418D-4A85-BA5E-CD803DE38715} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {17F4D7E0-6933-4C2E-8714-FD7E98D625D5} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {3EAA45A9-735C-4AC7-A799-947B93EA449D} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {461606BD-E824-4D0A-8CBA-01810B1F5E02} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} {8AA421C8-D7AF-4957-9F43-5135328ACB24} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {000E4F64-5D0D-4EB1-B0BF-1A62ADBC6EAD} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} - {869951D5-A0D6-4DC6-9F1D-E6B9A12AC446} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} - {E6F4983F-DE41-4AEC-88E7-1FA9AFB4E6FF} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} - {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} + {461606BD-E824-4D0A-8CBA-01810B1F5E02} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {3EAA45A9-735C-4AC7-A799-947B93EA449D} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {17F4D7E0-6933-4C2E-8714-FD7E98D625D5} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {E54A5AD2-418D-4A85-BA5E-CD803DE38715} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {1F261725-6318-4434-A1B1-6C70CE4CD324} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {08ce9972-283b-44f4-82fa-966f7dfa6b7a} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {5EEB99CF-EA2B-4733-80A6-CE9192D68170} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {F93E52FD-DA66-4CE5-A0CB-BCD902811122} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {918487B7-2153-4618-BBB3-344DBDDF2A2A} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {6604365C-C702-4C10-9BA8-637F1E3D4D0D} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {D022A6CE-7438-41E8-AC64-F2DE18EC54C6} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {64A3E5E6-90BF-47F6-94DF-68C94B62C817} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {4B8F0F98-8BE1-402B-AA8B-C8D548577B38} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {9196DD8A-B4D4-4780-8742-C5762E547FC2} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + 86CE7B3F-6273-4215-9E36-6184D98F854E = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {3CA90546-3B4C-4663-9445-C4E9371750A7} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} {EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} - {2FF700C2-A38A-48BD-A637-8CAFD4FE6237} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {4139CCF6-FB49-4A9D-B2CF-331E9EA3198D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {E73BB233-D88B-44A7-A98F-D71EE158381D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} + {E6F4983F-DE41-4AEC-88E7-1FA9AFB4E6FF} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} + {869951D5-A0D6-4DC6-9F1D-E6B9A12AC446} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} + {000E4F64-5D0D-4EB1-B0BF-1A62ADBC6EAD} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} + {e1b288a2-08ee-4318-8bbb-8ab72c69e33e} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {DBCF20A1-BA13-4582-BFA9-74DE4D987B73} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {6e59af58-f635-459a-9a35-c9ac41c00339} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {BF38FB72-B380-4196-AF8C-95749D726C61} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {1F1AC7CD-D154-45BB-8EAF-804CA8055F5A} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {8CF9DB5A-A2F6-4A88-BABA-100912EAF6E8} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {99BAE3A2-C40D-40D2-A7B4-EBB4798F36E4} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {7C96B65D-28A5-4F28-A35B-8D83CE831EE8} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {D332F2D1-2CF1-43B7-903C-844BD5211A7E} = {8CF9DB5A-A2F6-4A88-BABA-100912EAF6E8} + {8D732610-8FC6-43BA-94C9-7126FD7FE361} = {8CF9DB5A-A2F6-4A88-BABA-100912EAF6E8} + {533F4684-DBA6-4518-B005-C84F22A2DD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {85226AFB-CE71-4851-9A75-7EEC663A8E8A} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {6B717BD1-CD5E-498C-A42E-9E6A4584DC48} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {CBC6C247-747B-4908-B09A-4D2E0F640B6B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {E618A9CD-A39F-4925-A538-E8A3FEF24E54} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {0162E499-42D0-409B-AA25-EED21F75336B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {DFB936AD-90EE-4B4F-941E-4F4A636F0D92} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} + {DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} + {0991423A-DBF6-4C89-B365-A1DF1EB32E42} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} + {5A1354DF-4989-4BB4-BC6B-D627C2E9FA13} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} + {08F772A1-F0BE-433E-8B37-F6522953DB05} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} {DDE2A481-8271-4EAC-A330-8FA6A38D13D1} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - B13EFF7F-7EA4-4B68-A375-D112105E9182 = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {1152B71B-3C05-4598-B20D-823B5D40559E} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {2748AD25-9C63-4E12-877B-4DCE96FBED54} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {80318B5F-A25D-45AB-8A95-EF31D2370A4C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {8035765F-D51F-4A0C-A746-2FD100E19419} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {E73BB233-D88B-44A7-A98F-D71EE158381D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {4139CCF6-FB49-4A9D-B2CF-331E9EA3198D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {2FF700C2-A38A-48BD-A637-8CAFD4FE6237} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {8035765F-D51F-4A0C-A746-2FD100E19419} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {80318B5F-A25D-45AB-8A95-EF31D2370A4C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {2748AD25-9C63-4E12-877B-4DCE96FBED54} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {1152B71B-3C05-4598-B20D-823B5D40559E} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + B13EFF7F-7EA4-4B68-A375-D112105E9182 = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} EndGlobalSection EndGlobal From 5449d1aa4fe53f455f8dd0476726b476b719bfdf Mon Sep 17 00:00:00 2001 From: Sergej Andrejev Date: Wed, 3 Jun 2009 22:21:31 +0000 Subject: [PATCH 02/51] Filter shortcuts by key gesture in shortcuts management addin and other visual enchantments git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4219 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../ShortcutsManagement.suo | Bin 51712 -> 66048 bytes .../ShortcutsManagement.csproj | 5 + .../Src/Converters/GesturesListConverter.cs | 7 +- .../ShortcutsManagement/Src/Data/Shortcut.cs | 14 ++- .../Src/Data/ShortcutsProvider.cs | 113 +++++++++++++++--- .../ShortcutsManagementOptionsPanel.xaml | 33 ++--- .../ShortcutsManagementOptionsPanel.xaml.cs | 92 +++++++++++--- .../Src/Extensions/GesturesHelper.cs | 49 ++++++++ .../Src/Extensions/TextBlockBehavior.cs | 7 +- .../Src/Extensions/TreeViewExtensions.cs | 12 +- 10 files changed, 272 insertions(+), 60 deletions(-) create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/GesturesHelper.cs diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo index 8e13b9c93a269146a31f9a57691071e24e275521..fc96421dd7a97a196443a286306a9bff0a02f5bb 100644 GIT binary patch delta 3742 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 delta 2395 zcmaKte^gXO6vt=YzFpt)8{CkBVp&i@!H|H=C>Iy?_={bF&@vOtGCgP((9zX$ODnVE zNx7D$gxaC}ffX{PW+p32fnw4x|0s`8(dmb#R;-yR^qt+e{qmgNJD+#&+&lAT=Dj=j zdX}r6wT6Z~MeXhD>m$38z~gAT63?S(k@7tClx13-jIn9J1&Y8u0Db#PAcuoBMR8Pa zNLf>~pjw^8!zoEkj5t60u7O3}ZQKCAy@1^6cydGzr%Y8P??RO>tF1henhxDac8f|E zjd_9DN0>4LO1Y_yub^l{;`GUQK_QTf2rl3b=*2)T;7(8qrhuv7E^s%H3ziF=4(C2FkR5IrHQIT=&p$?CPy z!LW5?(Nbx7TGYA*&PPyd_+q(DV+guiXi^OVHt}LHCiz;Dq9ps?F+SpQSbz>WA)iF=X%ff1rc70ozv=# z6AgAlGu^&2N5oTtqBoMsOfjNqbsEp-oG}F$fC`Mj1o{CDm_Y~#1z{i@M1V*T1$uWC zy~Wp*MG>EHE7@IfG^{9wR!_9h`)h4fYc5b7%b3{(tSi;~r;ASRMl8VOGwnSS6bSZ9co5yerd+m%t}y%4Vb4 z2$t`EX0Z%tIqYU8wQM$)jR6_#7T6rnGa$44cQ(9oWUilVCTC)FywE1RSzg{~+sWxf zauOX&E)iRDJ9+gWi@7z8v2mk|9gk7c(D$fePzoJe5n;M~XvVCMzY$S`Ek^F4{L@G2 ze7cR?^TPNXy7Fy{=s1<2G-h?0xlMH4TF;eKuUK_kg+iWz9^q;9aC-CG6cP2+Nkesk zBM?3EpviDGT?fU^$Xzhr%;hPK(jC-O;8gfPdFVvtm=2Sc3WpjTH4KVJBln~>a>U$5 zp2?M=GIWz-@W6|obiE>K3hNXeO+2$noas*B;@%RK)1~fx=k4=x;_n_0nY+|{<4;(4wTAT7+wS~>5lb~FM|zWqqNby zvgD<&L3+Lrn-vn>z?Ol+KK!CS(+iu7`U@v%Ax4j3sAH1)(n;^a5 zAZP}1uEPvL)`G?dx}g=a4IBYSb=xt>kHB%zq1!%z{1ki!K9@GSbEbnXmW56G5v|kU z4EPD01?Rwd@H6-Y{0e%24_pAhfs5dGa0&bYE`uwe7x;e)XY`0Q2dVu^%g@yP(HE4} z-X*$bSvj{-{@{2@Ex+eqe;>jA^>Ld2kd4>raqt+QBNET-Qj9V<*8dgpchAm)qwQ>) zD$YD=;nd-~PL%l;aB6P8D0X*fhU$f0DmdMW_!=3RhjYAuJs{6A3uhq|t=(AdUZ`}Z zk=yO&>&WMJYJ;)l>p>uMFLnmbK!$D!t%D-J5-v(w=AZ>9qUhw~&0@*YXG~;WRv-FwJr_mfyqNAJMspq+Eh%fYC3;M_%?-^D9ag3mnOsxn2BRmfvwL&?J8%B zkkaO}2ie1P^0{g1P1!lQ>$Y${L)IYI-wzbq2)w|bjr(B+Tqh{=h0jIpb{ne0gt;;c zn*$C!>ELHutEbtG5z<04hg?J6dV6DTr;$2$B{k+fe{~Y7-s|ue^~$|2Eg6H1a-iJC z0rKs2YBn@)2$~L2)w@eWKSWa&8flHTPoY!arHUu^ePGZA!D5wGIlP^!4iuXCwP+^= zZ6A~GKw)6ECYP2D^AO!7dYYVSz;oE?uf8?##1T(PB$p+f4!7jVZ&Dx*x9sQSdB9G? zW~Ye`#9|wH|bhgP$uK6S0KTSg)GOvs6ZGl Xp+_?I=m~ISWT3d@qdYiJOtSw39x(ML diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj index c4b85c436d..bd922aeebe 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj @@ -47,6 +47,10 @@ False ..\..\..\..\..\bin\ICSharpCode.Core.dll + + False + ..\..\..\..\..\bin\ICSharpCode.Core.Presentation.dll + False ..\..\..\..\..\bin\ICSharpCode.SharpDevelop.dll @@ -125,6 +129,7 @@ + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs index 0137209f1c..77a5ad67a0 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Globalization; using System.Windows.Data; +using System.Windows.Input; +using ICSharpCode.Core.Presentation; namespace ICSharpCode.ShortcutsManagement { @@ -10,10 +12,9 @@ namespace ICSharpCode.ShortcutsManagement { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - if (value is IEnumerable && (targetType == typeof(string) || targetType.IsSubclassOf(typeof(string)))) + if (value is InputGestureCollection && (targetType == typeof(string) || targetType.IsSubclassOf(typeof(string)))) { - var enumerableValue = (IEnumerable)value; - return string.Join(" | ", enumerableValue.ToArray()); + return new InputGestureCollectionConverter().ConvertToInvariantString(value); } return value.ToString(); diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs index 91278bd297..5a8416d963 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs @@ -1,5 +1,7 @@ -using System.Collections.Generic; +using System.Collections; +using System.Collections.Generic; using System.ComponentModel; +using System.Windows.Input; namespace ICSharpCode.ShortcutsManagement { @@ -11,7 +13,7 @@ namespace ICSharpCode.ShortcutsManagement /// /// List of keyboard gestures which will invoke provided action /// - public List Gestures + public InputGestureCollection Gestures { get; private set; @@ -66,11 +68,15 @@ namespace ICSharpCode.ShortcutsManagement /// /// Shortcut action name /// Gestures - public Shortcut(string shortcutName, List gestures) + public Shortcut(string shortcutName, InputGestureCollection gestures) { IsVisible = true; Name = shortcutName; - Gestures = gestures ?? new List(); + Gestures = new InputGestureCollection(); + if(gestures != null) + { + Gestures.AddRange(gestures); + } } public event PropertyChangedEventHandler PropertyChanged; diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs index c66c65ff1e..ed8b2527d7 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs @@ -1,9 +1,18 @@ using System; -using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Globalization; +using System.Text.RegularExpressions; +using System.Windows.Input; +using ICSharpCode.Core.Presentation; namespace ICSharpCode.ShortcutsManagement { + internal enum FilterType + { + Gesture, + Action + } + internal class ShortcutsProvider { private readonly ObservableCollection addins = new ObservableCollection(); @@ -17,6 +26,70 @@ namespace ICSharpCode.ShortcutsManagement return addins; } + /// + /// Filter addins containing shortcuts with matching gesture + /// + /// Key event + public void FilterGesture(InputEventArgs keyEventArgs) + { + foreach (var addIn in addins) + { + var subCategoryIsVisible = false; + foreach (var category in addIn.Categories) + { + if (FilterGesture(category, keyEventArgs)) + { + subCategoryIsVisible = true; + } + } + + addIn.IsVisible = subCategoryIsVisible; + } + } + + /// + /// Filter categories containing shortcuts with matching gesture + /// + /// Category to filter + /// Key event + /// + private static bool FilterGesture(ShortcutCategory category, InputEventArgs keyEventArgs) + { + var isSubElementVisible = false; + foreach (var subCategory in category.SubCategories) + { + if (FilterGesture(subCategory, keyEventArgs)) + { + isSubElementVisible = true; + } + } + + foreach (var shortcut in category.Shortcuts) + { + var gestureMatched = false; + foreach (InputGesture gesture in shortcut.Gestures) + { + if(gesture.Matches(null, keyEventArgs)) + { + gestureMatched = true; + break; + } + } + + if (gestureMatched) + { + shortcut.IsVisible = true; + isSubElementVisible = true; + } + else + { + shortcut.IsVisible = false; + } + } + + return category.IsVisible = isSubElementVisible; + } + /// /// Filter addins, child categories and shortcuts where item name /// contains filter string @@ -67,7 +140,9 @@ namespace ICSharpCode.ShortcutsManagement foreach (var shortcut in category.Shortcuts) { - if ((forseMatch.HasValue && forseMatch.Value) || shortcut.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0) + if ( + (forseMatch.HasValue && forseMatch.Value) + || shortcut.Name.IndexOf(filterString, StringComparison.InvariantCultureIgnoreCase) >= 0) { shortcut.IsVisible = true; isSubElementVisible = true; @@ -81,31 +156,37 @@ namespace ICSharpCode.ShortcutsManagement return category.IsVisible = (forseMatch.HasValue && forseMatch.Value) || isSubElementVisible; } + private static InputGestureCollection GetGestures(string gesturesString) + { + var converter = new InputGestureCollectionConverter(); + return (InputGestureCollection)converter.ConvertFromInvariantString(gesturesString); + } + public ShortcutsProvider() { // Test data addins.Add(new AddIn("SharpDevelop")); addins[0].Categories.Add(new ShortcutCategory("Editing")); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Copy", new List { "Ctrl+C" })); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Paste", new List { "Ctrl+V", "Ctrl+Insert" })); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Cut", new List { "Ctrl+X" })); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Undo", new List { "Ctrl+Z" })); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Redo", new List { "Ctrl+Y" })); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Copy", GetGestures("Ctrl + C"))); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Paste", GetGestures("Ctrl + V | Ctrl+Insert"))); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Cut", GetGestures("Ctrl + X"))); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Undo", GetGestures("Ctrl + Z"))); + addins[0].Categories[0].Shortcuts.Add(new Shortcut("Redo", GetGestures("Ctrl + Y"))); addins[0].Categories.Add(new ShortcutCategory("Building")); - addins[0].Categories[1].Shortcuts.Add(new Shortcut("Build", new List { "Ctrl+Shift+B" })); - addins[0].Categories[1].Shortcuts.Add(new Shortcut("Run", new List { "F5" })); - addins[0].Categories[1].Shortcuts.Add(new Shortcut("Run without debuger", new List { "Ctrl+F5" })); - addins[0].Categories[1].Shortcuts.Add(new Shortcut("Attach debuger", new List { "Ctrl+F8" })); + addins[0].Categories[1].Shortcuts.Add(new Shortcut("Build", GetGestures("Ctrl + Shift+B"))); + addins[0].Categories[1].Shortcuts.Add(new Shortcut("Run", GetGestures("F5"))); + addins[0].Categories[1].Shortcuts.Add(new Shortcut("Run without debuger", GetGestures("Ctrl + F5"))); + addins[0].Categories[1].Shortcuts.Add(new Shortcut("Attach debuger", GetGestures("Ctrl + F8"))); addins[0].Categories.Add(new ShortcutCategory("Uncategorized")); - addins[0].Categories[2].Shortcuts.Add(new Shortcut("Attach debuger", new List { "Ctrl+F8" })); + addins[0].Categories[2].Shortcuts.Add(new Shortcut("Attach debuger", GetGestures("Ctrl + F8"))); addins.Add(new AddIn("Search & replace")); addins[1].Categories.Add(new ShortcutCategory("Uncategorized")); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick find", new List { "Ctrl+F" })); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick replace", new List { "Ctrl+H" })); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find in files", new List { "Ctrl+Shift+F" })); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Replace in files", new List { "Ctrl+Shift+H" })); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick find", GetGestures("Ctrl + F"))); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick replace", GetGestures("Ctrl + H"))); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find in files", GetGestures("Ctrl + Shift + F"))); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Replace in files", GetGestures("Ctrl + Shift + H"))); addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find symbol", null)); addins.Add(new AddIn("Unspecified")); diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml index a421114824..e96077e473 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml @@ -5,7 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ShortcutsManagement="clr-namespace:ICSharpCode.ShortcutsManagement" mc:Ignorable="d" - d:DesignHeight="300" d:DesignWidth="300" > + d:DesignHeight="300" d:DesignWidth="300" Padding="10" > @@ -19,7 +19,12 @@ - + + + + + + - + @@ -134,7 +135,7 @@ - + @@ -144,14 +145,14 @@ - - + + - + - + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs index fe19e3ed2b..a5313a950b 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; @@ -31,27 +32,16 @@ namespace ICSharpCode.ShortcutsManagement /// /// /// - private void searchTextBox_KeyUp(object sender, KeyEventArgs e) + private void searchTextBox_TextChanged(object sender, TextChangedEventArgs e) { - var receiver = ((ShortcutsProvider) Resources["ShortcutsReceiver"]); + if (!searchTypeToggleButton.IsChecked.HasValue || searchTypeToggleButton.IsChecked.Value) return; + + var receiver = ((ShortcutsProvider)Resources["ShortcutsReceiver"]); receiver.Filter(searchTextBox.Text); if (!string.IsNullOrEmpty(searchTextBox.Text)) { - // Select first visible shortcut - var selectedAddIn = receiver.GetAddIns().FirstOrDefault(a => a.IsVisible); - if (selectedAddIn != null) - { - var selectedCategory = selectedAddIn.Categories.FirstOrDefault(c => c.IsVisible); - if (selectedCategory != null) - { - var selectedShortcut = selectedCategory.Shortcuts.FirstOrDefault(s => s.IsVisible); - if (selectedShortcut != null) - { - shortcutsTreeView.SelectItem(new List { selectedAddIn, selectedCategory, selectedShortcut }); - } - } - } + SelectFirstVisibleShortcut(shortcutsTreeView, receiver.GetAddIns(), false); } else { @@ -59,6 +49,60 @@ namespace ICSharpCode.ShortcutsManagement } } + + private void searchTextBox_PreviewKeyDown(object sender, KeyEventArgs e) + { + var receiver = ((ShortcutsProvider)Resources["ShortcutsReceiver"]); + + // If Up/Down is pressed switch focus to shortcuts tree + var keyboardDevice = (KeyboardDevice)e.Device; + if (keyboardDevice.Modifiers == ModifierKeys.None + && Array.IndexOf(new[] { Key.Up, Key.Down }, e.Key) >= 0) + { + SelectFirstVisibleShortcut(shortcutsTreeView, receiver.GetAddIns(), true); + + return; + } + + if (searchTypeToggleButton.IsChecked.HasValue && !searchTypeToggleButton.IsChecked.Value) return; + + e.Handled = true; + + receiver.FilterGesture(e); + + SelectFirstVisibleShortcut(shortcutsTreeView, receiver.GetAddIns(), false); + + searchTextBox.Text = GesturesHelper.GetGestureFromKeyEventArgument(e); + } + + private void searchTypeToggleButton_Click(object sender, RoutedEventArgs e) + { + searchTextBox.Text = ""; + + var receiver = ((ShortcutsProvider)Resources["ShortcutsReceiver"]); + receiver.Filter(""); + shortcutsTreeView.SetExpandAll(false); + } + + private static void SelectFirstVisibleShortcut(TreeView treeView, IEnumerable addIns, bool setFocus) + { + // Select first visible shortcut + var selectedAddIn = addIns.FirstOrDefault(a => a.IsVisible); + if (selectedAddIn != null) + { + var selectedCategory = selectedAddIn.Categories.FirstOrDefault(c => c.IsVisible); + if (selectedCategory != null) + { + var selectedShortcut = selectedCategory.Shortcuts.FirstOrDefault(s => s.IsVisible); + if (selectedShortcut != null) + { + treeView.SelectItem(new List { selectedAddIn, selectedCategory, selectedShortcut }, setFocus); + } + } + } + } + + #region IOptionPanel public void LoadOptions() { } @@ -80,5 +124,19 @@ namespace ICSharpCode.ShortcutsManagement return this; } } + #endregion + + private void shortcutsTreeView_PreviewKeyDown(object sender, KeyEventArgs e) + { + // If not navigating tree set focus to search text box + var keyboardDevice = (KeyboardDevice)e.Device; + if (keyboardDevice.Modifiers != ModifierKeys.None + || Array.IndexOf(new[] { Key.Up, Key.Right, Key.Down, Key.Left }, e.Key) < 0) + { + searchTextBox.Text = ""; + Keyboard.Focus(searchTextBox); + return; + } + } } } diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/GesturesHelper.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/GesturesHelper.cs new file mode 100644 index 0000000000..3606bfa850 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/GesturesHelper.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Input; + +namespace ICSharpCode.ShortcutsManagement +{ + public static class GesturesHelper + { + public static string GetGestureFromKeyEventArgument(KeyEventArgs args) + { + var pressedButton = new StringBuilder(); + + // If gesture is not supported that means it was not entered fully + var keyboardDevice = (KeyboardDevice) args.Device; + if ((keyboardDevice.Modifiers & ModifierKeys.Control) > 0) + { + pressedButton.Append("Ctrl + "); + } + if ((keyboardDevice.Modifiers & ModifierKeys.Windows) > 0) + { + pressedButton.Append("Windows + "); + } + if ((keyboardDevice.Modifiers & ModifierKeys.Alt) > 0) + { + pressedButton.Append("Alt + "); + } + if ((keyboardDevice.Modifiers & ModifierKeys.Shift) > 0) + { + pressedButton.Append("Shift + "); + } + + + // Filter modifier keys from being displayed twice (example: Control + LeftCtrl) + + if (Array.IndexOf(new [] { Key.LeftAlt, Key.RightAlt, + Key.LeftShift, Key.RightShift, + Key.LeftCtrl, Key.RightCtrl, + Key.LWin, Key.RWin, + Key.System}, args.Key) < 0) + { + pressedButton.Append(new KeyConverter().ConvertToInvariantString(args.Key)); + } + + return pressedButton.ToString(); + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs index 44f68e3e86..833a649880 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TextBlockBehavior.cs @@ -2,6 +2,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Documents; +using System.Windows.Media; namespace ICSharpCode.ShortcutsManagement { @@ -64,7 +65,11 @@ namespace ICSharpCode.ShortcutsManagement var matchedText = match.Groups[2].Value; if (!string.IsNullOrEmpty(matchedText)) { - textBlock.Inlines.Add(new Bold(new Run(matchedText))); + var matchedRun = new Run(matchedText); + + matchedRun.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#CEDEF7")); + matchedRun.Foreground = new SolidColorBrush((Color) ColorConverter.ConvertFromString("#000000")); + textBlock.Inlines.Add(matchedRun); } var matchedTextSuffix = match.Groups[3].Value; diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs index 5b0de181a2..8477b3584a 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Extensions/TreeViewExtensions.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using System.Windows.Controls; using System.Windows.Controls.Primitives; +using System.Windows.Input; namespace ICSharpCode.ShortcutsManagement { @@ -18,7 +19,7 @@ namespace ICSharpCode.ShortcutsManagement /// /// TreeView or TreeViewItem /// Path to the selected item - public static void SelectItem(this ItemsControl parentContainer, List path) + public static void SelectItem(this ItemsControl parentContainer, List path, bool setFocus) { var head = path.First(); var tail = path.GetRange(1, path.Count - 1); @@ -28,6 +29,11 @@ namespace ICSharpCode.ShortcutsManagement { itemContainer.IsSelected = true; + if(setFocus) + { + Keyboard.Focus(itemContainer); + } + var selectMethod = typeof(TreeViewItem).GetMethod("Select", BindingFlags.NonPublic | BindingFlags.Instance); selectMethod.Invoke(itemContainer, new object[] { true }); } @@ -39,12 +45,12 @@ namespace ICSharpCode.ShortcutsManagement { itemContainer.ItemContainerGenerator.StatusChanged += delegate { - SelectItem(itemContainer, tail); + SelectItem(itemContainer, tail, setFocus); }; } else { - SelectItem(itemContainer, tail); + SelectItem(itemContainer, tail, setFocus); } } } From 90b3d0fef8ebacc59b57d83f7a781e64a5d552b6 Mon Sep 17 00:00:00 2001 From: Sergej Andrejev Date: Thu, 4 Jun 2009 13:53:41 +0000 Subject: [PATCH 03/51] Shortcuts gestures management window git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4226 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../ShortcutsManagement.suo | Bin 66048 -> 70144 bytes .../Resources/16-square-red-remove.png | Bin 0 -> 311 bytes .../ShortcutsManagement/Resources/Thumbs.db | Bin 4608 -> 0 bytes .../Resources/add-smaller.png | Bin 0 -> 861 bytes .../ShortcutsManagement.csproj | 11 ++ .../Converters/BoolToVisibilityConverter.cs | 27 +++++ .../Src/Converters/GesturesListConverter.cs | 13 ++- .../Src/Converters/InputGestureConverter.cs | 33 ++++++ .../Src/Converters/ShortcutsTreeConverter.cs | 2 +- .../Src/Converters/TypeNameConverter.cs | 2 +- .../ShortcutsManagement/Src/Data/Shortcut.cs | 11 +- .../Src/Data/ShortcutsProvider.cs | 10 +- .../Src/Dialogs/ShortcutManagementWindow.xaml | 110 ++++++++++++++++++ .../Dialogs/ShortcutManagementWindow.xaml.cs | 63 ++++++++++ .../ShortcutsManagementOptionsPanel.xaml | 50 ++++---- .../ShortcutsManagementOptionsPanel.xaml.cs | 22 +++- 16 files changed, 315 insertions(+), 39 deletions(-) create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/16-square-red-remove.png delete mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/add-smaller.png create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/BoolToVisibilityConverter.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/InputGestureConverter.cs create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo index fc96421dd7a97a196443a286306a9bff0a02f5bb..e827e4fa7c739ea713d36898a83834cfbbd6477b 100644 GIT binary patch delta 5396 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 JPDHLkV1h&Sfqeh~ literal 0 HcmV?d00001 diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/Thumbs.db deleted file mode 100644 index 0aa333449aa3aa7515dabf3ac9fc0c1a7e503cd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4608 zcmeHK2~ZSA6z$m?mTO@TWIdK+O+ruv0}(Gg2q0Jz4iy0v6j+c$5mYp26qPHr2&fQ6 zNYogQBrdod3Sv+|LNoy-3M+)LTq=pW3%aZaO#UDm%NUDTl~g6gpLz3pdVWv;*T4JE zbX_g0^jDuYU;P^g-8I*p;Fsino#WHPmN^!2oLSUOCm9#@ZL zz~*o`TDm+#F56I_&0!NS!N|~tLe-#BHQ3rrZT8<5yd1F@FlPj0%mk5G7@39PmBc*4 zsNgN(@Q`36@R3GmXlOFQpb%CFMkbReWWsB(-VDzXg+6r5|LN z&dEQ|@wlQeo4jIeyoM&1XE@48IR34--!XsB#`gUwc2nm%eBkKhJkQ0`YvH2B-b;K| z1_lL-LPA$X$E;hwA$H@Y?K^fRBqk-NWbEFvH#6(geftj`{^H1&M~@vpaY|ZHSX6xa zOv#0c%BqXi-_?A7wf?7T*BcsTH{@;Y9i3e_Z{6-z_VnI=pz2dUd_?fV5cw&s=geN> z#R6U=3WZFe6TC3e1^}5wp&DD!^k=)%1ELH}thX`PbJ7pypVu&*?4jVSSbIg2YxbU8 zs3fQjG8-PT_%~wqoY)_{ZXhi(2Eikp^*$xk$QnWnYN=eL20PyFl7F=KM~~5MWglG&D{BgS0ybyzRn$9nSr*_sv_&kiFdAAwwPPxZX(OyJrtWgU%2?f z{%iJvHnx}=OnLv>E-Lc=ty=LTnexE^Jywb z%U>iDR)&dh;+*p#;2Y637QH$I8 zIO4~KJs#(#NG%)P)8aGl=7P*NGq2O)#tf-JpVxibR^!z>TlmFE<{?F=$>Xde?f0GB zF2A@fLLRZvzdo(WXSuK2^y}Rn)m@H?6M3E&4mkfjwL|oI6^?kTik2DHA1*x?>>OB9 zB=tz~ez^O`G{;HPcHe&WA8^D8ieJy=iEw1nR7Z+)OLDbLls@65;%JYX`|XC= zsH^boI{$_!?*;ibwK8GoScYuj&-25-eP;!2t&_);+B(IAlg+XWo#bPdkL!IuR(_9K zr$;F(Dt^(QDU;`D+qjmwIxBH{EixrDT{k(c)ridhM#i8zxPCFJ-Cbc%hoSigYkb}eg~*n!nyze diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/add-smaller.png b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Resources/add-smaller.png new file mode 100644 index 0000000000000000000000000000000000000000..61fce7bf0e583fdc6b5ea453a9d8d8bcae120f06 GIT binary patch literal 861 zcmV-j1ETziP)C-Vj1KOBQ5o=_-sVsCG6F_B2P0I;MP z3a6Wo2c3&&|!fxxKx;qXmP(I=|naa5x-rI-PL2TyVSHsHv%u@_0OHQg!yQ zmmYe_=<4e7YR%2f&+T@*EdCFW46-zz&-ck{wZdkzfyF;T4@*Z6y=0K3dA(lUVzDHF zDydq#zM&B(&vc{nYzVFG9r7A@rdCxzGRV?uYio70*$fsqC3SrouSbWl9D9$oS06C@ zEROnyKpKo5ddVP56DGa7x*8^v=}_pkTSM4JQS6>J~95d^$@o-}cvqJo4ZE7`!k@*dH#9+ecC4($Y6!fB^A`}-FqpYk< z9$p-X;NzFC(m4J&Cg5>QuEjASzDE}~@or}qBXjF;x;@fEFBxQMBC1|kSSSl6B_(oF z@WKGX_a9+!WC=G$R}dLnmEw1JWD$eI3+Rtdz+!Vs54~iNl?LP_HdyU0)E{j_!?AYs zT!|t)yexI~?i`xhgYvA_ACSXUx+GAns23Cz$O&q7m6Yprp6|zb?#qZgSiz(KUW!b>WVWTj)VfJvd3m{>pP!G+lxlsmNaPE&NO^n# z0sFOPW;!y+(!^R4sGzA}PFIN)K-G9f?4^{SEKS_SmeFVgm70_Wb*~Dd)>CH+ru<}S zIXOAK0<@o(mzSKRCjafNlKuAX3sxV0$c5S2*$blhLjVpGM5RbgnOaL3c0ex~WXZq1 nkWuKI&^@8Ce-u6Rl41A>^{YehNhpho00000NkvXXu0mjf@a>0Z literal 0 HcmV?d00001 diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj index bd922aeebe..738bf46fe1 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj @@ -85,6 +85,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -107,6 +111,8 @@ + + @@ -124,6 +130,9 @@ + + ShortcutManagementWindow.xaml + ShortcutsManagementOptionsPanel.xaml @@ -146,6 +155,8 @@ + + Always diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/BoolToVisibilityConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/BoolToVisibilityConverter.cs new file mode 100644 index 0000000000..9cb87bd41f --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/BoolToVisibilityConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Windows.Data; + +namespace ICSharpCode.ShortcutsManagement.Converters +{ + public class BoolToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if(value is bool) + { + return (bool) value ? "Visible" : "Hidden"; + } + + throw new System.NotImplementedException(); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new System.NotImplementedException(); + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs index 77a5ad67a0..a2f43b2816 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/GesturesListConverter.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Globalization; using System.Windows.Data; using System.Windows.Input; using ICSharpCode.Core.Presentation; -namespace ICSharpCode.ShortcutsManagement +namespace ICSharpCode.ShortcutsManagement.Converters { public class GesturesListConverter : IValueConverter { @@ -17,6 +18,16 @@ namespace ICSharpCode.ShortcutsManagement return new InputGestureCollectionConverter().ConvertToInvariantString(value); } + if (value is ObservableCollection && (targetType == typeof(string) || targetType.IsSubclassOf(typeof(string)))) + { + var inputGestureCollection = new InputGestureCollection(); + foreach (var gesture in (ObservableCollection)value) + { + inputGestureCollection.Add(gesture); + } + return new InputGestureCollectionConverter().ConvertToInvariantString(inputGestureCollection); + } + return value.ToString(); } diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/InputGestureConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/InputGestureConverter.cs new file mode 100644 index 0000000000..89a342de8a --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/InputGestureConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Windows.Input; + +namespace ICSharpCode.ShortcutsManagement.Converters +{ + public class InputGestureConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if(value is KeyGesture && targetType == typeof(string)) + { + return new KeyGestureConverter().ConvertToInvariantString(value).Replace("+", " + "); + } + + if(value is MouseGesture && targetType == typeof(string)) + { + return new MouseGestureConverter().ConvertToInvariantString(value).Replace("+", " + "); + } + + return ""; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new System.NotImplementedException(); + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/ShortcutsTreeConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/ShortcutsTreeConverter.cs index 3255d1466f..51c0e1d422 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/ShortcutsTreeConverter.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/ShortcutsTreeConverter.cs @@ -4,7 +4,7 @@ using System.Globalization; using System.Linq; using System.Windows.Data; -namespace ICSharpCode.ShortcutsManagement +namespace ICSharpCode.ShortcutsManagement.Converters { public class ShortcutsTreeConverter : IMultiValueConverter { diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/TypeNameConverter.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/TypeNameConverter.cs index eba1046599..bfa0fedf58 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/TypeNameConverter.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Converters/TypeNameConverter.cs @@ -2,7 +2,7 @@ using System.Globalization; using System.Windows.Data; -namespace ICSharpCode.ShortcutsManagement +namespace ICSharpCode.ShortcutsManagement.Converters { class TypeNameConverter : IValueConverter { diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs index 5a8416d963..5b43a0aae5 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows.Input; @@ -13,12 +14,13 @@ namespace ICSharpCode.ShortcutsManagement /// /// List of keyboard gestures which will invoke provided action /// - public InputGestureCollection Gestures + public ObservableCollection Gestures { get; private set; } + private string name; /// @@ -72,10 +74,13 @@ namespace ICSharpCode.ShortcutsManagement { IsVisible = true; Name = shortcutName; - Gestures = new InputGestureCollection(); + Gestures = new ObservableCollection(); if(gestures != null) { - Gestures.AddRange(gestures); + foreach (InputGesture gesture in gestures) + { + Gestures.Add(gesture); + } } } diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs index ed8b2527d7..5901ae7bba 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs @@ -7,13 +7,7 @@ using ICSharpCode.Core.Presentation; namespace ICSharpCode.ShortcutsManagement { - internal enum FilterType - { - Gesture, - Action - } - - internal class ShortcutsProvider + public class ShortcutsProvider { private readonly ObservableCollection addins = new ObservableCollection(); @@ -185,7 +179,7 @@ namespace ICSharpCode.ShortcutsManagement addins[1].Categories.Add(new ShortcutCategory("Uncategorized")); addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick find", GetGestures("Ctrl + F"))); addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick replace", GetGestures("Ctrl + H"))); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find in files", GetGestures("Ctrl + Shift + F"))); + addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find in files", GetGestures("Ctrl + Shift + F | Ctrl + Shift + H | Ctrl + I"))); addins[1].Categories[0].Shortcuts.Add(new Shortcut("Replace in files", GetGestures("Ctrl + Shift + H"))); addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find symbol", null)); diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml new file mode 100644 index 0000000000..4877529acf --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs new file mode 100644 index 0000000000..666ae7f42a --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace ICSharpCode.ShortcutsManagement +{ + /// + /// Interaction logic for ShortcutManagementWindow.xaml + /// + public partial class ShortcutManagementWindow : Window + { + private ShortcutsProvider shortcutsProvider; + private Shortcut shortcut; + private InputGesture lastEnteredInputGesture; + + public ShortcutManagementWindow(Shortcut shortcut, ShortcutsProvider provider) + { + DataContext = shortcut; + this.shortcut = shortcut; + shortcutsProvider = provider; + + InitializeComponent(); + } + + private void shortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e) + { + e.Handled = true; + + shortcutTextBox.Text = GesturesHelper.GetGestureFromKeyEventArgument(e); + + lastEnteredInputGesture = null; + try + { + lastEnteredInputGesture = new KeyGesture(e.Key, Keyboard.Modifiers); + } + catch (NotSupportedException) + { } + } + + private void removeGestureButton_Click(object sender, RoutedEventArgs e) + { + var tag = ((Button) sender).Tag as InputGesture; + shortcut.Gestures.Remove(tag); + } + + private void addGestureButton_Click(object sender, RoutedEventArgs e) + { + if(lastEnteredInputGesture != null) + { + shortcut.Gestures.Add(lastEnteredInputGesture); + } + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml index e96077e473..237bb944e9 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml @@ -3,15 +3,16 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:ShortcutsManagement="clr-namespace:ICSharpCode.ShortcutsManagement" + xmlns:ShortcutsManagement="clr-namespace:ICSharpCode.ShortcutsManagement" + xmlns:Converters="clr-namespace:ICSharpCode.ShortcutsManagement.Converters" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Padding="10" > - - - + + + ..\..\Resources\key_enter.png ..\..\Resources\key_enter_pressed.png @@ -67,10 +68,6 @@ - - - - @@ -112,6 +109,7 @@ + @@ -152,21 +150,25 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs index a5313a950b..1bb89edd11 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; +using System.Windows.Data; using System.Windows.Input; using ICSharpCode.SharpDevelop; @@ -23,7 +24,12 @@ namespace ICSharpCode.ShortcutsManagement { if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2) { - MessageBox.Show("Changing shortcut"); + if (shortcutsTreeView.SelectedItem is Shortcut) + { + var receiver = ((ShortcutsProvider)Resources["ShortcutsReceiver"]); + var shortcut = (Shortcut)shortcutsTreeView.SelectedItem; + new ShortcutManagementWindow(shortcut, receiver).ShowDialog(); + } } } @@ -56,6 +62,7 @@ namespace ICSharpCode.ShortcutsManagement // If Up/Down is pressed switch focus to shortcuts tree var keyboardDevice = (KeyboardDevice)e.Device; + if (keyboardDevice.Modifiers == ModifierKeys.None && Array.IndexOf(new[] { Key.Up, Key.Down }, e.Key) >= 0) { @@ -64,6 +71,19 @@ namespace ICSharpCode.ShortcutsManagement return; } + // If enter is pressed open shortcut configuration + if (keyboardDevice.Modifiers == ModifierKeys.None && e.Key == Key.Enter) + { + e.Handled = true; + if (shortcutsTreeView.SelectedItem is Shortcut) + { + var shortcut = (Shortcut) shortcutsTreeView.SelectedItem; + new ShortcutManagementWindow(shortcut, receiver).ShowDialog(); + } + + return; + } + if (searchTypeToggleButton.IsChecked.HasValue && !searchTypeToggleButton.IsChecked.Value) return; e.Handled = true; From 93b84b3b1ad5c2cd709e512ca6230ed1c13b05c0 Mon Sep 17 00:00:00 2001 From: Sergej Andrejev Date: Fri, 5 Jun 2009 15:47:58 +0000 Subject: [PATCH 04/51] Similar shortcuts list in shortcut management window git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4237 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../ShortcutsManagement.suo | Bin 70144 -> 67072 bytes .../ShortcutsManagement.csproj | 1 + .../Src/Data/KeyGestureTemplate.cs | 66 +++++++++++ .../ShortcutsManagement/Src/Data/Shortcut.cs | 44 ++++++- .../Src/Data/ShortcutsProvider.cs | 76 +++--------- .../Src/Dialogs/ShortcutManagementWindow.xaml | 18 +-- .../Dialogs/ShortcutManagementWindow.xaml.cs | 82 ++++++++++--- .../ShortcutsManagementOptionsPanel.xaml | 13 +-- .../ShortcutsManagementOptionsPanel.xaml.cs | 109 ++++++++++++++---- .../ShortcutsManagement/Window1.xaml | 8 +- .../ShortcutsManagement/Window1.xaml.cs | 42 ++++++- 11 files changed, 343 insertions(+), 116 deletions(-) create mode 100644 src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/KeyGestureTemplate.cs diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo index e827e4fa7c739ea713d36898a83834cfbbd6477b..b3911ea2e8d3f6e0e1245b2d488de4a3632f60f6 100644 GIT binary patch delta 4073 zcmbVPdr*|u75~n+-!8lC!{s6Ja$S%r5QRn1Dg{{u11J$t;v-cG2b&?8jv)m1%@I zgy#wA1aCqnVJ=}FM#*A*7Sq=&gr$U+2rJMc8&}82*+4a3uB37mVKu=*c$rX2uoBh~ z))Lkc$_eWU6@*H{CPEcq3}GXonovWiC8QAe*m^3d7>pST(RgWsuWRT#R%c{=N#FI!(;H$)3Wdu6ajkEZwrVv(;9V&z} z!6-~7M0(WosqSuFNY-0Pno-mvQIO~@AXt8d4y_r>qa^ItPePNv(XPu-hEbb)COJQ^ zb6BIBr_skbyv4kpf{qWzqOgt-(12tBS%GPjwm4}v^cMA~dB?zoXKL*gQkGA{g zq24EQvW1RLL6!m#gkO>Zca-Ub%SRG?zwf_4z~$VI+-6aDy4sH>`HxRJroE7aHeV}@ z#vgnaDnqH&y(qN$d9u#wzKHmi-g`2~;-`G`POTPtU!{U?D_*l zDO|@O{EPb)&9mc~YvEn6`E3hx1jqnW-VMZ%L$=`I^;vrT?|?!0bWy4KYoTr9!7MY* zibxR8iMTgn95zM7i`A}AH4k#`o~kf4hDiocH(yo3J^KWIRSTIgefGlC4G7mi!p;d1 z`1*F8Ja~Rq{Xf~Li4T=1t~#lWA&;-5?%WS`2>G8kpYnm3?2f4)@Y0P5M-wK9P)h@x zM#psT@$-ZdVuW;hS5j}GqGRWX?~7kFcB7R8Me zx6hdc>M|1fkERzz+nRk6u(zWZ8#}Vloa?|MM+BO0OBnOwXYA3vtH7?VngaGk zRz(SQxjq_e7rBBEor`)kUL@j&=w2E+7vGb|zR+G9%=kjS*9I`h zvJ9CIr=hLXX$%TnO|Uk4p;8yNXxai^AnIs`~Exvx!C506*IkgN+CLQP-u{?|Asy z3Acf1qyg-WGJq5NqUzd90DUWpv9U4`%PN(u!Lq>{O$;2~($y%yw*XfD=ZTo#D0!aU`PM68Kv{eM36!HW6XlOT+BgMa*A@mT`t{ z8EM>AJ2hf(x2)kAw})%2PjO@&b<>YD-?l(wd;+)1@FU`vq08HM(}m8XtxuW!Kai>5 zrstr=->BVb0(TYx!xCn|bqenkduuA^MYOi&DMLJb44tjnS|OSw<2|L;KWA%!5Ah2R zsoFx7P=3i0q2}({LhB30We0pw)cS%BPsgXA@8`YPyVrz8T}}LoNW|Vxeeu$A1BQ3q zz@ZFa`WUlvlz6#idofVVN^TwK$GCqC5dH9M zmQxll(_HlP-VptC$3@KJ*QoU;=(zKMuvv?ujCV^E?<1VO95h?ikG3tpPmq-CX8<#b3nmzu)0kFFmnW`VVAe;LCSz zo*F%;s5Mr=K1~!Ir_FxqEYDEUc`DmgT6=Odlc)pdQSLcBrDo2aY`F-=!JPXO@~Jp# z<$3E9jZZW*ofJ4|m=k(D(H=Qu9R3%?jl;_%mvJt78pn%sG8qSRohz_$jiGrNz%<0tF)|*7~W*OzFShxQxP_eOB zzlQcC2^*7YS#4*%3=K?$w)4I$^ zuZ15JFD=8VV@!J}Ru^ycoEUCBP92RD55J)i_{6-7agEgKF|j^7Mo1+;UrQS*bZw~e zsYEl9euM{4+xk?C@u{1O$Hd_E&0WrbK6`GHA0(k^TO`Y==mad^9C=U!;?YME9rFjd s@58S0tR@M_?WH(4*8GD6b#SD)N)Ge2z|+rIg4?e(f1*mnAXf_i1*<^TivR!s delta 3218 zcmai$dsNiN6~}+`+uy<>y9UsQleEbXro3Etx43ASegd4Xj9DD_=ip1erIJHk~T8ue13E1 z&YhXxyzU+6FBRtjr8!CVGfI*a02b0Ld9vRaNa0{9Rmj`yDUedZBe&ZvNQayO=7M=3 z6U+x$U;!9L6Eq1XVOfCE(*UCT87kI{8J&hw6<7_{fVE&9Ce%)EQK%oY%)e90o*3bXkcer=LRQ+SXZmC=I{~#E5~&O&|yi2WBt=SU@lkHX{e} zYAW{0)QPTzmfCy@*bXxJ-c>}gMVFyr3Dn-1Ko0*!bXsd8m;cV03arJLxzh8}vzWz3 z$f9otW>G9{lH$KnBSzmW6-n!*GT5pubxcD=u89=miXp2mjC6)%)i_@#79K--W~LR> z+(Q+{g?gb9bMsdD_@j{RM-Poz2FVw)_z`a?TvrSbD7@lHS`jo!YmDSnY}8JPa`isp}a9 z9ISiNK&K9-@c!LJjIL${(Wc**Kgkw9PEl_j<}5Nb)4C+J^{CD&XV-abos60)I2VlN~(?8?6~K0M)830_jRPY zZfdYUovWePEK5+fblW`k%8{t3%(r|0x@G*Tk|a7dKSNZF{NF0iF5#42 z&m7NFvz)S;?eK|*GTxsmv$JHDDDF>_E1UU?17a2z5!OFHw4VxdjP!2BY)V~F30X(m z>MY_!Bb}%2H_uUW?mbG)>!2?_oX(TdF31%7Ku>{PAz~5~v-pad@9mD;z=4Vl- zVkcLAw>}Ii;WoTymRw8kX}7fgY);SL4Bi0ryF%->RtRr_x4|Dk8+Zqt z1joT2!3iK7O*`@qa0C1#l4vyGzKs!DVpevCiPW3gH8A z3s6B(>WJHqYutZF-Usf2d$g-)iMlFMJ0+{`N)R8v>N;!cXl0G7nI=1{1V`=^IU7Rx zwIwk!^_AAp^tF1vbIp&3(JI?AdUQU7Z*;7YwUNCI=M?&6bJJ6sq~(%LT8W-#f=%#< zrSOjqM1V4U;}IuTL+e0kqeqID79%f#)n?=|s3}4`n1Hr}5}lY4MIZk|M;$F4sXA16 z-HX@72wUO1)(@%^u17?z#Xv*@ZyU8d$t-qJ?2XuWubw8A7gz^(E;@*U0q&m^GGIvd z;1KFw7^7B}%f}LUW#x88>e|HGMNHwg=elKn^Q%@x{r5Z;NbCpg(|_2b^kHXr}UAKARui9V-vv8u{~KFEVO< zVR>km<~oBH`#-)P{WLJDt$S&xzLxHL0B1V-0_{7pW+>aK&F2_dtrJ7%Dc?1&h&hxQ zUflR=*3^8TsrBj9skM`%{`)vlVPj}B9HxV zqr4{P0UW{p=x;U7qrBKDR8reTZVI9I$2ddHnwOpsT#3{;a_`*f+1v2ENU|+DP1YO> z0_d8r9rOzps(W2eRrY-PkoWNp^&>V!zkI3X8lzVuMmFA5=%^)}*Z0k2vX0S)^cq@l zz{-L-yWnPO8x~iwvtv}&mSbR%m}4~Xt|oW2=^5$ohvDtC^7B&VvA)KZ;&lMiU|ax1 z@?L0he+MV8UJ{R*$BCS^oaY}p!Ax_dIBZ9tYpm1&Z3^uUk!Nh4F;<)J8jmr_e+IsV}IUTre!%|mGpN|9X+t(>StXnnJ#^n z#)8SzYh`+#*jvmrV~5}6^|w}O8XwB^sjc2~6!_J9MuvAQ`{4&vZ=bF7Na@ml02oLK A3jhEB diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj index 738bf46fe1..1b9a682c65 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/ShortcutsManagement.csproj @@ -128,6 +128,7 @@ Settings.settings True + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/KeyGestureTemplate.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/KeyGestureTemplate.cs new file mode 100644 index 0000000000..b863269403 --- /dev/null +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/KeyGestureTemplate.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Input; + +namespace ICSharpCode.ShortcutsManagement +{ + public class KeyGestureTemplate + { + public Key Key + { + get; set; + } + + public ModifierKeys Modifiers + { + get; set; + } + + public KeyGestureTemplate(KeyGesture gesture) + { + Key = gesture.Key; + Modifiers = gesture.Modifiers; + } + + public KeyGestureTemplate(Key key, ModifierKeys modifiers) + { + Key = key; + Modifiers = modifiers; + } + + public KeyGestureTemplate(Key key) + { + Key = key; + Modifiers = ModifierKeys.None; + } + + public bool Matches(KeyGesture gesture, bool strictMatch) + { + if(strictMatch) + { + return Key == gesture.Key && Modifiers == gesture.Modifiers; + } + + var modifierMatches = gesture.Modifiers - (gesture.Modifiers ^ Modifiers) >= 0; + var keyMatches = Key == gesture.Key; + + if (Modifiers == ModifierKeys.None) + { + return keyMatches; + } + + if (Array.IndexOf(new[] { Key.LeftAlt, Key.RightAlt, + Key.LeftShift, Key.RightShift, + Key.LeftCtrl, Key.RightCtrl, + Key.LWin, Key.RWin, + Key.System}, Key) >= 0) + { + return modifierMatches; + } + + return modifierMatches && keyMatches; + } + } +} diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs index 5b43a0aae5..05eadd8c92 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/Shortcut.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; @@ -9,8 +10,10 @@ namespace ICSharpCode.ShortcutsManagement /// /// Shortcut /// - public class Shortcut : INotifyPropertyChanged + public class Shortcut : INotifyPropertyChanged, ICloneable { + private ObservableCollection gestures; + /// /// List of keyboard gestures which will invoke provided action /// @@ -82,6 +85,32 @@ namespace ICSharpCode.ShortcutsManagement Gestures.Add(gesture); } } + + Gestures.CollectionChanged += delegate { InvokePropertyChanged("Gestures"); }; + } + + public bool ContainsGesture(InputGesture gesture) + { + foreach (var existingGesture in Gestures) + { + if(existingGesture == gesture) + { + return true; + } + + if(existingGesture is KeyGesture && gesture is KeyGesture) + { + var existingKeyGesture = (KeyGesture) existingGesture; + var keyGesture = (KeyGesture) gesture; + + if(existingKeyGesture.Key == keyGesture.Key && existingKeyGesture.Modifiers == keyGesture.Modifiers) + { + return true; + } + } + } + + return false; } public event PropertyChangedEventHandler PropertyChanged; @@ -97,5 +126,16 @@ namespace ICSharpCode.ShortcutsManagement PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } + + public object Clone() + { + var clone = new Shortcut(Name, null); + foreach (var gesture in Gestures) + { + clone.Gestures.Add(gesture); + } + + return clone; + } } } diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs index 5901ae7bba..9614c5ede7 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Data/ShortcutsProvider.cs @@ -1,37 +1,34 @@ using System; +using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Globalization; -using System.Text.RegularExpressions; using System.Windows.Input; using ICSharpCode.Core.Presentation; namespace ICSharpCode.ShortcutsManagement { - public class ShortcutsProvider + public static class ShortcutsProvider { - private readonly ObservableCollection addins = new ObservableCollection(); - /// - /// Get list of add-ins containing shortcuts + /// Filter addins containing shortcuts with matching gesture /// - /// List of add-ins - public ObservableCollection GetAddIns() + /// Gesture template (Uncompleted gesture) + public static void FilterGesture(ICollection addins, KeyGestureTemplate keyGestureTemplate, bool strictMatch) { - return addins; + FilterGesture(addins, new List {keyGestureTemplate}, strictMatch); } /// /// Filter addins containing shortcuts with matching gesture /// - /// Key event - public void FilterGesture(InputEventArgs keyEventArgs) + /// Gesture template (Uncompleted gesture) + public static void FilterGesture(ICollection addins, ICollection keyGestureTemplateCollection, bool strictMatch) { foreach (var addIn in addins) { var subCategoryIsVisible = false; foreach (var category in addIn.Categories) { - if (FilterGesture(category, keyEventArgs)) + if (FilterGesture(category, keyGestureTemplateCollection, strictMatch)) { subCategoryIsVisible = true; } @@ -45,14 +42,14 @@ namespace ICSharpCode.ShortcutsManagement /// Filter categories containing shortcuts with matching gesture /// /// Category to filter - /// Key event + /// Uncompleted gesture /// - private static bool FilterGesture(ShortcutCategory category, InputEventArgs keyEventArgs) + private static bool FilterGesture(ShortcutCategory category, ICollection keyGestureTemplateCollection, bool strictMatch) { var isSubElementVisible = false; foreach (var subCategory in category.SubCategories) { - if (FilterGesture(subCategory, keyEventArgs)) + if (FilterGesture(subCategory, keyGestureTemplateCollection, strictMatch)) { isSubElementVisible = true; } @@ -63,10 +60,13 @@ namespace ICSharpCode.ShortcutsManagement var gestureMatched = false; foreach (InputGesture gesture in shortcut.Gestures) { - if(gesture.Matches(null, keyEventArgs)) + foreach (var template in keyGestureTemplateCollection) { - gestureMatched = true; - break; + if (template == null || (gesture is KeyGesture && template.Matches((KeyGesture)gesture, strictMatch))) + { + gestureMatched = true; + break; + } } } @@ -89,7 +89,7 @@ namespace ICSharpCode.ShortcutsManagement /// contains filter string /// /// Filter string - public void Filter(string filterString) + public static void Filter(ICollection addins, string filterString) { foreach (var addIn in addins) { @@ -149,43 +149,5 @@ namespace ICSharpCode.ShortcutsManagement return category.IsVisible = (forseMatch.HasValue && forseMatch.Value) || isSubElementVisible; } - - private static InputGestureCollection GetGestures(string gesturesString) - { - var converter = new InputGestureCollectionConverter(); - return (InputGestureCollection)converter.ConvertFromInvariantString(gesturesString); - } - - public ShortcutsProvider() - { - // Test data - addins.Add(new AddIn("SharpDevelop")); - addins[0].Categories.Add(new ShortcutCategory("Editing")); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Copy", GetGestures("Ctrl + C"))); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Paste", GetGestures("Ctrl + V | Ctrl+Insert"))); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Cut", GetGestures("Ctrl + X"))); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Undo", GetGestures("Ctrl + Z"))); - addins[0].Categories[0].Shortcuts.Add(new Shortcut("Redo", GetGestures("Ctrl + Y"))); - addins[0].Categories.Add(new ShortcutCategory("Building")); - addins[0].Categories[1].Shortcuts.Add(new Shortcut("Build", GetGestures("Ctrl + Shift+B"))); - addins[0].Categories[1].Shortcuts.Add(new Shortcut("Run", GetGestures("F5"))); - addins[0].Categories[1].Shortcuts.Add(new Shortcut("Run without debuger", GetGestures("Ctrl + F5"))); - addins[0].Categories[1].Shortcuts.Add(new Shortcut("Attach debuger", GetGestures("Ctrl + F8"))); - addins[0].Categories.Add(new ShortcutCategory("Uncategorized")); - addins[0].Categories[2].Shortcuts.Add(new Shortcut("Attach debuger", GetGestures("Ctrl + F8"))); - - - addins.Add(new AddIn("Search & replace")); - addins[1].Categories.Add(new ShortcutCategory("Uncategorized")); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick find", GetGestures("Ctrl + F"))); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Quick replace", GetGestures("Ctrl + H"))); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find in files", GetGestures("Ctrl + Shift + F | Ctrl + Shift + H | Ctrl + I"))); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Replace in files", GetGestures("Ctrl + Shift + H"))); - addins[1].Categories[0].Shortcuts.Add(new Shortcut("Find symbol", null)); - - addins.Add(new AddIn("Unspecified")); - addins[2].Categories.Add(new ShortcutCategory("Uncategorized")); - addins[2].Categories[0].Shortcuts.Add(new Shortcut("Test regex expression", null)); - } } } diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml index 4877529acf..d57e15ab26 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml @@ -4,11 +4,10 @@ xmlns:ShortcutsManagement="clr-namespace:ICSharpCode.ShortcutsManagement" xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:Converters="clr-namespace:ICSharpCode.ShortcutsManagement.Converters" - Title="{Binding Path=Name}" Height="300" Width="300"> + Title="{Binding Path=Name}" MinHeight="400" MinWidth="400"> - @@ -25,9 +24,8 @@ - - - + + @@ -50,7 +48,7 @@ - + @@ -93,8 +91,10 @@ - + + + @@ -102,8 +102,8 @@ - - + + diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs index 666ae7f42a..fcfd8dec8d 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml.cs @@ -1,15 +1,8 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; namespace ICSharpCode.ShortcutsManagement { @@ -18,17 +11,56 @@ namespace ICSharpCode.ShortcutsManagement /// public partial class ShortcutManagementWindow : Window { - private ShortcutsProvider shortcutsProvider; - private Shortcut shortcut; - private InputGesture lastEnteredInputGesture; + private Shortcut shortcutCopy; + + public Shortcut ModifiedShortcut + { + get; private set; + } + + public bool IsShortcutModified + { + get; private set; + } - public ShortcutManagementWindow(Shortcut shortcut, ShortcutsProvider provider) + private ICollection AddIns { - DataContext = shortcut; - this.shortcut = shortcut; - shortcutsProvider = provider; + get; set; + } + + private InputGesture lastEnteredInputGesture; + public ShortcutManagementWindow(Shortcut shortcut, ICollection addIns) + { + shortcutCopy = (Shortcut)shortcut.Clone(); + shortcutCopy.Gestures.CollectionChanged += Gestures_CollectionChanged; + DataContext = shortcutCopy; + InitializeComponent(); + + AddIns = addIns; + shortcutsManagementOptionsPanel.DataContext = AddIns; + FilterSimilarShortcuts(); + shortcutsManagementOptionsPanel.shortcutsTreeView.SetExpandAll(true); + } + + void Gestures_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + FilterSimilarShortcuts(); + } + + private void FilterSimilarShortcuts() + { + var templates = new List(); + foreach (var gesture in shortcutCopy.Gestures) + { + if (gesture is KeyGesture) + { + templates.Add(new KeyGestureTemplate((KeyGesture)gesture)); + } + } + + ShortcutsProvider.FilterGesture(AddIns, templates, true); } private void shortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e) @@ -45,19 +77,33 @@ namespace ICSharpCode.ShortcutsManagement catch (NotSupportedException) { } } - + private void removeGestureButton_Click(object sender, RoutedEventArgs e) { var tag = ((Button) sender).Tag as InputGesture; - shortcut.Gestures.Remove(tag); + shortcutCopy.Gestures.Remove(tag); } private void addGestureButton_Click(object sender, RoutedEventArgs e) { - if(lastEnteredInputGesture != null) + if(lastEnteredInputGesture != null && !shortcutCopy.ContainsGesture(lastEnteredInputGesture)) { - shortcut.Gestures.Add(lastEnteredInputGesture); + shortcutCopy.Gestures.Add(lastEnteredInputGesture); } } + + private void saveButton_Click(object sender, RoutedEventArgs e) + { + IsShortcutModified = true; + ModifiedShortcut = shortcutCopy; + + Close(); + } + + private void resetButton_Click(object sender, RoutedEventArgs e) + { + IsShortcutModified = false; + Close(); + } } } diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml index 237bb944e9..c743cbd8f5 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml @@ -6,10 +6,9 @@ xmlns:ShortcutsManagement="clr-namespace:ICSharpCode.ShortcutsManagement" xmlns:Converters="clr-namespace:ICSharpCode.ShortcutsManagement.Converters" mc:Ignorable="d" - d:DesignHeight="300" d:DesignWidth="300" Padding="10" > + d:DesignHeight="300" d:DesignWidth="300" > - @@ -17,8 +16,6 @@ ..\..\Resources\key_enter.png ..\..\Resources\key_enter_pressed.png - - @@ -66,10 +63,10 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml index be6ab8451c..507d267260 100644 --- a/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml +++ b/src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutManagementWindow.xaml @@ -2,85 +2,54 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ShortcutsManagement="clr-namespace:ICSharpCode.ShortcutsManagement" - xmlns:Converters="clr-namespace:ICSharpCode.ShortcutsManagement.Converters" - Title="{Binding Path=Name}" MinHeight="400" MinWidth="400"> + xmlns:core="http://icsharpcode.net/sharpdevelop/core" + Title="{Binding Text}" MinHeight="400" MinWidth="400"> - - - - - - - + + + + + - + - - + + - - - - + +