Browse Source

Add support of bindings associated with whole type. Add named types and instances. Named instances and types can be used before the instance or class associated with the name is loaded

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4314 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts^2
Sergej Andrejev 16 years ago
parent
commit
d7f200ab01
  1. 4
      AddIns/ICSharpCode.SharpDevelop.addin
  2. 21
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  3. BIN
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo
  4. 11
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
  5. 18
      src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
  6. 19
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs
  7. 20
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
  8. 25
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
  9. 14
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDescriptor.cs
  10. 14
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDescriptor.cs
  11. 6
      src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs
  12. 138
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs
  13. 694
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs
  14. 33
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
  15. 246
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
  16. 18
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
  17. 3
      src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs

4
AddIns/ICSharpCode.SharpDevelop.addin

@ -130,7 +130,9 @@ @@ -130,7 +130,9 @@
command="SDBuildCommands.BuildSolution"
class="ICSharpCode.SharpDevelop.Project.Commands.Build"
gestures="F8"
category="Building" />
category="Building"
owner-instance="ICSharpCode.SharpDevelop.Gui.ClassBrowser.ClassBrowserPad"
/>
<CommandBinding
command="SDBuildCommands.RebuildSolution"
class="ICSharpCode.SharpDevelop.Project.Commands.Rebuild"

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

@ -119,30 +119,13 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -119,30 +119,13 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
var contextName = this.GetType().FullName;
CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, this, delegate {
var newBindings = CommandsRegistry.FindCommandBindings(contextName, this, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(newBindings);
});
CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, this, delegate {
var newBindings = CommandsRegistry.FindInputBindings(contextName, this, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(newBindings);
});
var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.ContextName = contextName;
commandBindingInfo.Context = this;
commandBindingInfo.OwnerInstance = this;
commandBindingInfo.RoutedCommandName = "SDWindowCommands.SplitView";
commandBindingInfo.ExecutedEventHandler = OnSplitView;
commandBindingInfo.CanExecutedEventHandler = OnCanSplitView;
commandBindingInfo.CanExecutedEventHandler = OnCanSplitView;
CommandsRegistry.RegisterCommandBinding(commandBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, this);
CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, this);
textMarkerService = new TextMarkerService(this);
iconBarManager = new IconBarManager();

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

Binary file not shown.

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

@ -45,7 +45,7 @@ namespace ICSharpCode.ShortcutsManagement @@ -45,7 +45,7 @@ namespace ICSharpCode.ShortcutsManagement
rootEntries.Add(unspecifiedAddInSection);
// Go through all input bindings
var inputBindingInfos = CommandsRegistry.FindInputBindingInfos(null, null, null);
var inputBindingInfos = CommandsRegistry.FindInputBindingInfos(null, null, null, null, null);
foreach(var inputBindingInfo in inputBindingInfos) {
// Find appropriate or create new add-in section for input binding
ShortcutManagement.AddIn addinSection;
@ -156,10 +156,17 @@ namespace ICSharpCode.ShortcutsManagement @@ -156,10 +156,17 @@ namespace ICSharpCode.ShortcutsManagement
var shortcut = pair.Key;
var inputBindingInfo = pair.Value;
if (inputBindingInfo.Gestures.Count == shortcut.Gestures.Count) {
foreach (var gesture in shortcut.Gestures) {
inputBindingInfo.Gestures.ContainsCopy(gesture);
}
} else {
inputBindingInfo.IsModifyed = true;
}
inputBindingInfo.Gestures = new InputGestureCollection(shortcut.Gestures);
}
CommandsRegistry.InvokeInputBindingUpdateHandlers(null, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers();
return true;
}

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

@ -483,7 +483,7 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -483,7 +483,7 @@ namespace ICSharpCode.SharpDevelop.Commands
var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.ClassName = routedCommandName;
commandBindingInfo.ContextName = CommandsRegistry.DefaultContextName;
commandBindingInfo.OwnerType = typeof(WpfWorkbench);
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.AddIn = addIn;
@ -491,10 +491,15 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -491,10 +491,15 @@ namespace ICSharpCode.SharpDevelop.Commands
// If pad have shortcut specified add input binding
if (!string.IsNullOrEmpty(padContent.Shortcut)) {
CommandsRegistry.RegisterClassInputBindingsUpdateHandler(CommandsRegistry.DefaultContextName, delegate {
var updatedGestures = CommandsRegistry.FindInputGestures(CommandsRegistry.DefaultContextName, null, null, null, routedCommandName);
item.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
});
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(padContent.Shortcut);
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.ContextName = CommandsRegistry.DefaultContextName;
inputBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = gestures;
inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories("Menu Items/Views"));
@ -505,15 +510,6 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -505,15 +510,6 @@ namespace ICSharpCode.SharpDevelop.Commands
bindingsAssigned.Add(routedCommandName);
}
CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
var updatedGestures = CommandsRegistry.FindInputGestures(CommandsRegistry.DefaultContextName, null, routedCommandName);
item.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
item.Command = CommandsRegistry.GetRoutedUICommand(routedCommandName);

19
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs

@ -88,24 +88,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -88,24 +88,7 @@ namespace ICSharpCode.SharpDevelop.Gui
placeholder = null;
var contextName = padInstance.GetType().FullName;
CommandsRegistry.LoadContext(contextName, (UIElement)Content);
CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, delegate {
var newBindings = CommandsRegistry.FindCommandBindings(contextName, null, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(newBindings);
});
CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, delegate {
var newBindings = CommandsRegistry.FindInputBindings(contextName, null, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(newBindings);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null);
CommandsRegistry.RegisterNamedUIElementInstance(contextName, (UIElement)Content);
}
}
}

20
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs

@ -93,24 +93,8 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -93,24 +93,8 @@ namespace ICSharpCode.SharpDevelop.Gui
CommandManager.InvalidateRequerySuggested();
if (newActiveViewContent != null) {
string contextName = newActiveViewContent.GetType().FullName;
CommandsRegistry.LoadContext(contextName, (UIElement)Content);
CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, delegate {
var newBindings = CommandsRegistry.FindCommandBindings(contextName, null, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(newBindings);
});
CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, delegate {
var newBindings = CommandsRegistry.FindInputBindings(contextName, null, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(newBindings);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null);
string ownerName = newActiveViewContent.GetType().FullName;
CommandsRegistry.RegisterNamedUIElementInstance(ownerName, (UIElement)Content);
}
}

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

@ -80,7 +80,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -80,7 +80,7 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
CommandsRegistry.DefaultContextName = this.GetType().Name;
CommandsRegistry.DefaultContextName = this.GetType().AssemblyQualifiedName;
CommandsService.RegisterBuiltInRoutedUICommands();
@ -92,20 +92,17 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -92,20 +92,17 @@ namespace ICSharpCode.SharpDevelop.Gui
// Register context and load all commands from addin
CommandsRegistry.LoadAddinCommands(AddInTree.AddIns.FirstOrDefault(a => a.Name == "SharpDevelop"));
CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
var newBindings = CommandsRegistry.FindCommandBindings(CommandsRegistry.DefaultContextName, null, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(newBindings);
});
//CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
// var newBindings = CommandsRegistry.FindCommandBindings(CommandsRegistry.DefaultContextName, null, null, null);
// CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
// CommandBindings.AddRange(newBindings);
//});
CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
var newBindings = CommandsRegistry.FindInputBindings(null, null, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(newBindings);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
//CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
// var newBindings = CommandsRegistry.FindInputBindings(null, null, null);
// CommandsRegistry.RemoveManagedInputBindings(InputBindings);
// InputBindings.AddRange(newBindings);
//});
mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath);

14
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDescriptor.cs

@ -38,12 +38,11 @@ namespace ICSharpCode.Core @@ -38,12 +38,11 @@ namespace ICSharpCode.Core
get; private set;
}
/// <summary>
/// Full name of context class.
///
/// UI element in which this binding will be valid
/// </summary>
public string Context {
public string OwnerInstanceName {
get; private set;
}
public string OwnerTypeName {
get; private set;
}
@ -86,7 +85,8 @@ namespace ICSharpCode.Core @@ -86,7 +85,8 @@ namespace ICSharpCode.Core
Class = Codon.Properties["class"];
Command = Codon.Properties["command"];
CommandText = Codon.Properties["commandtext"];
Context = Codon.Properties["context"];
OwnerInstanceName = Codon.Properties["owner-instance"];
OwnerTypeName = Codon.Properties["owner-type"];
Gestures = Codon.Properties["gestures"];
Category = Codon.Properties["category"];
}

14
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDescriptor.cs

@ -28,12 +28,11 @@ namespace ICSharpCode.Core @@ -28,12 +28,11 @@ namespace ICSharpCode.Core
get; private set;
}
/// <summary>
/// Full name of context class.
///
/// UI element in which this binding will be valid
/// </summary>
public string Context {
public string OwnerInstanceName {
get; private set;
}
public string OwnerTypeName {
get; private set;
}
@ -60,7 +59,8 @@ namespace ICSharpCode.Core @@ -60,7 +59,8 @@ namespace ICSharpCode.Core
Codon = codon;
Command = codon.Properties["command"];
CommandText = codon.Properties["commandtext"];
Context = codon.Properties["context"];
OwnerInstanceName = codon.Properties["owner-instance"];
OwnerTypeName = codon.Properties["owner-type"];
Gestures = codon.Properties["gestures"];
Category = codon.Properties["category"];
}

6
src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs

@ -84,6 +84,10 @@ namespace ICSharpCode.Core @@ -84,6 +84,10 @@ namespace ICSharpCode.Core
// preload assembly to provoke FileLoadException if dependencies are missing
loadedAssembly.GetExportedTypes();
#endif
if(Loaded != null) {
Loaded(this, null);
}
} catch (FileNotFoundException ex) {
MessageService.ShowError("The addin '" + assembly + "' could not be loaded:\n" + ex.ToString());
} catch (FileLoadException ex) {
@ -92,6 +96,8 @@ namespace ICSharpCode.Core @@ -92,6 +96,8 @@ namespace ICSharpCode.Core
}
}
public event EventHandler Loaded;
public Assembly LoadedAssembly {
get {
Load(); // load the assembly, if not already done

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

@ -8,12 +8,12 @@ namespace ICSharpCode.Core.Presentation @@ -8,12 +8,12 @@ namespace ICSharpCode.Core.Presentation
/// Stores details about command binding
/// </summary>
public class CommandBindingInfo
{
private UIElement contextInstance;
{
public CommandBindingInfo()
{
ContextName = CommandsRegistry.DefaultContextName;
IsModifyed = true;
OldCommandBindings = new CommandBindingCollection();
NewCommandBindings = new CommandBindingCollection();
}
/// <summary>
@ -90,28 +90,105 @@ namespace ICSharpCode.Core.Presentation @@ -90,28 +90,105 @@ namespace ICSharpCode.Core.Presentation
}
/// <summary>
/// Name of the class which owns this binding
/// Store name of object owning this binding (can only be used with named objects)
///
/// Named objects can be registered throgut <see cref="CommandsRegistry.RegisterNamedUIElementInstance" />
/// </summary>
public string OwnerInstanceName{
get; set;
}
private UIElement ownerInstance;
/// <summary>
/// Stores instance of object which is owning this binding
/// </summary>
public UIElement OwnerInstance{
get {
if(OwnerInstanceName != null && ownerInstance == null) {
ownerInstance = CommandsRegistry.GetNamedUIElementInstance(OwnerInstanceName);
}
return ownerInstance;
}
set {
ownerInstance = value;
}
}
/// <summary>
/// Assembly qualified name of the class owning this instance
///
/// Named type can be registered throgut <see cref="CommandsRegistry.RegisterNamedUIType" />
/// </summary>
public string ContextName{
public string OwnerTypeName{
get; set;
}
private Type ownerType;
/// <summary>
/// Instance of class which owns this binding
/// Stores type owning this binding
/// </summary>
public UIElement Context {
public Type OwnerType {
set {
contextInstance = value;
ownerType = value;
}
get {
if(contextInstance != null) {
return contextInstance;
} else {
UIElement context;
CommandsRegistry.contexts.TryGetValue(ContextName, out context);
return context;
if(ownerType == null && OwnerTypeName != null) {
ownerType = Type.GetType(OwnerTypeName);
CommandsRegistry.RegisterNamedUIType(OwnerTypeName, ownerType);
}
return ownerType;
}
}
/// <summary>
/// Default binding update handler update owner or type bindings (depending on input binding info type)
/// so they would always contain latest version
/// </summary>
private BindingsUpdatedHandler defaultCommandBindingHandler;
/// <summary>
/// Default command binding handler. Updates command binding if binding info changes
/// </summary>
internal BindingsUpdatedHandler DefaultCommandBindingHandler
{
get {
if(defaultCommandBindingHandler == null && (OwnerTypeName != null || OwnerType != null)) {
defaultCommandBindingHandler = delegate {
if(OwnerType != null && IsModifyed) {
GenerateCommandBindings();
foreach(ManagedCommandBinding binding in OldCommandBindings) {
CommandsRegistry.RemoveClassCommandBinding(OwnerType, binding);
}
foreach(ManagedCommandBinding binding in NewCommandBindings) {
CommandManager.RegisterClassCommandBinding(OwnerType, binding);
}
IsModifyed = false;
}
};
} else if(defaultCommandBindingHandler == null && (OwnerInstanceName != null || OwnerInstance != null)) {
defaultCommandBindingHandler = delegate {
if(OwnerInstance != null && IsModifyed) {
GenerateCommandBindings();
foreach(ManagedCommandBinding binding in OldCommandBindings) {
OwnerInstance.CommandBindings.Remove(binding);
}
OwnerInstance.CommandBindings.AddRange(NewCommandBindings);
IsModifyed = false;
}
};
}
return defaultCommandBindingHandler;
}
}
@ -136,6 +213,35 @@ namespace ICSharpCode.Core.Presentation @@ -136,6 +213,35 @@ namespace ICSharpCode.Core.Presentation
{
get; set;
}
/// <summary>
/// Indicates that generated command bindings are modified from last access
/// </summary>
public bool IsModifyed {
get; set;
}
public void GenerateCommandBindings()
{
OldCommandBindings = NewCommandBindings;
var managedCommandBinding = new ManagedCommandBinding(RoutedCommand);
managedCommandBinding.CanExecute += GeneratedCanExecuteEventHandler;
managedCommandBinding.Executed += GeneratedExecutedEventHandler;
NewCommandBindings = new CommandBindingCollection();
NewCommandBindings.Add(managedCommandBinding);
}
internal CommandBindingCollection OldCommandBindings
{
get; set;
}
internal CommandBindingCollection NewCommandBindings
{
get; set;
}
internal void GeneratedExecutedEventHandler(object sender, ExecutedRoutedEventArgs e) {
if(ExecutedEventHandler != null) {

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

@ -7,6 +7,8 @@ using System.Threading; @@ -7,6 +7,8 @@ using System.Threading;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
using System.Reflection;
using System.Collections.Specialized;
namespace ICSharpCode.Core.Presentation
{
@ -31,18 +33,111 @@ namespace ICSharpCode.Core.Presentation @@ -31,18 +33,111 @@ namespace ICSharpCode.Core.Presentation
get; set;
}
// Binding infos
private static List<CommandBindingInfo> commandBindings = new List<CommandBindingInfo>();
private static List<InputBindingInfo> inputBidnings = new List<InputBindingInfo>();
// Commands
private static Dictionary<string, RoutedUICommand> routedCommands = new Dictionary<string, RoutedUICommand>();
internal static Dictionary<string, System.Windows.Input.ICommand> commands = new Dictionary<string, System.Windows.Input.ICommand>();
internal static Dictionary<string, UIElement> contexts = new Dictionary<string, UIElement>();
private static Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>> commandBindingsUpdateHandlers = new Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>>();
private static Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>> inputBindingsUpdateHandlers = new Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>>();
// Update hanlers
private static Dictionary<string, List<BindingsUpdatedHandler>> classCommandBindingUpdateHandlers = new Dictionary<string, List<BindingsUpdatedHandler>>();
private static Dictionary<object, List<BindingsUpdatedHandler>> instanceCommandBindingUpdateHandlers = new Dictionary<object, List<BindingsUpdatedHandler>>();
private static Dictionary<string, List<BindingsUpdatedHandler>> classInputBindingUpdateHandlers = new Dictionary<string, List<BindingsUpdatedHandler>>();
private static Dictionary<object, List<BindingsUpdatedHandler>> instanceInputBindingUpdateHandlers = new Dictionary<object, List<BindingsUpdatedHandler>>();
// Named instances and types
private static Dictionary<string, UIElement> namedUIInstances = new Dictionary<string, UIElement>();
private static Dictionary<string, Type> namedUITypes = new Dictionary<string, Type>();
// Categories
private static List<InputBindingCategory> categories = new List<InputBindingCategory>();
/// <summary>
/// Register UI element instance accessible by unique name
/// </summary>
/// <param name="instanceName">Instance name</param>
/// <param name="element">Instance</param>
public static void RegisterNamedUIElementInstance(string instanceName, UIElement element)
{
if(!namedUIInstances.ContainsKey(instanceName)){
namedUIInstances.Add(instanceName, element);
// If there are some bindings and update handlers already registered,
// but owner is not loaded then move these to arrays which holds bindings
// and update handlers of loaded instances
if(instanceCommandBindingUpdateHandlers.ContainsKey(instanceName)) {
foreach(var handler in instanceCommandBindingUpdateHandlers[instanceName]) {
RegisterInstanceCommandBindingsUpdateHandler(element, handler);
}
instanceCommandBindingUpdateHandlers.Remove(instanceName);
InvokeInstanceCommandBindingUpdateHandlers(element);
foreach(var handler in instanceInputBindingUpdateHandlers[instanceName]) {
RegisterInstanceInputBindingsUpdateHandler(element, handler);
}
instanceInputBindingUpdateHandlers.Remove(instanceName);
InvokeInstanceInputBindingUpdateHandlers(element);
}
}
}
/// <summary>
/// Get instance by unique instance name
/// </summary>
/// <param name="instanceName">Instance name</param>
/// <returns></returns>
public static UIElement GetNamedUIElementInstance(string instanceName)
{
UIElement instance;
namedUIInstances.TryGetValue(instanceName, out instance);
return instance;
}
/// <summary>
/// Register UI type which can be accessible by name
/// </summary>
/// <param name="typeName">Type name</param>
/// <param name="type">Type</param>
public static void RegisterNamedUIType(string typeName, Type type)
{
if(!namedUITypes.ContainsKey(typeName)){
namedUITypes.Add(typeName, type);
// If any bindings or update handlers where assigned to the type
// before it was loaded using unique name move these to array
// holding type bindings and update handlers
if(classCommandBindingUpdateHandlers.ContainsKey(typeName)) {
foreach(var handler in classCommandBindingUpdateHandlers[typeName]) {
RegisterClassCommandBindingsUpdateHandler(type, handler);
}
classCommandBindingUpdateHandlers.Remove(typeName);
InvokeClassCommandBindingUpdateHandlers(type);
foreach(var handler in classInputBindingUpdateHandlers[typeName]) {
RegisterClassInputBindingsUpdateHandler(type, handler);
}
classInputBindingUpdateHandlers.Remove(typeName);
InvokeClassInputBindingUpdateHandlers(type);
}
}
}
/// <summary>
/// Get type by uniqe type name
/// </summary>
/// <param name="typeName">Type name</param>
/// <returns>Type</returns>
public static Type GetNamedUIType(string typeName)
{
Type instance;
namedUITypes.TryGetValue(typeName, out instance);
return instance;
}
/// <summary>
/// Get reference to routed UI command by name
/// </summary>
@ -121,7 +216,14 @@ namespace ICSharpCode.Core.Presentation @@ -121,7 +216,14 @@ namespace ICSharpCode.Core.Presentation
public static void RegisterInputBinding(InputBindingInfo inputBindingInfo)
{
inputBidnings.Add(inputBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(inputBindingInfo.ContextName, null);
if(inputBindingInfo.OwnerTypeName != null || inputBindingInfo.OwnerType != null) {
RegisterClassDefaultInputBindingHandler(inputBindingInfo);
} else if (inputBindingInfo.OwnerInstanceName != null || inputBindingInfo.OwnerInstance != null) {
RegisterInstaceDefaultInputBindingHandler(inputBindingInfo);
} else {
throw new ArgumentException("Binding owner must be specified");
}
}
/// <summary>
@ -134,233 +236,371 @@ namespace ICSharpCode.Core.Presentation @@ -134,233 +236,371 @@ namespace ICSharpCode.Core.Presentation
}
/// <summary>
/// Find input input bindings which satisfy provided arguments
/// Find input input binding infos which satisfy provided arguments
///
/// Null arguments are ignored
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Unregister binding assigned to specific context instance</param>
/// <param name="routedCommandName">Routed UI command name</param>
public static ICollection<InputBindingInfo> FindInputBindingInfos(string contextName, UIElement contextInstance, string routedCommandName) {
public static ICollection<InputBindingInfo> FindInputBindingInfos(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName) {
var foundBindings = new List<InputBindingInfo>();
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)) {
foundBindings.Add(inputBidnings[i]);
foreach(var binding in inputBidnings) {
if( (ownerInstanceName == null || binding.OwnerInstanceName == ownerInstanceName)
&& (ownerInstance == null || binding.OwnerInstance == ownerInstance)
&& (ownerTypeName == null || binding.OwnerTypeName == ownerTypeName)
&& (ownerType == null || binding.OwnerType == ownerType)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName)) {
foundBindings.Add(binding);
}
}
return foundBindings;
}
/// <summary>
/// Register delegate which will be invoked on change in input bindings in specified context
/// Remove input binding associated with type
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Register update handler which will trigger only if input bindings registered for this object where triggered</param>
/// <param name="handler">Update handler delegate</param>
public static void RegisterInputBindingUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) {
if(contextInstance == null) {
contextInstance = NullUIElement;
/// <param name="ownerType">Owner type</param>
/// <param name="inputBinding">Input binding</param>
public static void RemoveClassInputBinding(Type ownerType, InputBinding inputBinding)
{
var fieldInfo = typeof(CommandManager).GetField("_classInputBindings", BindingFlags.Static | BindingFlags.NonPublic);
var fieldData = (HybridDictionary)fieldInfo.GetValue(null);
var classInputBindings = (InputBindingCollection)fieldData[ownerType];
if(classInputBindings != null) {
classInputBindings.Remove(inputBinding);
}
if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) {
inputBindingsUpdateHandlers.Add(contextName, new Dictionary<UIElement, List<BindingsUpdatedHandler>>());
}
/// <summary>
/// Remove command binding associated with type
/// </summary>
/// <param name="ownerType"></param>
/// <param name="commandBinding"></param>
public static void RemoveClassCommandBinding(Type ownerType, CommandBinding commandBinding)
{
var fieldInfo = typeof(CommandManager).GetField("_classCommandBindings", BindingFlags.Static | BindingFlags.NonPublic);
var fieldData = (HybridDictionary)fieldInfo.GetValue(null);
var classCommandBindings = (CommandBindingCollection)fieldData[ownerType];
if(classCommandBindings != null) {
classCommandBindings.Remove(commandBinding);
}
}
/// <summary>
/// Register command binding by specifying command binding parameters
/// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void RegisterCommandBinding(CommandBindingInfo commandBindingInfo) {
commandBindings.Add(commandBindingInfo);
commandBindingInfo.GenerateCommandBindings();
if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
inputBindingsUpdateHandlers[contextName].Add(contextInstance, new List<BindingsUpdatedHandler>());
if(commandBindingInfo.OwnerTypeName != null || commandBindingInfo.OwnerType != null) {
RegisterClassDefaultCommandBindingHandler(commandBindingInfo);
} else if (commandBindingInfo.OwnerInstanceName != null || commandBindingInfo.OwnerInstance != null) {
RegisterInstaceDefaultCommandBindingHandler(commandBindingInfo);
} else {
throw new ArgumentException("Binding owner must be specified");
}
inputBindingsUpdateHandlers[contextName][contextInstance].Add(handler);
}
/// <summary>
/// Remove input bindings update handler
/// Unregister command binding
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Unregister update handler which was triggered only if input bindings registered for specific instance where updated</param>
/// <param name="handler">Update handler delegate</param>
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);
}
}
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void UnregisterCommandBinding(CommandBindingInfo commandBindingInfo) {
commandBindings.Remove(commandBindingInfo);
// Remove command bindings
if(commandBindingInfo.OwnerType != null) {
foreach(ManagedCommandBinding binding in commandBindingInfo.OldCommandBindings) {
RemoveClassCommandBinding(commandBindingInfo.OwnerType, binding);
}
foreach(ManagedCommandBinding binding in commandBindingInfo.NewCommandBindings) {
RemoveClassCommandBinding(commandBindingInfo.OwnerType, binding);
}
} else if (commandBindingInfo.OwnerInstance != null) {
foreach(ManagedCommandBinding binding in commandBindingInfo.OldCommandBindings) {
commandBindingInfo.OwnerInstance.CommandBindings.Remove(binding);
}
foreach(ManagedCommandBinding binding in commandBindingInfo.NewCommandBindings) {
commandBindingInfo.OwnerInstance.CommandBindings.Remove(binding);
}
}
}
#region Register bindings update handler
/// <summary>
/// Invoke registered input bindings update handlers registered in specified context
/// Register command binding update handler which is triggered when input bindings associated
/// with specified type change
/// </summary>
/// <param name="contextName">Context class full name</param>
public static void InvokeInputBindingUpdateHandlers(string contextName, UIElement contextInstance) {
if(contextInstance == null) {
contextInstance = NullUIElement;
/// <param name="ownerType">Owner type</param>
/// <param name="handler">Update handler</param>
public static void RegisterClassCommandBindingsUpdateHandler(Type ownerType, BindingsUpdatedHandler handler)
{
RegisterClassCommandBindingsUpdateHandler(ownerType.AssemblyQualifiedName, handler);
}
/// <summary>
/// Register command binding update handler which is triggered when input bindings associated
/// with specified type change
/// </summary>
/// <param name="ownerTypeName">Owner type name</param>
/// <param name="handler">Update handler</param>
public static void RegisterClassCommandBindingsUpdateHandler(string ownerTypeName, BindingsUpdatedHandler handler)
{
if(!classCommandBindingUpdateHandlers.ContainsKey(ownerTypeName)) {
classCommandBindingUpdateHandlers.Add(ownerTypeName, new List<BindingsUpdatedHandler>());
}
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();
}
}
}
if(!classCommandBindingUpdateHandlers[ownerTypeName].Contains(handler)) {
classCommandBindingUpdateHandlers[ownerTypeName].Add(handler);
}
}
/// <summary>
/// Register command binding update handler which is triggered when input bindings associated
/// with specified instance change
/// </summary>
/// <param name="instanceName">Owner instance name</param>
/// <param name="handler">Update handler</param>
public static void RegisterInstanceCommandBindingsUpdateHandler(string instanceName, BindingsUpdatedHandler handler)
{
var instance = GetNamedUIElementInstance(instanceName);
if(instance != null) {
RegisterInstanceCommandBindingsUpdateHandler(instance, handler);
} else {
foreach(var contextHandlers in inputBindingsUpdateHandlers) {
foreach(var instanceHandlers in contextHandlers.Value) {
foreach(var handler in instanceHandlers.Value) {
if(handler != null) {
((BindingsUpdatedHandler)handler).Invoke();
}
}
}
if(!instanceCommandBindingUpdateHandlers.ContainsKey(instanceName)) {
instanceCommandBindingUpdateHandlers.Add(instanceName, new List<BindingsUpdatedHandler>());
}
instanceCommandBindingUpdateHandlers[instanceName].Add(handler);
}
}
/// <summary>
/// Remove all managed input bindings from <see cref="InputBindingCollection" />
/// Register command binding update handler which is triggered when input bindings associated
/// with specified instance change
/// </summary>
/// <param name="inputBindingCollection">Input binding cllection containing managed input bindings</param>
public static void RemoveManagedInputBindings(InputBindingCollection inputBindingCollection) {
for(int i = inputBindingCollection.Count - 1; i >= 0; i--) {
if(inputBindingCollection[i] is ManagedInputBinding) {
inputBindingCollection.RemoveAt(i);
}
/// <param name="instance">Owner instance</param>
/// <param name="handler">Update handler</param>
public static void RegisterInstanceCommandBindingsUpdateHandler(UIElement instance, BindingsUpdatedHandler handler)
{
if(!instanceCommandBindingUpdateHandlers.ContainsKey(instance)) {
instanceCommandBindingUpdateHandlers.Add(instance, new List<BindingsUpdatedHandler>());
}
instanceCommandBindingUpdateHandlers[instance].Add(handler);
}
/// <summary>
/// Register input binding update handler which is triggered when input bindings associated
/// with specified type change
/// </summary>
/// <param name="ownerType">Owner type</param>
/// <param name="handler">Update handler</param>
public static void RegisterClassInputBindingsUpdateHandler(Type ownerType, BindingsUpdatedHandler handler)
{
RegisterClassInputBindingsUpdateHandler(ownerType.AssemblyQualifiedName, handler);
}
/// <summary>
/// Register command binding by specifying command binding parameters
/// Register input binding update handler which is triggered when input bindings associated
/// with specified type change
/// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void RegisterCommandBinding(CommandBindingInfo commandBindingInfo) {
commandBindings.Add(commandBindingInfo);
/// <param name="ownerTypeName">Owner type name</param>
/// <param name="handler">Update handler</param>
public static void RegisterClassInputBindingsUpdateHandler(string ownerTypeName, BindingsUpdatedHandler handler)
{
if(!classInputBindingUpdateHandlers.ContainsKey(ownerTypeName)) {
classInputBindingUpdateHandlers.Add(ownerTypeName, new List<BindingsUpdatedHandler>());
}
if(!classInputBindingUpdateHandlers[ownerTypeName].Contains(handler)) {
classInputBindingUpdateHandlers[ownerTypeName].Add(handler);
}
}
/// <summary>
/// Unregister command binding
/// Register input binding update handler which is triggered when input bindings associated
/// with specified instance change
/// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void UnregisterCommandBinding(CommandBindingInfo commandBindingInfo) {
commandBindings.Remove(commandBindingInfo);
/// <param name="instanceName">Owner instance name</param>
/// <param name="handler">Update handler</param>
public static void RegisterInstanceInputBindingsUpdateHandler(string instanceName, BindingsUpdatedHandler handler)
{
var instance = GetNamedUIElementInstance(instanceName);
if(instance != null) {
RegisterInstanceInputBindingsUpdateHandler(instance, handler);
} else {
if(!instanceInputBindingUpdateHandlers.ContainsKey(instanceName)) {
instanceInputBindingUpdateHandlers.Add(instanceName, new List<BindingsUpdatedHandler>());
}
instanceInputBindingUpdateHandlers[instanceName].Add(handler);
}
}
/// <summary>
/// Register delegate which will be invoked on any chage in command bindings of specified context
/// Register input binding update handler which is triggered when input bindings associated
/// with specified instance change
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Register update handler which is triggered only if input bindings registered for specific instance are updated</param>
/// <param name="handler">Update handler delegate</param>
public static void RegisterCommandBindingsUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) {
if(contextInstance == null) {
contextInstance = NullUIElement;
/// <param name="instance">Owner instance</param>
/// <param name="handler">Update handler</param>
public static void RegisterInstanceInputBindingsUpdateHandler(UIElement instance, BindingsUpdatedHandler handler)
{
if(!instanceInputBindingUpdateHandlers.ContainsKey(instance)) {
instanceInputBindingUpdateHandlers.Add(instance, new List<BindingsUpdatedHandler>());
}
if(!commandBindingsUpdateHandlers.ContainsKey(contextName)) {
commandBindingsUpdateHandlers.Add(contextName, new Dictionary<UIElement, List<BindingsUpdatedHandler>>());
instanceInputBindingUpdateHandlers[instance].Add(handler);
}
#endregion
#region Invoke binding update handlers
/// <summary>
/// Invoke all inbut binding update handlers
/// </summary>
public static void InvokeInputBindingUpdateHandlers()
{
foreach(var instanceHandlers in instanceInputBindingUpdateHandlers) {
foreach(var handler in instanceHandlers.Value) {
handler.Invoke();
}
}
if(!commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
commandBindingsUpdateHandlers[contextName].Add(contextInstance, new List<BindingsUpdatedHandler>());
foreach(var classHandlers in classInputBindingUpdateHandlers) {
foreach(var handler in classHandlers.Value) {
handler.Invoke();
}
}
}
/// <summary>
/// Invoke all command binding update handlers
/// </summary>
public static void InvokeCommandBindingUpdateHandlers()
{
foreach(var instanceHandlers in instanceCommandBindingUpdateHandlers) {
foreach(var handler in instanceHandlers.Value) {
handler.Invoke();
}
}
commandBindingsUpdateHandlers[contextName][contextInstance].Add(handler);
foreach(var classHandlers in classCommandBindingUpdateHandlers) {
foreach(var handler in classHandlers.Value) {
handler.Invoke();
}
}
}
/// <summary>
/// Remove handler command bindings update handler
/// Invoke command binding update handlers associated with UI element instance
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Unregister update handler which was triggered only if input bindings registered for specific instance were updated</param>
/// <param name="handler">Update handler delegate</param>
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);
}
}
/// <param name="owner">Owner instance</param>
public static void InvokeInstanceCommandBindingUpdateHandlers(UIElement owner)
{
if(instanceCommandBindingUpdateHandlers.ContainsKey(owner)) {
foreach(var handler in instanceCommandBindingUpdateHandlers[owner]) {
handler.Invoke();
}
}
}
/// <summary>
/// Invoke registered command bindings update handlers registered in specified context
/// Invoke command binding update handlers associated with UI element instance
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Invoke update handlers which handle update only in specifyc context</param>
public static void InvokeCommandBindingUpdateHandlers(string contextName, UIElement contextInstance) {
if(contextInstance == null) {
contextInstance = NullUIElement;
/// <param name="owner">Owner instance name</param>
public static void InvokeInstanceCommandBindingUpdateHandlers(string ownerName)
{
if(instanceCommandBindingUpdateHandlers.ContainsKey(ownerName)) {
foreach(var handler in instanceCommandBindingUpdateHandlers[ownerName]) {
handler.Invoke();
}
}
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();
}
}
}
}
/// <summary>
/// Invoke command binding update handlers associated with UI element type
/// </summary>
/// <param name="owner">Owner type</param>
public static void InvokeClassCommandBindingUpdateHandlers(Type ownerType)
{
InvokeClassCommandBindingUpdateHandlers(ownerType.AssemblyQualifiedName);
}
/// <summary>
/// Invoke command binding update handlers associated with UI element type
/// </summary>
/// <param name="owner">Owner type name</param>
public static void InvokeClassCommandBindingUpdateHandlers(string ownerTypeName)
{
if(instanceCommandBindingUpdateHandlers.ContainsKey(ownerTypeName)) {
foreach(var handler in classCommandBindingUpdateHandlers[ownerTypeName]) {
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();
}
}
}
}
}
/// <summary>
/// Invoke input binding update handlers associated with UI element instance
/// </summary>
/// <param name="owner">Owner instance</param>
public static void InvokeInstanceInputBindingUpdateHandlers(UIElement owner)
{
if(instanceInputBindingUpdateHandlers.ContainsKey(owner)) {
foreach(var handler in instanceInputBindingUpdateHandlers[owner]) {
handler.Invoke();
}
}
}
/// <summary>
/// Remove all managed command bindings from <see cref="CommandBindingCollection" />
/// Invoke input binding update handlers associated with UI element instance
/// </summary>
/// <param name="commandBindingsCollection">Command binding cllection containing managed input bindings</param>
public static void RemoveManagedCommandBindings(CommandBindingCollection commandBindingsCollection) {
for(int i = commandBindingsCollection.Count - 1; i >= 0; i--) {
if(commandBindingsCollection[i] is ManagedCommandBinding) {
commandBindingsCollection.RemoveAt(i);
/// <param name="ownerName">Owner instance name</param>
public static void InvokeInstanceInputBindingUpdateHandlers(string ownerName)
{
if(instanceInputBindingUpdateHandlers.ContainsKey(ownerName)) {
foreach(var handler in instanceInputBindingUpdateHandlers[ownerName]) {
handler.Invoke();
}
}
}
/// <summary>
/// Invoke input binding update handlers associated with UI element type
/// </summary>
/// <param name="owner">Owner type</param>
public static void InvokeClassInputBindingUpdateHandlers(Type ownerType)
{
InvokeClassInputBindingUpdateHandlers(ownerType.AssemblyQualifiedName);
}
/// <summary>
/// Invoke input binding update handlers associated with UI element type
/// </summary>
/// <param name="owner">Owner type name</param>
public static void InvokeClassInputBindingUpdateHandlers(string ownerTypeName)
{
if(instanceInputBindingUpdateHandlers.ContainsKey(ownerTypeName)) {
foreach(var handler in instanceInputBindingUpdateHandlers[ownerTypeName]) {
handler.Invoke();
}
}
}
#endregion
/// <summary>
/// Load all registered commands in add-in
/// </summary>
@ -398,15 +638,6 @@ namespace ICSharpCode.Core.Presentation @@ -398,15 +638,6 @@ namespace ICSharpCode.Core.Presentation
}
}
/// <summary>
/// Register binding owner instance which can be identified by unique name
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="context">Context class instance</param>
public static void LoadContext(string contextName, UIElement context) {
contexts[contextName] = context;
}
/// <summary>
/// Get list of all command bindings which satisfy provided parameters
///
@ -417,12 +648,14 @@ namespace ICSharpCode.Core.Presentation @@ -417,12 +648,14 @@ namespace ICSharpCode.Core.Presentation
/// <param name="routedCommandName">Context class full name</param>
/// <param name="className">Context class full name</param>
/// <returns>Collection of managed command bindings</returns>
public static ICollection<CommandBindingInfo> FindCommandBindingInfos(string contextName, UIElement contextInstance, string routedCommandName, string className) {
public static ICollection<CommandBindingInfo> FindCommandBindingInfos(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName, string className) {
var foundBindings = new List<CommandBindingInfo>();
foreach(var binding in commandBindings) {
if((contextName == null || binding.ContextName == contextName)
&& (contextInstance == null || binding.Context == null || binding.Context == contextInstance)
if( (ownerInstanceName == null || binding.OwnerInstanceName == ownerInstanceName)
&& (ownerInstance == null || binding.OwnerInstance == ownerInstance)
&& (ownerTypeName == null || binding.OwnerTypeName == ownerTypeName)
&& (ownerType == null || binding.OwnerType == ownerType)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName)
&& (className == null || binding.ClassName == className)) {
@ -434,51 +667,6 @@ namespace ICSharpCode.Core.Presentation @@ -434,51 +667,6 @@ namespace ICSharpCode.Core.Presentation
}
/// <summary>
/// Get list of all command bindings which satisfy provided parameters
///
/// Null arguments are ignored
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Get command bindings assigned only to specific context</param>
/// <param name="routedCommandName">Context class full name</param>
/// <param name="className">Context class full name</param>
/// <returns>Collection of managed command bindings</returns>
public static CommandBindingCollection FindCommandBindings(string contextName, UIElement contextInstance, string routedCommandName, string className) {
var commandBindingInfos = FindCommandBindingInfos(contextName, contextInstance, routedCommandName, className);
var bindings = new CommandBindingCollection();
foreach(var binding in commandBindingInfos) {
var managedCommandBinding = new ManagedCommandBinding(binding.RoutedCommand);
managedCommandBinding.CanExecute += binding.GeneratedCanExecuteEventHandler;
managedCommandBinding.Executed += binding.GeneratedExecutedEventHandler;
bindings.Add(managedCommandBinding);
}
return bindings;
}
/// <summary>
/// Get list of all input bindings which satisfy provided parameters
///
/// Null arguments are ignored
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Get input bindings assigned only to specific context</param>
/// <param name="routedCommandName">Routed UI command name</param>
public static InputBindingCollection FindInputBindings(string contextName, UIElement contextInstance, string routedCommandName) {
var inputBindingInfos = FindInputBindingInfos(contextName, contextInstance, routedCommandName);
var bindings = new InputBindingCollection();
foreach(var binding in inputBindingInfos) {
foreach(InputGesture bindingGesture in binding.Gestures) {
bindings.Add(new ManagedInputBinding(binding.RoutedCommand, bindingGesture));
}
}
return bindings;
}
/// <summary>
/// Get list of input gestures from all input bindings which satisfy provided parameters
@ -489,12 +677,12 @@ namespace ICSharpCode.Core.Presentation @@ -489,12 +677,12 @@ namespace ICSharpCode.Core.Presentation
/// <param name="contextInstance">Get gestures assigned only to specific context</param>
/// <param name="routedCommandName">Routed UI command name</param>
/// <param name="gesture">Gesture</param>
public static InputGestureCollection FindInputGestures(string contextName, UIElement contextInstance, string routedCommandName) {
var bindings = FindInputBindings(contextName, contextInstance, routedCommandName);
public static InputGestureCollection FindInputGestures(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName) {
var bindings = FindInputBindingInfos(ownerTypeName, ownerType, ownerInstanceName, ownerInstance, routedCommandName);
var gestures = new InputGestureCollection();
foreach(InputBinding binding in bindings) {
gestures.Add(binding.Gesture);
foreach(InputBindingInfo bindingInfo in bindings) {
gestures.AddRange(bindingInfo.Gestures);
}
return gestures;
@ -540,5 +728,77 @@ namespace ICSharpCode.Core.Presentation @@ -540,5 +728,77 @@ namespace ICSharpCode.Core.Presentation
return registeredCategories;
}
/// <summary>
/// Register default command binding update hander which will keep instance command
/// bindings upated
/// </summary>
/// <param name="commandBindingInfo">Command binding info</param>
private static void RegisterInstaceDefaultCommandBindingHandler(CommandBindingInfo commandBindingInfo)
{
if(commandBindingInfo.DefaultCommandBindingHandler != null) {
commandBindingInfo.DefaultCommandBindingHandler.Invoke();
}
if(commandBindingInfo.OwnerInstanceName != null && commandBindingInfo.OwnerInstance == null) {
RegisterInstanceCommandBindingsUpdateHandler(commandBindingInfo.OwnerInstanceName, commandBindingInfo.DefaultCommandBindingHandler);
} else if(commandBindingInfo.OwnerInstance != null) {
RegisterInstanceCommandBindingsUpdateHandler(commandBindingInfo.OwnerInstance, commandBindingInfo.DefaultCommandBindingHandler);
}
}
/// <summary>
/// Register default command binding update hander which will keep type command
/// bindings upated
/// </summary>
/// <param name="commandBindingInfo">Command binding info</param>
private static void RegisterClassDefaultCommandBindingHandler(CommandBindingInfo commandBindingInfo)
{
if(commandBindingInfo.DefaultCommandBindingHandler != null) {
commandBindingInfo.DefaultCommandBindingHandler.Invoke();
}
if(commandBindingInfo.OwnerTypeName != null && commandBindingInfo.OwnerType == null) {
RegisterClassCommandBindingsUpdateHandler(commandBindingInfo.OwnerTypeName, commandBindingInfo.DefaultCommandBindingHandler);
} else if(commandBindingInfo.OwnerType != null) {
RegisterClassCommandBindingsUpdateHandler(commandBindingInfo.OwnerType, commandBindingInfo.DefaultCommandBindingHandler);
}
}
/// <summary>
/// Register default input binding update hander which will keep instance command
/// bindings upated
/// </summary>
/// <param name="inputBindingInfo">Input binding info</param>
private static void RegisterInstaceDefaultInputBindingHandler(InputBindingInfo inputBindingInfo)
{
if(inputBindingInfo.DefaultInputBindingHandler != null) {
inputBindingInfo.DefaultInputBindingHandler.Invoke();
}
if(inputBindingInfo.OwnerInstanceName != null && inputBindingInfo.OwnerInstance == null) {
RegisterInstanceInputBindingsUpdateHandler(inputBindingInfo.OwnerInstanceName, inputBindingInfo.DefaultInputBindingHandler);
} else if(inputBindingInfo.OwnerInstance != null) {
RegisterInstanceInputBindingsUpdateHandler(inputBindingInfo.OwnerInstance, inputBindingInfo.DefaultInputBindingHandler);
}
}
/// <summary>
/// Register default input binding update hander which will keep type command
/// bindings upated
/// </summary>
/// <param name="inputBindingInfo">Input binding info</param>
private static void RegisterClassDefaultInputBindingHandler(InputBindingInfo inputBindingInfo)
{
if(inputBindingInfo.DefaultInputBindingHandler != null) {
inputBindingInfo.DefaultInputBindingHandler.Invoke();
}
if(inputBindingInfo.OwnerTypeName != null && inputBindingInfo.OwnerType == null) {
RegisterClassInputBindingsUpdateHandler(inputBindingInfo.OwnerTypeName, inputBindingInfo.DefaultInputBindingHandler);
} else if(inputBindingInfo.OwnerType != null) {
RegisterClassInputBindingsUpdateHandler(inputBindingInfo.OwnerType, inputBindingInfo.DefaultInputBindingHandler);
}
}
}
}

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

@ -39,8 +39,6 @@ namespace ICSharpCode.Core.Presentation @@ -39,8 +39,6 @@ namespace ICSharpCode.Core.Presentation
{
var descriptors = AddInTree.BuildItems<CommandBindingDescriptor>(path, caller, false);
foreach(var desc in descriptors) {
var contextName = !string.IsNullOrEmpty(desc.Context) ? desc.Context : CommandsRegistry.DefaultContextName;
// If routed with such name is not registered register routed command with text same as name
if(CommandsRegistry.GetRoutedUICommand(desc.Command) == null) {
var commandText = string.IsNullOrEmpty(desc.CommandText) ? desc.Command : desc.CommandText;
@ -48,7 +46,15 @@ namespace ICSharpCode.Core.Presentation @@ -48,7 +46,15 @@ namespace ICSharpCode.Core.Presentation
}
var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.ContextName = contextName;
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
commandBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
} else if(!string.IsNullOrEmpty(desc.OwnerTypeName)) {
commandBindingInfo.OwnerTypeName = desc.OwnerTypeName;
} else {
commandBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
}
commandBindingInfo.RoutedCommandName = desc.Command;
commandBindingInfo.ClassName = desc.Class;
commandBindingInfo.AddIn = desc.Codon.AddIn;
@ -60,7 +66,15 @@ namespace ICSharpCode.Core.Presentation @@ -60,7 +66,15 @@ namespace ICSharpCode.Core.Presentation
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures);
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.ContextName = contextName;
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
inputBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
} else if(!string.IsNullOrEmpty(desc.OwnerTypeName)) {
inputBindingInfo.OwnerTypeName = desc.OwnerTypeName;
} else {
inputBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
}
inputBindingInfo.AddIn = desc.Codon.AddIn;
inputBindingInfo.RoutedCommandName = desc.Command;
inputBindingInfo.Gestures = gestures;
@ -83,10 +97,17 @@ namespace ICSharpCode.Core.Presentation @@ -83,10 +97,17 @@ namespace ICSharpCode.Core.Presentation
var descriptors = AddInTree.BuildItems<InputBindingDescriptor>(path, caller, false);
foreach(var desc in descriptors) {
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures);
var contextName = !string.IsNullOrEmpty(desc.Context) ? desc.Context : CommandsRegistry.DefaultContextName;
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.ContextName = contextName;
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
inputBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
} else if(!string.IsNullOrEmpty(desc.OwnerTypeName)) {
inputBindingInfo.OwnerTypeName = desc.OwnerTypeName;
} else {
inputBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
}
inputBindingInfo.AddIn = desc.Codon.AddIn;
inputBindingInfo.RoutedCommandName = desc.Command;
inputBindingInfo.Gestures = gestures;

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

@ -5,95 +5,183 @@ using System.Collections.Generic; @@ -5,95 +5,183 @@ using System.Collections.Generic;
namespace ICSharpCode.Core.Presentation
{
/// <summary>
/// Stores details about input binding
/// </summary>
public class InputBindingInfo
{
private UIElement contextInstance;
public InputBindingInfo() {
ContextName = CommandsRegistry.DefaultContextName;
Categories = new List<InputBindingCategory>();
}
/// <summary>
/// Context class full name
///
/// Described binding will be valid in this context
/// </summary>
public string ContextName {
get; set;
}
/// <summary>
/// Context class instance
///
/// Described binding will be valid in this context
/// </summary>
public UIElement Context {
get {
if(contextInstance != null) {
return contextInstance;
} else {
UIElement context;
CommandsRegistry.contexts.TryGetValue(ContextName, out context);
return context;
}
/// <summary>
/// Stores details about input binding
/// </summary>
public class InputBindingInfo
{
public InputBindingInfo() {
IsModifyed = true;
OldInputBindings = new InputBindingCollection();
NewInputBindings = new InputBindingCollection();
Categories = new List<InputBindingCategory>();
}
public string OwnerInstanceName{
get; set;
}
private UIElement ownerInstance;
public UIElement OwnerInstance{
get {
if(OwnerInstanceName != null && ownerInstance == null) {
ownerInstance = CommandsRegistry.GetNamedUIElementInstance(OwnerInstanceName);
}
return ownerInstance;
}
/// <summary>
/// Routed command text
///
/// Override routed command text when displaying to user
/// </summary>
/// <seealso cref="RoutedCommand"></seealso>
public string RoutedCommandText {
get; set;
set {
ownerInstance = value;
}
/// <summary>
/// Add-in to which registered this input binding
/// </summary>
public AddIn AddIn {
get; set;
}
public string OwnerTypeName{
get; set;
}
private Type ownerType;
public Type OwnerType {
set {
ownerType = value;
}
/// <summary>
/// Routed command name
///
/// Described binding triggers this routed command
/// </summary>
/// <seealso cref="RoutedCommand"></seealso>
public string RoutedCommandName {
get; set;
get {
if(ownerType == null && OwnerTypeName != null) {
ownerType = Type.GetType(OwnerTypeName);
CommandsRegistry.RegisterNamedUIType(OwnerTypeName, ownerType);
}
return ownerType;
}
}
/// <summary>
/// Routed command text
///
/// Override routed command text when displaying to user
/// </summary>
/// <seealso cref="RoutedCommand"></seealso>
public string RoutedCommandText {
get; set;
}
/// <summary>
/// Routed command instance
///
/// Described binding triggers this routed command
/// </summary>
/// <seealso cref="RoutedCommandName"></seealso>
public RoutedUICommand RoutedCommand {
get {
return CommandsRegistry.GetRoutedUICommand(RoutedCommandName);
/// <summary>
/// Add-in to which registered this input binding
/// </summary>
public AddIn AddIn {
get; set;
}
/// <summary>
/// Gestures which triggers this binding
/// </summary>
public InputGestureCollection Gestures {
get; set;
}
/// <summary>
/// Routed command name
///
/// Described binding triggers this routed command
/// </summary>
/// <seealso cref="RoutedCommand"></seealso>
public string RoutedCommandName {
get; set;
}
/// <summary>
/// Routed command instance
///
/// Described binding triggers this routed command
/// </summary>
/// <seealso cref="RoutedCommandName"></seealso>
public RoutedUICommand RoutedCommand {
get {
return CommandsRegistry.GetRoutedUICommand(RoutedCommandName);
}
}
private BindingsUpdatedHandler defaultInputBindingHandler;
/// <summary>
/// Default binding update handler update owner or type bindings (depending on input binding info type)
/// so they would always contain latest version
/// </summary>
public BindingsUpdatedHandler DefaultInputBindingHandler
{
get {
if(defaultInputBindingHandler == null && (OwnerTypeName != null || OwnerType != null)) {
defaultInputBindingHandler = delegate {
if(OwnerType != null && IsModifyed) {
GenerateInputBindings();
foreach(ManagedInputBinding binding in OldInputBindings) {
CommandsRegistry.RemoveClassInputBinding(OwnerType, binding);
}
foreach(ManagedInputBinding binding in NewInputBindings) {
CommandManager.RegisterClassInputBinding(OwnerType, binding);
}
IsModifyed = false;
}
};
} else if(defaultInputBindingHandler == null && (OwnerInstanceName != null || OwnerInstance != null)) {
defaultInputBindingHandler = delegate {
if(OwnerInstance != null && IsModifyed) {
GenerateInputBindings();
foreach(ManagedInputBinding binding in NewInputBindings) {
OwnerInstance.InputBindings.Remove(binding);
}
OwnerInstance.InputBindings.AddRange(NewInputBindings);
IsModifyed = false;
}
};
}
return defaultInputBindingHandler;
}
}
/// <summary>
/// List of categories associated with input binding
/// </summary>
public List<InputBindingCategory> Categories {
get; private set;
}
/// <summary>
/// Gestures which triggers this binding
/// </summary>
public InputGestureCollection Gestures {
get; set;
}
/// <summary>
/// Indicates whether generated input bindings where modified from last access
/// </summary>
public bool IsModifyed {
get; set;
}
public void GenerateInputBindings()
{
OldInputBindings = NewInputBindings;
public List<InputBindingCategory> Categories {
get; private set;
NewInputBindings = new InputBindingCollection();
foreach(InputGesture gesture in Gestures) {
var managedInputBinding = new ManagedInputBinding(RoutedCommand, gesture);
NewInputBindings.Add(managedInputBinding);
}
}
internal InputBindingCollection OldInputBindings
{
get; set;
}
internal InputBindingCollection NewInputBindings
{
get; set;
}
}
}

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

@ -140,13 +140,12 @@ namespace ICSharpCode.Core.Presentation @@ -140,13 +140,12 @@ namespace ICSharpCode.Core.Presentation
if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) {
var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.AddIn = codon.AddIn;
commandBindingInfo.ContextName = CommandsRegistry.DefaultContextName;
commandBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
commandBindingInfo.Class = CommandWrapper.GetCommand(codon, caller, createCommand);
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.IsLazy = true;
CommandsRegistry.RegisterCommandBinding(commandBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
}
if(codon.Properties.Contains("shortcut")) {
@ -154,16 +153,19 @@ namespace ICSharpCode.Core.Presentation @@ -154,16 +153,19 @@ namespace ICSharpCode.Core.Presentation
var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.AddIn = codon.AddIn;
inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories("Menu Items"));
inputBindingInfo.ContextName = CommandsRegistry.DefaultContextName;
inputBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromInvariantString(codon.Properties["gestures"]);
CommandsRegistry.RegisterInputBinding(inputBindingInfo);
CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
var updatedGestures = CommandsRegistry.FindInputGestures(null, null, routedCommandName);
this.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
});
CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
BindingsUpdatedHandler gesturesUpdateHandler = delegate {
var updatedGestures = CommandsRegistry.FindInputGestures(null, null, null, null, routedCommandName);
this.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
};
gesturesUpdateHandler.Invoke();
CommandsRegistry.RegisterClassInputBindingsUpdateHandler(CommandsRegistry.DefaultContextName, gesturesUpdateHandler);
}
}
}

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

@ -50,13 +50,12 @@ namespace ICSharpCode.Core.Presentation @@ -50,13 +50,12 @@ namespace ICSharpCode.Core.Presentation
if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) {
var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.AddIn = codon.AddIn;
commandBindingInfo.ContextName = CommandsRegistry.DefaultContextName;
commandBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
commandBindingInfo.Class = CommandWrapper.GetCommand(codon, caller, createCommand);
commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.IsLazy = true;
CommandsRegistry.RegisterCommandBinding(commandBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
}
if (codon.Properties.Contains("icon")) {

Loading…
Cancel
Save