Events can now be instantiated.
authorStephaneLenclud
Fri, 12 Aug 2016 20:25:05 +0200
changeset 2314c706feaf706
parent 230 8c5cf2228e9a
child 232 5a739e2e5255
Events can now be instantiated.
Action editor is now a generic object editor.
Server/Actions/ActionCecActiveSource.cs
Server/Actions/ActionCecClose.cs
Server/Actions/ActionCecDevice.cs
Server/Actions/ActionCecDevicePowerOn.cs
Server/Actions/ActionCecDeviceStandby.cs
Server/Actions/ActionCecDeviceType.cs
Server/Actions/ActionCecInactiveSource.cs
Server/Actions/ActionCecOpen.cs
Server/Actions/ActionCecScan.cs
Server/Actions/ActionCecUserControlPressed.cs
Server/Actions/ActionCecUserControlReleased.cs
Server/Actions/ActionDisplayMessage.cs
Server/ConsumerElectronicControl.cs
Server/FormEditAction.Designer.cs
Server/FormEditAction.cs
Server/FormEditAction.resx
Server/FormEditObject.Designer.cs
Server/FormEditObject.cs
Server/FormEditObject.resx
Server/FormMain.Designer.cs
Server/FormMain.cs
Server/ItemActionType.cs
Server/SharpDisplayManager.csproj
SharpLibEar/Action.cs
SharpLibEar/ActionSleep.cs
SharpLibEar/AttributeAction.cs
SharpLibEar/AttributeActionProperty.cs
SharpLibEar/AttributeObject.cs
SharpLibEar/AttributeObjectProperty.cs
SharpLibEar/Event.cs
SharpLibEar/EventMonitorPowerOff.cs
SharpLibEar/EventMonitorPowerOn.cs
SharpLibEar/ManagerEventAction.cs
SharpLibEar/SharpLibEar.csproj
     1.1 --- a/Server/Actions/ActionCecActiveSource.cs	Sun Jul 31 12:03:52 2016 +0200
     1.2 +++ b/Server/Actions/ActionCecActiveSource.cs	Fri Aug 12 20:25:05 2016 +0200
     1.3 @@ -10,7 +10,7 @@
     1.4  namespace SharpDisplayManager
     1.5  {
     1.6      [DataContract]
     1.7 -    [AttributeAction(Id = "Cec.ActiveSource", Name = "CEC Active Source", Description = "Set this CEC device as active source.")]
     1.8 +    [AttributeObject(Id = "Cec.ActiveSource", Name = "CEC Active Source", Description = "Set this CEC device as active source.")]
     1.9      class ActionCecActiveSource : ActionCecDeviceType
    1.10      {
    1.11          /// <summary>
     2.1 --- a/Server/Actions/ActionCecClose.cs	Sun Jul 31 12:03:52 2016 +0200
     2.2 +++ b/Server/Actions/ActionCecClose.cs	Fri Aug 12 20:25:05 2016 +0200
     2.3 @@ -10,7 +10,7 @@
     2.4  namespace SharpDisplayManager
     2.5  {
     2.6      [DataContract]
     2.7 -    [AttributeAction(Id = "Cec.Close", Name = "CEC Close", Description = "Close CEC connection.")]
     2.8 +    [AttributeObject(Id = "Cec.Close", Name = "CEC Close", Description = "Close CEC connection.")]
     2.9      class ActionCecClose : SharpLib.Ear.Action
    2.10      {
    2.11          protected override void DoExecute()
     3.1 --- a/Server/Actions/ActionCecDevice.cs	Sun Jul 31 12:03:52 2016 +0200
     3.2 +++ b/Server/Actions/ActionCecDevice.cs	Fri Aug 12 20:25:05 2016 +0200
     3.3 @@ -17,7 +17,7 @@
     3.4      public abstract class ActionCecDevice: SharpLib.Ear.Action
     3.5      {
     3.6          [DataMember]
     3.7 -        [AttributeActionProperty
     3.8 +        [AttributeObjectProperty
     3.9              (
    3.10              Id = "CEC.Device",
    3.11              Name = "Device",
     4.1 --- a/Server/Actions/ActionCecDevicePowerOn.cs	Sun Jul 31 12:03:52 2016 +0200
     4.2 +++ b/Server/Actions/ActionCecDevicePowerOn.cs	Fri Aug 12 20:25:05 2016 +0200
     4.3 @@ -11,7 +11,7 @@
     4.4  namespace SharpDisplayManager
     4.5  {
     4.6      [DataContract]
     4.7 -    [AttributeAction(Id = "Cec.Device.PowerOn", Name = "CEC Device Power On", Description = "Turns on the specified CEC device on your HDMI bus.")]
     4.8 +    [AttributeObject(Id = "Cec.Device.PowerOn", Name = "CEC Device Power On", Description = "Turns on the specified CEC device on your HDMI bus.")]
     4.9      public class ActionCecDevicePowerOn : ActionCecDevice
    4.10      {
    4.11          /// <summary>
     5.1 --- a/Server/Actions/ActionCecDeviceStandby.cs	Sun Jul 31 12:03:52 2016 +0200
     5.2 +++ b/Server/Actions/ActionCecDeviceStandby.cs	Fri Aug 12 20:25:05 2016 +0200
     5.3 @@ -11,7 +11,7 @@
     5.4  namespace SharpDisplayManager
     5.5  {
     5.6      [DataContract]
     5.7 -    [AttributeAction(Id = "Cec.Device.Standby", Name = "CEC Device Standby", Description = "Puts on standby the specified CEC device on your HDMI bus.")]
     5.8 +    [AttributeObject(Id = "Cec.Device.Standby", Name = "CEC Device Standby", Description = "Puts on standby the specified CEC device on your HDMI bus.")]
     5.9      public class ActionCecDeviceStandby : ActionCecDevice
    5.10      {
    5.11          /// <summary>
     6.1 --- a/Server/Actions/ActionCecDeviceType.cs	Sun Jul 31 12:03:52 2016 +0200
     6.2 +++ b/Server/Actions/ActionCecDeviceType.cs	Fri Aug 12 20:25:05 2016 +0200
     6.3 @@ -17,7 +17,7 @@
     6.4      public abstract class ActionCecDeviceType : SharpLib.Ear.Action
     6.5      {
     6.6          [DataMember]
     6.7 -        [AttributeActionProperty
     6.8 +        [AttributeObjectProperty
     6.9              (
    6.10              Id = "CEC.DeviceType",
    6.11              Name = "Device Type",
     7.1 --- a/Server/Actions/ActionCecInactiveSource.cs	Sun Jul 31 12:03:52 2016 +0200
     7.2 +++ b/Server/Actions/ActionCecInactiveSource.cs	Fri Aug 12 20:25:05 2016 +0200
     7.3 @@ -10,7 +10,7 @@
     7.4  namespace SharpDisplayManager
     7.5  {
     7.6      [DataContract]
     7.7 -    [AttributeAction(Id = "Cec.InactiveSource", Name = "CEC Inactive Source", Description = "Set this CEC device as inactive source.")]
     7.8 +    [AttributeObject(Id = "Cec.InactiveSource", Name = "CEC Inactive Source", Description = "Set this CEC device as inactive source.")]
     7.9      class ActionCecInactiveSource : SharpLib.Ear.Action
    7.10      {
    7.11          protected override void DoExecute()
     8.1 --- a/Server/Actions/ActionCecOpen.cs	Sun Jul 31 12:03:52 2016 +0200
     8.2 +++ b/Server/Actions/ActionCecOpen.cs	Fri Aug 12 20:25:05 2016 +0200
     8.3 @@ -10,7 +10,7 @@
     8.4  namespace SharpDisplayManager
     8.5  {
     8.6      [DataContract]
     8.7 -    [AttributeAction(Id = "Cec.Open", Name = "CEC Open", Description = "Open CEC connection.")]
     8.8 +    [AttributeObject(Id = "Cec.Open", Name = "CEC Open", Description = "Open CEC connection.")]
     8.9      class ActionCecOpen : SharpLib.Ear.Action
    8.10      {
    8.11          protected override void DoExecute()
     9.1 --- a/Server/Actions/ActionCecScan.cs	Sun Jul 31 12:03:52 2016 +0200
     9.2 +++ b/Server/Actions/ActionCecScan.cs	Fri Aug 12 20:25:05 2016 +0200
     9.3 @@ -11,7 +11,7 @@
     9.4  {
     9.5  
     9.6      [DataContract]
     9.7 -    [AttributeAction(Id = "Cec.Scan", Name = "CEC Scan", Description = "Scan devices on your CEC HDMI network.")]
     9.8 +    [AttributeObject(Id = "Cec.Scan", Name = "CEC Scan", Description = "Scan devices on your CEC HDMI network.")]
     9.9      class ActionCecScan : SharpLib.Ear.Action
    9.10      {
    9.11          protected override void DoExecute()
    10.1 --- a/Server/Actions/ActionCecUserControlPressed.cs	Sun Jul 31 12:03:52 2016 +0200
    10.2 +++ b/Server/Actions/ActionCecUserControlPressed.cs	Fri Aug 12 20:25:05 2016 +0200
    10.3 @@ -14,7 +14,7 @@
    10.4      /// Send a user key press event to the given CEC device.
    10.5      /// </summary>
    10.6      [DataContract]
    10.7 -    [AttributeAction(Id = "Cec.UserControlPressed", Name = "CEC User Control Pressed", Description = "Send user control code to defined CEC device.")]
    10.8 +    [AttributeObject(Id = "Cec.UserControlPressed", Name = "CEC User Control Pressed", Description = "Send user control code to defined CEC device.")]
    10.9      public class ActionCecUserControlPressed : ActionCecDevice
   10.10      {
   10.11  
   10.12 @@ -24,7 +24,7 @@
   10.13          }
   10.14  
   10.15          [DataMember]
   10.16 -        [AttributeActionProperty(
   10.17 +        [AttributeObjectProperty(
   10.18          Id = "Cec.UserControlPressed.Code",
   10.19          Name = "Code",
   10.20          Description = "The key code used by this action."
   10.21 @@ -32,7 +32,7 @@
   10.22          public CecUserControlCode Code { get; set; }
   10.23  
   10.24          [DataMember]
   10.25 -        [AttributeActionProperty(
   10.26 +        [AttributeObjectProperty(
   10.27          Id = "Cec.UserControlPressed.Wait",
   10.28          Name = "Wait",
   10.29          Description = "Wait for that command."
    11.1 --- a/Server/Actions/ActionCecUserControlReleased.cs	Sun Jul 31 12:03:52 2016 +0200
    11.2 +++ b/Server/Actions/ActionCecUserControlReleased.cs	Fri Aug 12 20:25:05 2016 +0200
    11.3 @@ -14,7 +14,7 @@
    11.4      /// Send a user key press event to the given CEC device.
    11.5      /// </summary>
    11.6      [DataContract]
    11.7 -    [AttributeAction(Id = "Cec.UserControlReleased", Name = "CEC User Control Released", Description = "Send user control release opcode to a given CEC device.")]
    11.8 +    [AttributeObject(Id = "Cec.UserControlReleased", Name = "CEC User Control Released", Description = "Send user control release opcode to a given CEC device.")]
    11.9      public class ActionCecUserControlReleased : ActionCecDevice
   11.10      {
   11.11  
   11.12 @@ -24,7 +24,7 @@
   11.13          }
   11.14  
   11.15          [DataMember]
   11.16 -        [AttributeActionProperty(
   11.17 +        [AttributeObjectProperty(
   11.18          Id = "Cec.UserControlPressed.Wait",
   11.19          Name = "Wait",
   11.20          Description = "Wait for that command."
    12.1 --- a/Server/Actions/ActionDisplayMessage.cs	Sun Jul 31 12:03:52 2016 +0200
    12.2 +++ b/Server/Actions/ActionDisplayMessage.cs	Fri Aug 12 20:25:05 2016 +0200
    12.3 @@ -13,11 +13,11 @@
    12.4  
    12.5  
    12.6      [DataContract]
    12.7 -    [AttributeAction(Id = "Display.Message", Name = "Display Message", Description = "Shows a message on your internal display.")]
    12.8 +    [AttributeObject(Id = "Display.Message", Name = "Display Message", Description = "Shows a message on your internal display.")]
    12.9      class ActionDisplayMessage : SharpLib.Ear.Action
   12.10      {
   12.11          [DataMember]
   12.12 -        [AttributeActionProperty(
   12.13 +        [AttributeObjectProperty(
   12.14              Id = "Display.Message.Duration",
   12.15              Name = "Duration (ms)",
   12.16              Description = "Specifies the number of milliseconds this message should be displayed.",
   12.17 @@ -29,7 +29,7 @@
   12.18  
   12.19  
   12.20          [DataMember]
   12.21 -        [AttributeActionProperty(
   12.22 +        [AttributeObjectProperty(
   12.23              Id = "Display.Message.PrimaryText",
   12.24              Name = "Primary Text",
   12.25              Description = "The primary text of this message."
   12.26 @@ -37,7 +37,7 @@
   12.27          public string PrimaryText { get; set; } = "Your message";
   12.28  
   12.29          [DataMember]
   12.30 -        [AttributeActionProperty(
   12.31 +        [AttributeObjectProperty(
   12.32              Id = "Display.Message.SecondaryText",
   12.33              Name = "Secondary Text",
   12.34              Description = "The secondary text of this message."
    13.1 --- a/Server/ConsumerElectronicControl.cs	Sun Jul 31 12:03:52 2016 +0200
    13.2 +++ b/Server/ConsumerElectronicControl.cs	Fri Aug 12 20:25:05 2016 +0200
    13.3 @@ -82,14 +82,14 @@
    13.4          {
    13.5              MonitorPowerOn = true;
    13.6              //Trigger corresponding event thus executing associated actions
    13.7 -            ManagerEventAction.Current.GetEvent<EventMonitorPowerOn>().Trigger();            
    13.8 +            ManagerEventAction.Current.TriggerEvent<EventMonitorPowerOn>();            
    13.9          }
   13.10  
   13.11          private void OnMonitorPowerOff()
   13.12          {
   13.13              MonitorPowerOn = false;
   13.14              //Trigger corresponding event thus executing associated actions
   13.15 -            ManagerEventAction.Current.GetEvent<EventMonitorPowerOff>().Trigger();
   13.16 +            ManagerEventAction.Current.TriggerEvent<EventMonitorPowerOff>();
   13.17          }
   13.18  
   13.19          /// <summary>
    14.1 --- a/Server/FormEditAction.Designer.cs	Sun Jul 31 12:03:52 2016 +0200
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,152 +0,0 @@
    14.4 -namespace SharpDisplayManager
    14.5 -{
    14.6 -    partial class FormEditAction
    14.7 -    {
    14.8 -        /// <summary>
    14.9 -        /// Required designer variable.
   14.10 -        /// </summary>
   14.11 -        private System.ComponentModel.IContainer components = null;
   14.12 -
   14.13 -        /// <summary>
   14.14 -        /// Clean up any resources being used.
   14.15 -        /// </summary>
   14.16 -        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   14.17 -        protected override void Dispose(bool disposing)
   14.18 -        {
   14.19 -            if (disposing && (components != null))
   14.20 -            {
   14.21 -                components.Dispose();
   14.22 -            }
   14.23 -            base.Dispose(disposing);
   14.24 -        }
   14.25 -
   14.26 -        #region Windows Form Designer generated code
   14.27 -
   14.28 -        /// <summary>
   14.29 -        /// Required method for Designer support - do not modify
   14.30 -        /// the contents of this method with the code editor.
   14.31 -        /// </summary>
   14.32 -        private void InitializeComponent()
   14.33 -        {
   14.34 -            this.components = new System.ComponentModel.Container();
   14.35 -            this.comboBoxActionType = new System.Windows.Forms.ComboBox();
   14.36 -            this.labelActionType = new System.Windows.Forms.Label();
   14.37 -            this.buttonOk = new System.Windows.Forms.Button();
   14.38 -            this.buttonCancel = new System.Windows.Forms.Button();
   14.39 -            this.iTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
   14.40 -            this.toolTip = new System.Windows.Forms.ToolTip(this.components);
   14.41 -            this.buttonTest = new System.Windows.Forms.Button();
   14.42 -            this.SuspendLayout();
   14.43 -            // 
   14.44 -            // comboBoxActionType
   14.45 -            // 
   14.46 -            this.comboBoxActionType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
   14.47 -            | System.Windows.Forms.AnchorStyles.Right)));
   14.48 -            this.comboBoxActionType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
   14.49 -            this.comboBoxActionType.FormattingEnabled = true;
   14.50 -            this.comboBoxActionType.Location = new System.Drawing.Point(55, 12);
   14.51 -            this.comboBoxActionType.Name = "comboBoxActionType";
   14.52 -            this.comboBoxActionType.Size = new System.Drawing.Size(272, 21);
   14.53 -            this.comboBoxActionType.Sorted = true;
   14.54 -            this.comboBoxActionType.TabIndex = 18;
   14.55 -            this.comboBoxActionType.SelectedIndexChanged += new System.EventHandler(this.comboBoxActionType_SelectedIndexChanged);
   14.56 -            // 
   14.57 -            // labelActionType
   14.58 -            // 
   14.59 -            this.labelActionType.AutoSize = true;
   14.60 -            this.labelActionType.Location = new System.Drawing.Point(12, 15);
   14.61 -            this.labelActionType.Name = "labelActionType";
   14.62 -            this.labelActionType.Size = new System.Drawing.Size(37, 13);
   14.63 -            this.labelActionType.TabIndex = 20;
   14.64 -            this.labelActionType.Text = "Type :";
   14.65 -            // 
   14.66 -            // buttonOk
   14.67 -            // 
   14.68 -            this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
   14.69 -            this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
   14.70 -            this.buttonOk.Location = new System.Drawing.Point(12, 72);
   14.71 -            this.buttonOk.Name = "buttonOk";
   14.72 -            this.buttonOk.Size = new System.Drawing.Size(75, 23);
   14.73 -            this.buttonOk.TabIndex = 21;
   14.74 -            this.buttonOk.Text = "Ok";
   14.75 -            this.buttonOk.UseVisualStyleBackColor = true;
   14.76 -            this.buttonOk.Click += new System.EventHandler(this.buttonOk_Click);
   14.77 -            // 
   14.78 -            // buttonCancel
   14.79 -            // 
   14.80 -            this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
   14.81 -            this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
   14.82 -            this.buttonCancel.Location = new System.Drawing.Point(93, 72);
   14.83 -            this.buttonCancel.Name = "buttonCancel";
   14.84 -            this.buttonCancel.Size = new System.Drawing.Size(75, 23);
   14.85 -            this.buttonCancel.TabIndex = 22;
   14.86 -            this.buttonCancel.Text = "Cancel";
   14.87 -            this.buttonCancel.UseVisualStyleBackColor = true;
   14.88 -            // 
   14.89 -            // iTableLayoutPanel
   14.90 -            // 
   14.91 -            this.iTableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
   14.92 -            | System.Windows.Forms.AnchorStyles.Left) 
   14.93 -            | System.Windows.Forms.AnchorStyles.Right)));
   14.94 -            this.iTableLayoutPanel.AutoSize = true;
   14.95 -            this.iTableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
   14.96 -            this.iTableLayoutPanel.ColumnCount = 2;
   14.97 -            this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
   14.98 -            this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
   14.99 -            this.iTableLayoutPanel.Location = new System.Drawing.Point(15, 50);
  14.100 -            this.iTableLayoutPanel.Name = "iTableLayoutPanel";
  14.101 -            this.iTableLayoutPanel.RowCount = 2;
  14.102 -            this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
  14.103 -            this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
  14.104 -            this.iTableLayoutPanel.Size = new System.Drawing.Size(312, 16);
  14.105 -            this.iTableLayoutPanel.TabIndex = 23;
  14.106 -            // 
  14.107 -            // buttonTest
  14.108 -            // 
  14.109 -            this.buttonTest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  14.110 -            this.buttonTest.Location = new System.Drawing.Point(252, 72);
  14.111 -            this.buttonTest.Name = "buttonTest";
  14.112 -            this.buttonTest.Size = new System.Drawing.Size(75, 23);
  14.113 -            this.buttonTest.TabIndex = 24;
  14.114 -            this.buttonTest.Text = "Test";
  14.115 -            this.buttonTest.UseVisualStyleBackColor = true;
  14.116 -            this.buttonTest.Click += new System.EventHandler(this.buttonTest_Click);
  14.117 -            // 
  14.118 -            // FormEditAction
  14.119 -            // 
  14.120 -            this.AcceptButton = this.buttonOk;
  14.121 -            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
  14.122 -            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  14.123 -            this.AutoSize = true;
  14.124 -            this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
  14.125 -            this.CancelButton = this.buttonCancel;
  14.126 -            this.ClientSize = new System.Drawing.Size(339, 107);
  14.127 -            this.Controls.Add(this.buttonTest);
  14.128 -            this.Controls.Add(this.iTableLayoutPanel);
  14.129 -            this.Controls.Add(this.buttonCancel);
  14.130 -            this.Controls.Add(this.buttonOk);
  14.131 -            this.Controls.Add(this.labelActionType);
  14.132 -            this.Controls.Add(this.comboBoxActionType);
  14.133 -            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
  14.134 -            this.MaximizeBox = false;
  14.135 -            this.MinimizeBox = false;
  14.136 -            this.Name = "FormEditAction";
  14.137 -            this.Text = "Edit action";
  14.138 -            this.Load += new System.EventHandler(this.FormEditAction_Load);
  14.139 -            this.Validating += new System.ComponentModel.CancelEventHandler(this.FormEditAction_Validating);
  14.140 -            this.ResumeLayout(false);
  14.141 -            this.PerformLayout();
  14.142 -
  14.143 -        }
  14.144 -
  14.145 -        #endregion
  14.146 -
  14.147 -        private System.Windows.Forms.ComboBox comboBoxActionType;
  14.148 -        private System.Windows.Forms.Label labelActionType;
  14.149 -        private System.Windows.Forms.Button buttonOk;
  14.150 -        private System.Windows.Forms.Button buttonCancel;
  14.151 -        private System.Windows.Forms.TableLayoutPanel iTableLayoutPanel;
  14.152 -        private System.Windows.Forms.ToolTip toolTip;
  14.153 -        private System.Windows.Forms.Button buttonTest;
  14.154 -    }
  14.155 -}
  14.156 \ No newline at end of file
    15.1 --- a/Server/FormEditAction.cs	Sun Jul 31 12:03:52 2016 +0200
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,325 +0,0 @@
    15.4 -using System;
    15.5 -using System.Collections.Generic;
    15.6 -using System.ComponentModel;
    15.7 -using System.Data;
    15.8 -using System.Diagnostics;
    15.9 -using System.Drawing;
   15.10 -using System.Linq;
   15.11 -using System.Text;
   15.12 -using System.Threading.Tasks;
   15.13 -using System.Windows.Forms;
   15.14 -using SharpLib.Display;
   15.15 -using SharpLib.Ear;
   15.16 -using System.Reflection;
   15.17 -
   15.18 -namespace SharpDisplayManager
   15.19 -{
   15.20 -    /// <summary>
   15.21 -    /// Action edit dialog form.
   15.22 -    /// </summary>
   15.23 -    public partial class FormEditAction : Form
   15.24 -    {
   15.25 -        public SharpLib.Ear.Action Action = null;
   15.26 -
   15.27 -        public FormEditAction()
   15.28 -        {
   15.29 -            InitializeComponent();
   15.30 -        }
   15.31 -
   15.32 -        /// <summary>
   15.33 -        /// 
   15.34 -        /// </summary>
   15.35 -        /// <param name="sender"></param>
   15.36 -        /// <param name="e"></param>
   15.37 -        private void FormEditAction_Load(object sender, EventArgs e)
   15.38 -        {
   15.39 -            // Populate registered actions
   15.40 -            foreach (string key in ManagerEventAction.Current.ActionTypes.Keys)
   15.41 -            {
   15.42 -                ItemActionType item = new ItemActionType(ManagerEventAction.Current.ActionTypes[key]);
   15.43 -                comboBoxActionType.Items.Add(item);
   15.44 -            }
   15.45 -
   15.46 -            if (Action == null)
   15.47 -            {
   15.48 -                // Creating new issue, select our first item
   15.49 -                comboBoxActionType.SelectedIndex = 0;
   15.50 -            }
   15.51 -            else
   15.52 -            {
   15.53 -                // Editing existing issue
   15.54 -                // Look up our item in our combobox 
   15.55 -                foreach (ItemActionType item in comboBoxActionType.Items)
   15.56 -                {
   15.57 -                    if (item.Type == Action.GetType())
   15.58 -                    {
   15.59 -                        comboBoxActionType.SelectedItem = item;
   15.60 -                    }
   15.61 -                }
   15.62 -            }            
   15.63 -        }
   15.64 -
   15.65 -        private void buttonOk_Click(object sender, EventArgs e)
   15.66 -        {
   15.67 -            FetchPropertiesValue(Action);
   15.68 -        }
   15.69 -
   15.70 -        private void FormEditAction_Validating(object sender, CancelEventArgs e)
   15.71 -        {
   15.72 -
   15.73 -        }
   15.74 -
   15.75 -        private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
   15.76 -        {
   15.77 -            //Instantiate an action corresponding to our type
   15.78 -            Type actionType = ((ItemActionType) comboBoxActionType.SelectedItem).Type;
   15.79 -            //Create another type of action only if needed
   15.80 -            if (Action == null || Action.GetType() != actionType)
   15.81 -            {
   15.82 -                Action = (SharpLib.Ear.Action)Activator.CreateInstance(actionType);
   15.83 -            }
   15.84 -            
   15.85 -            //Create input fields
   15.86 -            UpdateTableLayoutPanel(Action);
   15.87 -        }
   15.88 -
   15.89 -
   15.90 -        /// <summary>
   15.91 -        /// Get properties values from our generated input fields
   15.92 -        /// </summary>
   15.93 -        private void FetchPropertiesValue(SharpLib.Ear.Action aAction)
   15.94 -        {
   15.95 -            int ctrlIndex = 0;
   15.96 -            foreach (PropertyInfo pi in aAction.GetType().GetProperties())
   15.97 -            {
   15.98 -                AttributeActionProperty[] attributes =
   15.99 -                    ((AttributeActionProperty[]) pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
  15.100 -                if (attributes.Length != 1)
  15.101 -                {
  15.102 -                    continue;
  15.103 -                }
  15.104 -
  15.105 -                AttributeActionProperty attribute = attributes[0];
  15.106 -
  15.107 -                if (!IsPropertyTypeSupported(pi))
  15.108 -                {
  15.109 -                    continue;
  15.110 -                }
  15.111 -
  15.112 -                GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aAction); //+1 otherwise we get the label
  15.113 -
  15.114 -                ctrlIndex+=2; //Jump over the label too
  15.115 -            }
  15.116 -        }
  15.117 -
  15.118 -        /// <summary>
  15.119 -        /// Extend this function to support reading new types of properties.
  15.120 -        /// </summary>
  15.121 -        /// <param name="aAction"></param>
  15.122 -        private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, SharpLib.Ear.Action aAction)
  15.123 -        {
  15.124 -            if (aInfo.PropertyType == typeof(int))
  15.125 -            {
  15.126 -                NumericUpDown ctrl=(NumericUpDown)aControl;
  15.127 -                aInfo.SetValue(aAction,(int)ctrl.Value);
  15.128 -            }
  15.129 -            else if (aInfo.PropertyType.IsEnum)
  15.130 -            {
  15.131 -                // Instantiate our enum
  15.132 -                object enumValue= Activator.CreateInstance(aInfo.PropertyType);
  15.133 -                // Parse our enum from combo box
  15.134 -                enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
  15.135 -                //enumValue = ((ComboBox)aControl).SelectedValue;
  15.136 -                // Set enum value
  15.137 -                aInfo.SetValue(aAction, enumValue);
  15.138 -            }
  15.139 -            else if (aInfo.PropertyType == typeof(bool))
  15.140 -            {
  15.141 -                CheckBox ctrl = (CheckBox)aControl;
  15.142 -                aInfo.SetValue(aAction, ctrl.Checked);
  15.143 -            }
  15.144 -            else if (aInfo.PropertyType == typeof(string))
  15.145 -            {
  15.146 -                TextBox ctrl = (TextBox)aControl;
  15.147 -                aInfo.SetValue(aAction, ctrl.Text);
  15.148 -            }
  15.149 -            //TODO: add support for other types here
  15.150 -        }
  15.151 -
  15.152 -        /// <summary>
  15.153 -        /// 
  15.154 -        /// </summary>
  15.155 -        /// <param name="aInfo"></param>
  15.156 -        /// <param name="action"></param>
  15.157 -        private Control CreateControlForProperty(PropertyInfo aInfo, AttributeActionProperty aAttribute, SharpLib.Ear.Action aAction)
  15.158 -        {
  15.159 -            if (aInfo.PropertyType == typeof(int))
  15.160 -            {
  15.161 -                //Integer properties are using numeric editor
  15.162 -                NumericUpDown ctrl = new NumericUpDown();
  15.163 -                ctrl.AutoSize = true;
  15.164 -                ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
  15.165 -                ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
  15.166 -                ctrl.Increment = Int32.Parse(aAttribute.Increment);
  15.167 -                ctrl.Value = (int)aInfo.GetValue(aAction);
  15.168 -                return ctrl;
  15.169 -            }
  15.170 -            else if (aInfo.PropertyType.IsEnum)
  15.171 -            {
  15.172 -                //Enum properties are using combo box
  15.173 -                ComboBox ctrl = new ComboBox();
  15.174 -                ctrl.AutoSize = true;                
  15.175 -                ctrl.Sorted = true;                
  15.176 -                ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
  15.177 -                //Data source is fine but it gives us duplicate entries for duplicated enum values
  15.178 -                //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
  15.179 -
  15.180 -                //Therefore we need to explicitly create our items
  15.181 -                Size cbSize = new Size(0,0);
  15.182 -                foreach (string name in aInfo.PropertyType.GetEnumNames())
  15.183 -                {
  15.184 -                    ctrl.Items.Add(name.ToString());
  15.185 -                    Graphics g = this.CreateGraphics();
  15.186 -                    //Since combobox autosize would not work we need to get measure text ourselves
  15.187 -                    SizeF size=g.MeasureString(name.ToString(), ctrl.Font);
  15.188 -                    cbSize.Width = Math.Max(cbSize.Width,(int)size.Width);
  15.189 -                    cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
  15.190 -                }
  15.191 -
  15.192 -                //Make sure our combobox is large enough
  15.193 -                ctrl.MinimumSize = cbSize;
  15.194 -
  15.195 -                // Instantiate our enum
  15.196 -                object enumValue = Activator.CreateInstance(aInfo.PropertyType);
  15.197 -                enumValue = aInfo.GetValue(aAction);
  15.198 -                //Set the current item
  15.199 -                ctrl.SelectedItem = enumValue.ToString();
  15.200 -
  15.201 -                return ctrl;
  15.202 -            }
  15.203 -            else if (aInfo.PropertyType == typeof(bool))
  15.204 -            {
  15.205 -                CheckBox ctrl = new CheckBox();
  15.206 -                ctrl.AutoSize = true;
  15.207 -                ctrl.Text = aAttribute.Description;
  15.208 -                ctrl.Checked = (bool)aInfo.GetValue(aAction);                
  15.209 -                return ctrl;
  15.210 -            }
  15.211 -            else if (aInfo.PropertyType == typeof(string))
  15.212 -            {
  15.213 -                TextBox ctrl = new TextBox();
  15.214 -                ctrl.AutoSize = true;
  15.215 -                ctrl.Text = (string)aInfo.GetValue(aAction);
  15.216 -                return ctrl;
  15.217 -            }
  15.218 -            //TODO: add support for other control type here
  15.219 -
  15.220 -            return null;
  15.221 -        }
  15.222 -
  15.223 -        /// <summary>
  15.224 -        /// Don't forget to extend that one and adding types
  15.225 -        /// </summary>
  15.226 -        /// <returns></returns>
  15.227 -        private bool IsPropertyTypeSupported(PropertyInfo aInfo)
  15.228 -        {
  15.229 -            if (aInfo.PropertyType == typeof(int))
  15.230 -            {
  15.231 -                return true;
  15.232 -            }
  15.233 -            else if (aInfo.PropertyType.IsEnum)
  15.234 -            {
  15.235 -                return true;
  15.236 -            }
  15.237 -            else if (aInfo.PropertyType == typeof(bool))
  15.238 -            {
  15.239 -                return true;
  15.240 -            }
  15.241 -            else if (aInfo.PropertyType == typeof(string))
  15.242 -            {
  15.243 -                return true;
  15.244 -            }
  15.245 -            //TODO: add support for other type here
  15.246 -
  15.247 -            return false;
  15.248 -        }
  15.249 -
  15.250 -        /// <summary>
  15.251 -        /// Update our table layout.
  15.252 -        /// Will instantiated every field control as defined by our action.
  15.253 -        /// Fields must be specified by rows from the left.
  15.254 -        /// </summary>
  15.255 -        /// <param name="aLayout"></param>
  15.256 -        private void UpdateTableLayoutPanel(SharpLib.Ear.Action aAction)
  15.257 -        {
  15.258 -            toolTip.RemoveAll();
  15.259 -            //Debug.Print("UpdateTableLayoutPanel")
  15.260 -            //First clean our current panel
  15.261 -            iTableLayoutPanel.Controls.Clear();
  15.262 -            iTableLayoutPanel.RowStyles.Clear();
  15.263 -            iTableLayoutPanel.ColumnStyles.Clear();
  15.264 -            iTableLayoutPanel.RowCount = 0;
  15.265 -
  15.266 -            //We always want two columns: one for label and one for the field
  15.267 -            iTableLayoutPanel.ColumnCount = 2;
  15.268 -            iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
  15.269 -            iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
  15.270 -
  15.271 -
  15.272 -            if (aAction == null)
  15.273 -            {
  15.274 -                //Just drop it
  15.275 -                return;
  15.276 -            }
  15.277 -            
  15.278 -            //IEnumerable<PropertyInfo> properties = aAction.GetType().GetProperties().Where(
  15.279 -            //    prop => Attribute.IsDefined(prop, typeof(AttributeActionProperty)));
  15.280 -
  15.281 -
  15.282 -            foreach (PropertyInfo pi in aAction.GetType().GetProperties())
  15.283 -            {
  15.284 -                AttributeActionProperty[] attributes = ((AttributeActionProperty[])pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
  15.285 -                if (attributes.Length != 1)
  15.286 -                {
  15.287 -                    continue;
  15.288 -                }
  15.289 -
  15.290 -                AttributeActionProperty attribute = attributes[0];
  15.291 -
  15.292 -                //Before anything we need to check if that kind of property is supported by our UI
  15.293 -                //Create the editor
  15.294 -                Control ctrl = CreateControlForProperty(pi, attribute, aAction);
  15.295 -                if (ctrl == null)
  15.296 -                {
  15.297 -                    //Property type not supported
  15.298 -                    continue;
  15.299 -                }
  15.300 -
  15.301 -                //Add a new row
  15.302 -                iTableLayoutPanel.RowCount++;
  15.303 -                iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
  15.304 -                //Create the label
  15.305 -                Label label = new Label();
  15.306 -                label.AutoSize = true;
  15.307 -                label.Dock = DockStyle.Fill;
  15.308 -                label.TextAlign = ContentAlignment.MiddleCenter;
  15.309 -                label.Text = attribute.Name;
  15.310 -                toolTip.SetToolTip(label, attribute.Description);
  15.311 -                iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
  15.312 -
  15.313 -                //Add our editor to our form
  15.314 -                iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
  15.315 -                //Add tooltip to editor too
  15.316 -                toolTip.SetToolTip(ctrl, attribute.Description);
  15.317 -
  15.318 -            }        
  15.319 -
  15.320 -        }
  15.321 -
  15.322 -        private void buttonTest_Click(object sender, EventArgs e)
  15.323 -        {
  15.324 -            FetchPropertiesValue(Action);
  15.325 -            Action.Execute();
  15.326 -        }
  15.327 -    }
  15.328 -}
    16.1 --- a/Server/FormEditAction.resx	Sun Jul 31 12:03:52 2016 +0200
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,123 +0,0 @@
    16.4 -<?xml version="1.0" encoding="utf-8"?>
    16.5 -<root>
    16.6 -  <!-- 
    16.7 -    Microsoft ResX Schema 
    16.8 -    
    16.9 -    Version 2.0
   16.10 -    
   16.11 -    The primary goals of this format is to allow a simple XML format 
   16.12 -    that is mostly human readable. The generation and parsing of the 
   16.13 -    various data types are done through the TypeConverter classes 
   16.14 -    associated with the data types.
   16.15 -    
   16.16 -    Example:
   16.17 -    
   16.18 -    ... ado.net/XML headers & schema ...
   16.19 -    <resheader name="resmimetype">text/microsoft-resx</resheader>
   16.20 -    <resheader name="version">2.0</resheader>
   16.21 -    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
   16.22 -    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
   16.23 -    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
   16.24 -    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
   16.25 -    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
   16.26 -        <value>[base64 mime encoded serialized .NET Framework object]</value>
   16.27 -    </data>
   16.28 -    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
   16.29 -        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
   16.30 -        <comment>This is a comment</comment>
   16.31 -    </data>
   16.32 -                
   16.33 -    There are any number of "resheader" rows that contain simple 
   16.34 -    name/value pairs.
   16.35 -    
   16.36 -    Each data row contains a name, and value. The row also contains a 
   16.37 -    type or mimetype. Type corresponds to a .NET class that support 
   16.38 -    text/value conversion through the TypeConverter architecture. 
   16.39 -    Classes that don't support this are serialized and stored with the 
   16.40 -    mimetype set.
   16.41 -    
   16.42 -    The mimetype is used for serialized objects, and tells the 
   16.43 -    ResXResourceReader how to depersist the object. This is currently not 
   16.44 -    extensible. For a given mimetype the value must be set accordingly:
   16.45 -    
   16.46 -    Note - application/x-microsoft.net.object.binary.base64 is the format 
   16.47 -    that the ResXResourceWriter will generate, however the reader can 
   16.48 -    read any of the formats listed below.
   16.49 -    
   16.50 -    mimetype: application/x-microsoft.net.object.binary.base64
   16.51 -    value   : The object must be serialized with 
   16.52 -            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
   16.53 -            : and then encoded with base64 encoding.
   16.54 -    
   16.55 -    mimetype: application/x-microsoft.net.object.soap.base64
   16.56 -    value   : The object must be serialized with 
   16.57 -            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
   16.58 -            : and then encoded with base64 encoding.
   16.59 -
   16.60 -    mimetype: application/x-microsoft.net.object.bytearray.base64
   16.61 -    value   : The object must be serialized into a byte array 
   16.62 -            : using a System.ComponentModel.TypeConverter
   16.63 -            : and then encoded with base64 encoding.
   16.64 -    -->
   16.65 -  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
   16.66 -    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
   16.67 -    <xsd:element name="root" msdata:IsDataSet="true">
   16.68 -      <xsd:complexType>
   16.69 -        <xsd:choice maxOccurs="unbounded">
   16.70 -          <xsd:element name="metadata">
   16.71 -            <xsd:complexType>
   16.72 -              <xsd:sequence>
   16.73 -                <xsd:element name="value" type="xsd:string" minOccurs="0" />
   16.74 -              </xsd:sequence>
   16.75 -              <xsd:attribute name="name" use="required" type="xsd:string" />
   16.76 -              <xsd:attribute name="type" type="xsd:string" />
   16.77 -              <xsd:attribute name="mimetype" type="xsd:string" />
   16.78 -              <xsd:attribute ref="xml:space" />
   16.79 -            </xsd:complexType>
   16.80 -          </xsd:element>
   16.81 -          <xsd:element name="assembly">
   16.82 -            <xsd:complexType>
   16.83 -              <xsd:attribute name="alias" type="xsd:string" />
   16.84 -              <xsd:attribute name="name" type="xsd:string" />
   16.85 -            </xsd:complexType>
   16.86 -          </xsd:element>
   16.87 -          <xsd:element name="data">
   16.88 -            <xsd:complexType>
   16.89 -              <xsd:sequence>
   16.90 -                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
   16.91 -                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
   16.92 -              </xsd:sequence>
   16.93 -              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
   16.94 -              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
   16.95 -              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
   16.96 -              <xsd:attribute ref="xml:space" />
   16.97 -            </xsd:complexType>
   16.98 -          </xsd:element>
   16.99 -          <xsd:element name="resheader">
  16.100 -            <xsd:complexType>
  16.101 -              <xsd:sequence>
  16.102 -                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
  16.103 -              </xsd:sequence>
  16.104 -              <xsd:attribute name="name" type="xsd:string" use="required" />
  16.105 -            </xsd:complexType>
  16.106 -          </xsd:element>
  16.107 -        </xsd:choice>
  16.108 -      </xsd:complexType>
  16.109 -    </xsd:element>
  16.110 -  </xsd:schema>
  16.111 -  <resheader name="resmimetype">
  16.112 -    <value>text/microsoft-resx</value>
  16.113 -  </resheader>
  16.114 -  <resheader name="version">
  16.115 -    <value>2.0</value>
  16.116 -  </resheader>
  16.117 -  <resheader name="reader">
  16.118 -    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  16.119 -  </resheader>
  16.120 -  <resheader name="writer">
  16.121 -    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  16.122 -  </resheader>
  16.123 -  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
  16.124 -    <value>17, 17</value>
  16.125 -  </metadata>
  16.126 -</root>
  16.127 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/Server/FormEditObject.Designer.cs	Fri Aug 12 20:25:05 2016 +0200
    17.3 @@ -0,0 +1,152 @@
    17.4 +namespace SharpDisplayManager
    17.5 +{
    17.6 +    partial class FormEditObject<T>
    17.7 +    {
    17.8 +        /// <summary>
    17.9 +        /// Required designer variable.
   17.10 +        /// </summary>
   17.11 +        private System.ComponentModel.IContainer components = null;
   17.12 +
   17.13 +        /// <summary>
   17.14 +        /// Clean up any resources being used.
   17.15 +        /// </summary>
   17.16 +        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   17.17 +        protected override void Dispose(bool disposing)
   17.18 +        {
   17.19 +            if (disposing && (components != null))
   17.20 +            {
   17.21 +                components.Dispose();
   17.22 +            }
   17.23 +            base.Dispose(disposing);
   17.24 +        }
   17.25 +
   17.26 +        #region Windows Form Designer generated code
   17.27 +
   17.28 +        /// <summary>
   17.29 +        /// Required method for Designer support - do not modify
   17.30 +        /// the contents of this method with the code editor.
   17.31 +        /// </summary>
   17.32 +        private void InitializeComponent()
   17.33 +        {
   17.34 +            this.components = new System.ComponentModel.Container();
   17.35 +            this.comboBoxActionType = new System.Windows.Forms.ComboBox();
   17.36 +            this.labelActionType = new System.Windows.Forms.Label();
   17.37 +            this.buttonOk = new System.Windows.Forms.Button();
   17.38 +            this.buttonCancel = new System.Windows.Forms.Button();
   17.39 +            this.iTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
   17.40 +            this.toolTip = new System.Windows.Forms.ToolTip(this.components);
   17.41 +            this.buttonTest = new System.Windows.Forms.Button();
   17.42 +            this.SuspendLayout();
   17.43 +            // 
   17.44 +            // comboBoxActionType
   17.45 +            // 
   17.46 +            this.comboBoxActionType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
   17.47 +            | System.Windows.Forms.AnchorStyles.Right)));
   17.48 +            this.comboBoxActionType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
   17.49 +            this.comboBoxActionType.FormattingEnabled = true;
   17.50 +            this.comboBoxActionType.Location = new System.Drawing.Point(55, 12);
   17.51 +            this.comboBoxActionType.Name = "comboBoxActionType";
   17.52 +            this.comboBoxActionType.Size = new System.Drawing.Size(272, 21);
   17.53 +            this.comboBoxActionType.Sorted = true;
   17.54 +            this.comboBoxActionType.TabIndex = 18;
   17.55 +            this.comboBoxActionType.SelectedIndexChanged += new System.EventHandler(this.comboBoxActionType_SelectedIndexChanged);
   17.56 +            // 
   17.57 +            // labelActionType
   17.58 +            // 
   17.59 +            this.labelActionType.AutoSize = true;
   17.60 +            this.labelActionType.Location = new System.Drawing.Point(12, 15);
   17.61 +            this.labelActionType.Name = "labelActionType";
   17.62 +            this.labelActionType.Size = new System.Drawing.Size(37, 13);
   17.63 +            this.labelActionType.TabIndex = 20;
   17.64 +            this.labelActionType.Text = "Type :";
   17.65 +            // 
   17.66 +            // buttonOk
   17.67 +            // 
   17.68 +            this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
   17.69 +            this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
   17.70 +            this.buttonOk.Location = new System.Drawing.Point(12, 72);
   17.71 +            this.buttonOk.Name = "buttonOk";
   17.72 +            this.buttonOk.Size = new System.Drawing.Size(75, 23);
   17.73 +            this.buttonOk.TabIndex = 21;
   17.74 +            this.buttonOk.Text = "Ok";
   17.75 +            this.buttonOk.UseVisualStyleBackColor = true;
   17.76 +            this.buttonOk.Click += new System.EventHandler(this.buttonOk_Click);
   17.77 +            // 
   17.78 +            // buttonCancel
   17.79 +            // 
   17.80 +            this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
   17.81 +            this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
   17.82 +            this.buttonCancel.Location = new System.Drawing.Point(93, 72);
   17.83 +            this.buttonCancel.Name = "buttonCancel";
   17.84 +            this.buttonCancel.Size = new System.Drawing.Size(75, 23);
   17.85 +            this.buttonCancel.TabIndex = 22;
   17.86 +            this.buttonCancel.Text = "Cancel";
   17.87 +            this.buttonCancel.UseVisualStyleBackColor = true;
   17.88 +            // 
   17.89 +            // iTableLayoutPanel
   17.90 +            // 
   17.91 +            this.iTableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
   17.92 +            | System.Windows.Forms.AnchorStyles.Left) 
   17.93 +            | System.Windows.Forms.AnchorStyles.Right)));
   17.94 +            this.iTableLayoutPanel.AutoSize = true;
   17.95 +            this.iTableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
   17.96 +            this.iTableLayoutPanel.ColumnCount = 2;
   17.97 +            this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
   17.98 +            this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
   17.99 +            this.iTableLayoutPanel.Location = new System.Drawing.Point(15, 50);
  17.100 +            this.iTableLayoutPanel.Name = "iTableLayoutPanel";
  17.101 +            this.iTableLayoutPanel.RowCount = 2;
  17.102 +            this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
  17.103 +            this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
  17.104 +            this.iTableLayoutPanel.Size = new System.Drawing.Size(312, 16);
  17.105 +            this.iTableLayoutPanel.TabIndex = 23;
  17.106 +            // 
  17.107 +            // buttonTest
  17.108 +            // 
  17.109 +            this.buttonTest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  17.110 +            this.buttonTest.Location = new System.Drawing.Point(252, 72);
  17.111 +            this.buttonTest.Name = "buttonTest";
  17.112 +            this.buttonTest.Size = new System.Drawing.Size(75, 23);
  17.113 +            this.buttonTest.TabIndex = 24;
  17.114 +            this.buttonTest.Text = "Test";
  17.115 +            this.buttonTest.UseVisualStyleBackColor = true;
  17.116 +            this.buttonTest.Click += new System.EventHandler(this.buttonTest_Click);
  17.117 +            // 
  17.118 +            // FormEditAction
  17.119 +            // 
  17.120 +            this.AcceptButton = this.buttonOk;
  17.121 +            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
  17.122 +            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  17.123 +            this.AutoSize = true;
  17.124 +            this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
  17.125 +            this.CancelButton = this.buttonCancel;
  17.126 +            this.ClientSize = new System.Drawing.Size(339, 107);
  17.127 +            this.Controls.Add(this.buttonTest);
  17.128 +            this.Controls.Add(this.iTableLayoutPanel);
  17.129 +            this.Controls.Add(this.buttonCancel);
  17.130 +            this.Controls.Add(this.buttonOk);
  17.131 +            this.Controls.Add(this.labelActionType);
  17.132 +            this.Controls.Add(this.comboBoxActionType);
  17.133 +            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
  17.134 +            this.MaximizeBox = false;
  17.135 +            this.MinimizeBox = false;
  17.136 +            this.Name = "FormEditAction";
  17.137 +            this.Text = "Edit action";
  17.138 +            this.Load += new System.EventHandler(this.FormEditAction_Load);
  17.139 +            this.Validating += new System.ComponentModel.CancelEventHandler(this.FormEditAction_Validating);
  17.140 +            this.ResumeLayout(false);
  17.141 +            this.PerformLayout();
  17.142 +
  17.143 +        }
  17.144 +
  17.145 +        #endregion
  17.146 +
  17.147 +        private System.Windows.Forms.ComboBox comboBoxActionType;
  17.148 +        private System.Windows.Forms.Label labelActionType;
  17.149 +        private System.Windows.Forms.Button buttonOk;
  17.150 +        private System.Windows.Forms.Button buttonCancel;
  17.151 +        private System.Windows.Forms.TableLayoutPanel iTableLayoutPanel;
  17.152 +        private System.Windows.Forms.ToolTip toolTip;
  17.153 +        private System.Windows.Forms.Button buttonTest;
  17.154 +    }
  17.155 +}
  17.156 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/Server/FormEditObject.cs	Fri Aug 12 20:25:05 2016 +0200
    18.3 @@ -0,0 +1,335 @@
    18.4 +using System;
    18.5 +using System.Collections.Generic;
    18.6 +using System.ComponentModel;
    18.7 +using System.Data;
    18.8 +using System.Diagnostics;
    18.9 +using System.Drawing;
   18.10 +using System.Linq;
   18.11 +using System.Text;
   18.12 +using System.Threading.Tasks;
   18.13 +using System.Windows.Forms;
   18.14 +using SharpLib.Display;
   18.15 +using SharpLib.Ear;
   18.16 +using System.Reflection;
   18.17 +using Microsoft.VisualBasic.CompilerServices;
   18.18 +using SharpLib.Utils;
   18.19 +
   18.20 +namespace SharpDisplayManager
   18.21 +{
   18.22 +    /// <summary>
   18.23 +    /// Object edit dialog form.
   18.24 +    /// </summary>
   18.25 +    public partial class FormEditObject<T> : Form where T : class
   18.26 +    {
   18.27 +        public T Object = null;
   18.28 +
   18.29 +        public FormEditObject()
   18.30 +        {
   18.31 +            InitializeComponent();
   18.32 +        }
   18.33 +
   18.34 +        /// <summary>
   18.35 +        /// 
   18.36 +        /// </summary>
   18.37 +        /// <param name="sender"></param>
   18.38 +        /// <param name="e"></param>
   18.39 +        private void FormEditAction_Load(object sender, EventArgs e)
   18.40 +        {
   18.41 +            // Populate registered actions
   18.42 +            IEnumerable < Type > types = Reflection.GetConcreteClassesDerivedFrom<T>();
   18.43 +            foreach (Type type in types)
   18.44 +            {
   18.45 +                ItemObjectType item = new ItemObjectType(type);
   18.46 +                comboBoxActionType.Items.Add(item);
   18.47 +            }
   18.48 +
   18.49 +            if (Object == null)
   18.50 +            {
   18.51 +                // Creating new issue, select our first item
   18.52 +                comboBoxActionType.SelectedIndex = 0;
   18.53 +            }
   18.54 +            else
   18.55 +            {
   18.56 +                // Editing existing object
   18.57 +                // Look up our item in our combobox 
   18.58 +                foreach (ItemObjectType item in comboBoxActionType.Items)
   18.59 +                {
   18.60 +                    if (item.Type == Object.GetType())
   18.61 +                    {
   18.62 +                        comboBoxActionType.SelectedItem = item;
   18.63 +                    }
   18.64 +                }
   18.65 +            }            
   18.66 +        }
   18.67 +
   18.68 +        private void buttonOk_Click(object sender, EventArgs e)
   18.69 +        {
   18.70 +            FetchPropertiesValue(Object);
   18.71 +        }
   18.72 +
   18.73 +        private void FormEditAction_Validating(object sender, CancelEventArgs e)
   18.74 +        {
   18.75 +
   18.76 +        }
   18.77 +
   18.78 +        private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
   18.79 +        {
   18.80 +            //Instantiate an action corresponding to our type
   18.81 +            Type actionType = ((ItemObjectType) comboBoxActionType.SelectedItem).Type;
   18.82 +            //Create another type of action only if needed
   18.83 +            if (Object == null || Object.GetType() != actionType)
   18.84 +            {
   18.85 +                Object = (T)Activator.CreateInstance(actionType);
   18.86 +            }
   18.87 +            
   18.88 +            //Create input fields
   18.89 +            UpdateTableLayoutPanel(Object);
   18.90 +        }
   18.91 +
   18.92 +
   18.93 +        /// <summary>
   18.94 +        /// Get properties values from our generated input fields
   18.95 +        /// </summary>
   18.96 +        private void FetchPropertiesValue(T aAction)
   18.97 +        {
   18.98 +            int ctrlIndex = 0;
   18.99 +            foreach (PropertyInfo pi in aAction.GetType().GetProperties())
  18.100 +            {
  18.101 +                AttributeObjectProperty[] attributes =
  18.102 +                    ((AttributeObjectProperty[]) pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
  18.103 +                if (attributes.Length != 1)
  18.104 +                {
  18.105 +                    continue;
  18.106 +                }
  18.107 +
  18.108 +                AttributeObjectProperty attribute = attributes[0];
  18.109 +
  18.110 +                if (!IsPropertyTypeSupported(pi))
  18.111 +                {
  18.112 +                    continue;
  18.113 +                }
  18.114 +
  18.115 +                GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aAction); //+1 otherwise we get the label
  18.116 +
  18.117 +                ctrlIndex+=2; //Jump over the label too
  18.118 +            }
  18.119 +        }
  18.120 +
  18.121 +        /// <summary>
  18.122 +        /// Extend this function to support reading new types of properties.
  18.123 +        /// </summary>
  18.124 +        /// <param name="aAction"></param>
  18.125 +        private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, T aAction)
  18.126 +        {
  18.127 +            if (aInfo.PropertyType == typeof(int))
  18.128 +            {
  18.129 +                NumericUpDown ctrl=(NumericUpDown)aControl;
  18.130 +                aInfo.SetValue(aAction,(int)ctrl.Value);
  18.131 +            }
  18.132 +            else if (aInfo.PropertyType.IsEnum)
  18.133 +            {
  18.134 +                // Instantiate our enum
  18.135 +                object enumValue= Activator.CreateInstance(aInfo.PropertyType);
  18.136 +                // Parse our enum from combo box
  18.137 +                enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
  18.138 +                //enumValue = ((ComboBox)aControl).SelectedValue;
  18.139 +                // Set enum value
  18.140 +                aInfo.SetValue(aAction, enumValue);
  18.141 +            }
  18.142 +            else if (aInfo.PropertyType == typeof(bool))
  18.143 +            {
  18.144 +                CheckBox ctrl = (CheckBox)aControl;
  18.145 +                aInfo.SetValue(aAction, ctrl.Checked);
  18.146 +            }
  18.147 +            else if (aInfo.PropertyType == typeof(string))
  18.148 +            {
  18.149 +                TextBox ctrl = (TextBox)aControl;
  18.150 +                aInfo.SetValue(aAction, ctrl.Text);
  18.151 +            }
  18.152 +            //TODO: add support for other types here
  18.153 +        }
  18.154 +
  18.155 +        /// <summary>
  18.156 +        /// 
  18.157 +        /// </summary>
  18.158 +        /// <param name="aInfo"></param>
  18.159 +        /// <param name="action"></param>
  18.160 +        private Control CreateControlForProperty(PropertyInfo aInfo, AttributeObjectProperty aAttribute, T aAction)
  18.161 +        {
  18.162 +            if (aInfo.PropertyType == typeof(int))
  18.163 +            {
  18.164 +                //Integer properties are using numeric editor
  18.165 +                NumericUpDown ctrl = new NumericUpDown();
  18.166 +                ctrl.AutoSize = true;
  18.167 +                ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
  18.168 +                ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
  18.169 +                ctrl.Increment = Int32.Parse(aAttribute.Increment);
  18.170 +                ctrl.Value = (int)aInfo.GetValue(aAction);
  18.171 +                return ctrl;
  18.172 +            }
  18.173 +            else if (aInfo.PropertyType.IsEnum)
  18.174 +            {
  18.175 +                //Enum properties are using combo box
  18.176 +                ComboBox ctrl = new ComboBox();
  18.177 +                ctrl.AutoSize = true;                
  18.178 +                ctrl.Sorted = true;                
  18.179 +                ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
  18.180 +                //Data source is fine but it gives us duplicate entries for duplicated enum values
  18.181 +                //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
  18.182 +
  18.183 +                //Therefore we need to explicitly create our items
  18.184 +                Size cbSize = new Size(0,0);
  18.185 +                foreach (string name in aInfo.PropertyType.GetEnumNames())
  18.186 +                {
  18.187 +                    ctrl.Items.Add(name.ToString());
  18.188 +                    Graphics g = this.CreateGraphics();
  18.189 +                    //Since combobox autosize would not work we need to get measure text ourselves
  18.190 +                    SizeF size=g.MeasureString(name.ToString(), ctrl.Font);
  18.191 +                    cbSize.Width = Math.Max(cbSize.Width,(int)size.Width);
  18.192 +                    cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
  18.193 +                }
  18.194 +
  18.195 +                //Make sure our combobox is large enough
  18.196 +                ctrl.MinimumSize = cbSize;
  18.197 +
  18.198 +                // Instantiate our enum
  18.199 +                object enumValue = Activator.CreateInstance(aInfo.PropertyType);
  18.200 +                enumValue = aInfo.GetValue(aAction);
  18.201 +                //Set the current item
  18.202 +                ctrl.SelectedItem = enumValue.ToString();
  18.203 +
  18.204 +                return ctrl;
  18.205 +            }
  18.206 +            else if (aInfo.PropertyType == typeof(bool))
  18.207 +            {
  18.208 +                CheckBox ctrl = new CheckBox();
  18.209 +                ctrl.AutoSize = true;
  18.210 +                ctrl.Text = aAttribute.Description;
  18.211 +                ctrl.Checked = (bool)aInfo.GetValue(aAction);                
  18.212 +                return ctrl;
  18.213 +            }
  18.214 +            else if (aInfo.PropertyType == typeof(string))
  18.215 +            {
  18.216 +                TextBox ctrl = new TextBox();
  18.217 +                ctrl.AutoSize = true;
  18.218 +                ctrl.Text = (string)aInfo.GetValue(aAction);
  18.219 +                return ctrl;
  18.220 +            }
  18.221 +            //TODO: add support for other control type here
  18.222 +
  18.223 +            return null;
  18.224 +        }
  18.225 +
  18.226 +        /// <summary>
  18.227 +        /// Don't forget to extend that one and adding types
  18.228 +        /// </summary>
  18.229 +        /// <returns></returns>
  18.230 +        private bool IsPropertyTypeSupported(PropertyInfo aInfo)
  18.231 +        {
  18.232 +            if (aInfo.PropertyType == typeof(int))
  18.233 +            {
  18.234 +                return true;
  18.235 +            }
  18.236 +            else if (aInfo.PropertyType.IsEnum)
  18.237 +            {
  18.238 +                return true;
  18.239 +            }
  18.240 +            else if (aInfo.PropertyType == typeof(bool))
  18.241 +            {
  18.242 +                return true;
  18.243 +            }
  18.244 +            else if (aInfo.PropertyType == typeof(string))
  18.245 +            {
  18.246 +                return true;
  18.247 +            }
  18.248 +            //TODO: add support for other type here
  18.249 +
  18.250 +            return false;
  18.251 +        }
  18.252 +
  18.253 +        /// <summary>
  18.254 +        /// Update our table layout.
  18.255 +        /// Will instantiated every field control as defined by our action.
  18.256 +        /// Fields must be specified by rows from the left.
  18.257 +        /// </summary>
  18.258 +        /// <param name="aLayout"></param>
  18.259 +        private void UpdateTableLayoutPanel(T aAction)
  18.260 +        {
  18.261 +            toolTip.RemoveAll();
  18.262 +            //Debug.Print("UpdateTableLayoutPanel")
  18.263 +            //First clean our current panel
  18.264 +            iTableLayoutPanel.Controls.Clear();
  18.265 +            iTableLayoutPanel.RowStyles.Clear();
  18.266 +            iTableLayoutPanel.ColumnStyles.Clear();
  18.267 +            iTableLayoutPanel.RowCount = 0;
  18.268 +
  18.269 +            //We always want two columns: one for label and one for the field
  18.270 +            iTableLayoutPanel.ColumnCount = 2;
  18.271 +            iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
  18.272 +            iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
  18.273 +
  18.274 +
  18.275 +            if (aAction == null)
  18.276 +            {
  18.277 +                //Just drop it
  18.278 +                return;
  18.279 +            }
  18.280 +            
  18.281 +            //IEnumerable<PropertyInfo> properties = aAction.GetType().GetProperties().Where(
  18.282 +            //    prop => Attribute.IsDefined(prop, typeof(AttributeObjectProperty)));
  18.283 +
  18.284 +
  18.285 +            foreach (PropertyInfo pi in aAction.GetType().GetProperties())
  18.286 +            {
  18.287 +                AttributeObjectProperty[] attributes = ((AttributeObjectProperty[])pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
  18.288 +                if (attributes.Length != 1)
  18.289 +                {
  18.290 +                    continue;
  18.291 +                }
  18.292 +
  18.293 +                AttributeObjectProperty attribute = attributes[0];
  18.294 +
  18.295 +                //Before anything we need to check if that kind of property is supported by our UI
  18.296 +                //Create the editor
  18.297 +                Control ctrl = CreateControlForProperty(pi, attribute, aAction);
  18.298 +                if (ctrl == null)
  18.299 +                {
  18.300 +                    //Property type not supported
  18.301 +                    continue;
  18.302 +                }
  18.303 +
  18.304 +                //Add a new row
  18.305 +                iTableLayoutPanel.RowCount++;
  18.306 +                iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
  18.307 +                //Create the label
  18.308 +                Label label = new Label();
  18.309 +                label.AutoSize = true;
  18.310 +                label.Dock = DockStyle.Fill;
  18.311 +                label.TextAlign = ContentAlignment.MiddleCenter;
  18.312 +                label.Text = attribute.Name;
  18.313 +                toolTip.SetToolTip(label, attribute.Description);
  18.314 +                iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
  18.315 +
  18.316 +                //Add our editor to our form
  18.317 +                iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
  18.318 +                //Add tooltip to editor too
  18.319 +                toolTip.SetToolTip(ctrl, attribute.Description);
  18.320 +
  18.321 +            }        
  18.322 +
  18.323 +        }
  18.324 +
  18.325 +        private void buttonTest_Click(object sender, EventArgs e)
  18.326 +        {
  18.327 +            FetchPropertiesValue(Object);
  18.328 +
  18.329 +            //If our object has a test method with no parameters just run it then
  18.330 +            MethodInfo info = Object.GetType().GetMethod("Test");
  18.331 +            if ( info != null && info.GetParameters().Length==0)
  18.332 +            {
  18.333 +                info.Invoke(Object,null);
  18.334 +            }
  18.335 +
  18.336 +        }
  18.337 +    }
  18.338 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/Server/FormEditObject.resx	Fri Aug 12 20:25:05 2016 +0200
    19.3 @@ -0,0 +1,123 @@
    19.4 +<?xml version="1.0" encoding="utf-8"?>
    19.5 +<root>
    19.6 +  <!-- 
    19.7 +    Microsoft ResX Schema 
    19.8 +    
    19.9 +    Version 2.0
   19.10 +    
   19.11 +    The primary goals of this format is to allow a simple XML format 
   19.12 +    that is mostly human readable. The generation and parsing of the 
   19.13 +    various data types are done through the TypeConverter classes 
   19.14 +    associated with the data types.
   19.15 +    
   19.16 +    Example:
   19.17 +    
   19.18 +    ... ado.net/XML headers & schema ...
   19.19 +    <resheader name="resmimetype">text/microsoft-resx</resheader>
   19.20 +    <resheader name="version">2.0</resheader>
   19.21 +    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
   19.22 +    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
   19.23 +    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
   19.24 +    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
   19.25 +    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
   19.26 +        <value>[base64 mime encoded serialized .NET Framework object]</value>
   19.27 +    </data>
   19.28 +    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
   19.29 +        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
   19.30 +        <comment>This is a comment</comment>
   19.31 +    </data>
   19.32 +                
   19.33 +    There are any number of "resheader" rows that contain simple 
   19.34 +    name/value pairs.
   19.35 +    
   19.36 +    Each data row contains a name, and value. The row also contains a 
   19.37 +    type or mimetype. Type corresponds to a .NET class that support 
   19.38 +    text/value conversion through the TypeConverter architecture. 
   19.39 +    Classes that don't support this are serialized and stored with the 
   19.40 +    mimetype set.
   19.41 +    
   19.42 +    The mimetype is used for serialized objects, and tells the 
   19.43 +    ResXResourceReader how to depersist the object. This is currently not 
   19.44 +    extensible. For a given mimetype the value must be set accordingly:
   19.45 +    
   19.46 +    Note - application/x-microsoft.net.object.binary.base64 is the format 
   19.47 +    that the ResXResourceWriter will generate, however the reader can 
   19.48 +    read any of the formats listed below.
   19.49 +    
   19.50 +    mimetype: application/x-microsoft.net.object.binary.base64
   19.51 +    value   : The object must be serialized with 
   19.52 +            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
   19.53 +            : and then encoded with base64 encoding.
   19.54 +    
   19.55 +    mimetype: application/x-microsoft.net.object.soap.base64
   19.56 +    value   : The object must be serialized with 
   19.57 +            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
   19.58 +            : and then encoded with base64 encoding.
   19.59 +
   19.60 +    mimetype: application/x-microsoft.net.object.bytearray.base64
   19.61 +    value   : The object must be serialized into a byte array 
   19.62 +            : using a System.ComponentModel.TypeConverter
   19.63 +            : and then encoded with base64 encoding.
   19.64 +    -->
   19.65 +  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
   19.66 +    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
   19.67 +    <xsd:element name="root" msdata:IsDataSet="true">
   19.68 +      <xsd:complexType>
   19.69 +        <xsd:choice maxOccurs="unbounded">
   19.70 +          <xsd:element name="metadata">
   19.71 +            <xsd:complexType>
   19.72 +              <xsd:sequence>
   19.73 +                <xsd:element name="value" type="xsd:string" minOccurs="0" />
   19.74 +              </xsd:sequence>
   19.75 +              <xsd:attribute name="name" use="required" type="xsd:string" />
   19.76 +              <xsd:attribute name="type" type="xsd:string" />
   19.77 +              <xsd:attribute name="mimetype" type="xsd:string" />
   19.78 +              <xsd:attribute ref="xml:space" />
   19.79 +            </xsd:complexType>
   19.80 +          </xsd:element>
   19.81 +          <xsd:element name="assembly">
   19.82 +            <xsd:complexType>
   19.83 +              <xsd:attribute name="alias" type="xsd:string" />
   19.84 +              <xsd:attribute name="name" type="xsd:string" />
   19.85 +            </xsd:complexType>
   19.86 +          </xsd:element>
   19.87 +          <xsd:element name="data">
   19.88 +            <xsd:complexType>
   19.89 +              <xsd:sequence>
   19.90 +                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
   19.91 +                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
   19.92 +              </xsd:sequence>
   19.93 +              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
   19.94 +              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
   19.95 +              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
   19.96 +              <xsd:attribute ref="xml:space" />
   19.97 +            </xsd:complexType>
   19.98 +          </xsd:element>
   19.99 +          <xsd:element name="resheader">
  19.100 +            <xsd:complexType>
  19.101 +              <xsd:sequence>
  19.102 +                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
  19.103 +              </xsd:sequence>
  19.104 +              <xsd:attribute name="name" type="xsd:string" use="required" />
  19.105 +            </xsd:complexType>
  19.106 +          </xsd:element>
  19.107 +        </xsd:choice>
  19.108 +      </xsd:complexType>
  19.109 +    </xsd:element>
  19.110 +  </xsd:schema>
  19.111 +  <resheader name="resmimetype">
  19.112 +    <value>text/microsoft-resx</value>
  19.113 +  </resheader>
  19.114 +  <resheader name="version">
  19.115 +    <value>2.0</value>
  19.116 +  </resheader>
  19.117 +  <resheader name="reader">
  19.118 +    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  19.119 +  </resheader>
  19.120 +  <resheader name="writer">
  19.121 +    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  19.122 +  </resheader>
  19.123 +  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
  19.124 +    <value>17, 17</value>
  19.125 +  </metadata>
  19.126 +</root>
  19.127 \ No newline at end of file
    20.1 --- a/Server/FormMain.Designer.cs	Sun Jul 31 12:03:52 2016 +0200
    20.2 +++ b/Server/FormMain.Designer.cs	Fri Aug 12 20:25:05 2016 +0200
    20.3 @@ -110,6 +110,10 @@
    20.4              this.labelHdmiPort = new System.Windows.Forms.Label();
    20.5              this.comboBoxHdmiPort = new System.Windows.Forms.ComboBox();
    20.6              this.tabPageEvent = new System.Windows.Forms.TabPage();
    20.7 +            this.buttonEventEdit = new System.Windows.Forms.Button();
    20.8 +            this.buttonEventDelete = new System.Windows.Forms.Button();
    20.9 +            this.buttonEventAdd = new System.Windows.Forms.Button();
   20.10 +            this.buttonEventTest = new System.Windows.Forms.Button();
   20.11              this.buttonActionEdit = new System.Windows.Forms.Button();
   20.12              this.buttonActionMoveUp = new System.Windows.Forms.Button();
   20.13              this.buttonActionMoveDown = new System.Windows.Forms.Button();
   20.14 @@ -129,7 +133,6 @@
   20.15              this.labelFontHeight = new System.Windows.Forms.Label();
   20.16              this.toolTip = new System.Windows.Forms.ToolTip(this.components);
   20.17              this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
   20.18 -            this.buttonEventTest = new System.Windows.Forms.Button();
   20.19              this.panelDisplay.SuspendLayout();
   20.20              this.iTableLayoutPanel.SuspendLayout();
   20.21              this.statusStrip.SuspendLayout();
   20.22 @@ -974,6 +977,9 @@
   20.23              // 
   20.24              // tabPageEvent
   20.25              // 
   20.26 +            this.tabPageEvent.Controls.Add(this.buttonEventEdit);
   20.27 +            this.tabPageEvent.Controls.Add(this.buttonEventDelete);
   20.28 +            this.tabPageEvent.Controls.Add(this.buttonEventAdd);
   20.29              this.tabPageEvent.Controls.Add(this.buttonEventTest);
   20.30              this.tabPageEvent.Controls.Add(this.buttonActionEdit);
   20.31              this.tabPageEvent.Controls.Add(this.buttonActionMoveUp);
   20.32 @@ -990,10 +996,53 @@
   20.33              this.tabPageEvent.Text = "Events";
   20.34              this.tabPageEvent.UseVisualStyleBackColor = true;
   20.35              // 
   20.36 +            // buttonEventEdit
   20.37 +            // 
   20.38 +            this.buttonEventEdit.Enabled = false;
   20.39 +            this.buttonEventEdit.Location = new System.Drawing.Point(6, 35);
   20.40 +            this.buttonEventEdit.Name = "buttonEventEdit";
   20.41 +            this.buttonEventEdit.Size = new System.Drawing.Size(96, 23);
   20.42 +            this.buttonEventEdit.TabIndex = 29;
   20.43 +            this.buttonEventEdit.Text = "Edit Event";
   20.44 +            this.buttonEventEdit.UseVisualStyleBackColor = true;
   20.45 +            this.buttonEventEdit.Click += new System.EventHandler(this.buttonEventEdit_Click);
   20.46 +            // 
   20.47 +            // buttonEventDelete
   20.48 +            // 
   20.49 +            this.buttonEventDelete.Enabled = false;
   20.50 +            this.buttonEventDelete.Location = new System.Drawing.Point(6, 64);
   20.51 +            this.buttonEventDelete.Name = "buttonEventDelete";
   20.52 +            this.buttonEventDelete.Size = new System.Drawing.Size(96, 23);
   20.53 +            this.buttonEventDelete.TabIndex = 28;
   20.54 +            this.buttonEventDelete.Text = "Delete Event";
   20.55 +            this.buttonEventDelete.UseVisualStyleBackColor = true;
   20.56 +            this.buttonEventDelete.Click += new System.EventHandler(this.buttonEventDelete_Click);
   20.57 +            // 
   20.58 +            // buttonEventAdd
   20.59 +            // 
   20.60 +            this.buttonEventAdd.Location = new System.Drawing.Point(6, 6);
   20.61 +            this.buttonEventAdd.Name = "buttonEventAdd";
   20.62 +            this.buttonEventAdd.Size = new System.Drawing.Size(96, 23);
   20.63 +            this.buttonEventAdd.TabIndex = 27;
   20.64 +            this.buttonEventAdd.Text = "Add Event";
   20.65 +            this.buttonEventAdd.UseVisualStyleBackColor = true;
   20.66 +            this.buttonEventAdd.Click += new System.EventHandler(this.buttonEventAdd_Click);
   20.67 +            // 
   20.68 +            // buttonEventTest
   20.69 +            // 
   20.70 +            this.buttonEventTest.Enabled = false;
   20.71 +            this.buttonEventTest.Location = new System.Drawing.Point(6, 93);
   20.72 +            this.buttonEventTest.Name = "buttonEventTest";
   20.73 +            this.buttonEventTest.Size = new System.Drawing.Size(96, 23);
   20.74 +            this.buttonEventTest.TabIndex = 26;
   20.75 +            this.buttonEventTest.Text = "Test Event";
   20.76 +            this.buttonEventTest.UseVisualStyleBackColor = true;
   20.77 +            this.buttonEventTest.Click += new System.EventHandler(this.buttonEventTest_Click);
   20.78 +            // 
   20.79              // buttonActionEdit
   20.80              // 
   20.81              this.buttonActionEdit.Enabled = false;
   20.82 -            this.buttonActionEdit.Location = new System.Drawing.Point(6, 35);
   20.83 +            this.buttonActionEdit.Location = new System.Drawing.Point(6, 190);
   20.84              this.buttonActionEdit.Name = "buttonActionEdit";
   20.85              this.buttonActionEdit.Size = new System.Drawing.Size(96, 23);
   20.86              this.buttonActionEdit.TabIndex = 25;
   20.87 @@ -1026,7 +1075,7 @@
   20.88              // buttonActionTest
   20.89              // 
   20.90              this.buttonActionTest.Enabled = false;
   20.91 -            this.buttonActionTest.Location = new System.Drawing.Point(6, 93);
   20.92 +            this.buttonActionTest.Location = new System.Drawing.Point(6, 248);
   20.93              this.buttonActionTest.Name = "buttonActionTest";
   20.94              this.buttonActionTest.Size = new System.Drawing.Size(96, 23);
   20.95              this.buttonActionTest.TabIndex = 22;
   20.96 @@ -1037,7 +1086,7 @@
   20.97              // buttonActionDelete
   20.98              // 
   20.99              this.buttonActionDelete.Enabled = false;
  20.100 -            this.buttonActionDelete.Location = new System.Drawing.Point(6, 64);
  20.101 +            this.buttonActionDelete.Location = new System.Drawing.Point(6, 219);
  20.102              this.buttonActionDelete.Name = "buttonActionDelete";
  20.103              this.buttonActionDelete.Size = new System.Drawing.Size(96, 23);
  20.104              this.buttonActionDelete.TabIndex = 21;
  20.105 @@ -1048,9 +1097,9 @@
  20.106              // buttonActionAdd
  20.107              // 
  20.108              this.buttonActionAdd.Enabled = false;
  20.109 -            this.buttonActionAdd.Location = new System.Drawing.Point(6, 6);
  20.110 +            this.buttonActionAdd.Location = new System.Drawing.Point(6, 157);
  20.111              this.buttonActionAdd.Name = "buttonActionAdd";
  20.112 -            this.buttonActionAdd.Size = new System.Drawing.Size(96, 23);
  20.113 +            this.buttonActionAdd.Size = new System.Drawing.Size(96, 27);
  20.114              this.buttonActionAdd.TabIndex = 20;
  20.115              this.buttonActionAdd.Text = "Add Action";
  20.116              this.buttonActionAdd.UseVisualStyleBackColor = true;
  20.117 @@ -1067,6 +1116,7 @@
  20.118              this.iTreeViewEvents.Size = new System.Drawing.Size(638, 376);
  20.119              this.iTreeViewEvents.TabIndex = 1;
  20.120              this.iTreeViewEvents.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.iTreeViewEvents_AfterSelect);
  20.121 +            this.iTreeViewEvents.Leave += new System.EventHandler(this.iTreeViewEvents_Leave);
  20.122              // 
  20.123              // tabPageApp
  20.124              // 
  20.125 @@ -1189,17 +1239,6 @@
  20.126              // 
  20.127              this.openFileDialog.Filter = "EXE files (*.exe)|*.exe|All files (*.*)|*.*";
  20.128              // 
  20.129 -            // buttonEventTest
  20.130 -            // 
  20.131 -            this.buttonEventTest.Enabled = false;
  20.132 -            this.buttonEventTest.Location = new System.Drawing.Point(6, 122);
  20.133 -            this.buttonEventTest.Name = "buttonEventTest";
  20.134 -            this.buttonEventTest.Size = new System.Drawing.Size(96, 23);
  20.135 -            this.buttonEventTest.TabIndex = 26;
  20.136 -            this.buttonEventTest.Text = "Test Event";
  20.137 -            this.buttonEventTest.UseVisualStyleBackColor = true;
  20.138 -            this.buttonEventTest.Click += new System.EventHandler(this.buttonEventTest_Click);
  20.139 -            // 
  20.140              // FormMain
  20.141              // 
  20.142              this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
  20.143 @@ -1344,6 +1383,9 @@
  20.144          private System.Windows.Forms.Button buttonActionTest;
  20.145          private System.Windows.Forms.Button buttonActionEdit;
  20.146          private System.Windows.Forms.Button buttonEventTest;
  20.147 +        private System.Windows.Forms.Button buttonEventDelete;
  20.148 +        private System.Windows.Forms.Button buttonEventAdd;
  20.149 +        private System.Windows.Forms.Button buttonEventEdit;
  20.150      }
  20.151  }
  20.152  
    21.1 --- a/Server/FormMain.cs	Sun Jul 31 12:03:52 2016 +0200
    21.2 +++ b/Server/FormMain.cs	Fri Aug 12 20:25:05 2016 +0200
    21.3 @@ -322,23 +322,33 @@
    21.4              Event currentEvent = CurrentEvent();
    21.5              SharpLib.Ear.Action currentAction = CurrentAction();
    21.6              TreeNode treeNodeToSelect = null;
    21.7 -
    21.8 +            
    21.9              //Reset our tree
   21.10              iTreeViewEvents.Nodes.Clear();
   21.11              //Populate registered events
   21.12 -            foreach (string key in ManagerEventAction.Current.Events.Keys)
   21.13 +            foreach (SharpLib.Ear.Event e in ManagerEventAction.Current.Events)
   21.14              {
   21.15 -                Event e = ManagerEventAction.Current.Events[key];
   21.16 -                TreeNode eventNode = iTreeViewEvents.Nodes.Add(key, e.Name);
   21.17 -                eventNode.Tag = e;
   21.18 -                eventNode.Nodes.Add(key + ".Description", e.Description);
   21.19 -                TreeNode actionsNodes = eventNode.Nodes.Add(key + ".Actions", "Actions");
   21.20 +                //Create our event node
   21.21 +                TreeNode eventNode = iTreeViewEvents.Nodes.Add(e.Name);
   21.22 +                eventNode.Tag = e; //For easy access to our event
   21.23 +                if (!e.Enabled)
   21.24 +                {
   21.25 +                    //Dim our nodes if disabled
   21.26 +                    eventNode.ForeColor = Color.DimGray;
   21.27 +                }
   21.28 +
   21.29 +                //Add event description as child node
   21.30 +                eventNode.Nodes.Add(e.Description).ForeColor = eventNode.ForeColor; 
   21.31 +                //Create child node for actions root
   21.32 +                TreeNode actionsNodes = eventNode.Nodes.Add("Actions");
   21.33 +                actionsNodes.ForeColor = eventNode.ForeColor;
   21.34  
   21.35                  // Add our actions for that event
   21.36                  foreach (SharpLib.Ear.Action a in e.Actions)
   21.37                  {
   21.38                      TreeNode actionNode = actionsNodes.Nodes.Add(a.Brief());
   21.39                      actionNode.Tag = a;
   21.40 +                    actionNode.ForeColor = eventNode.ForeColor;
   21.41                      if (a == currentAction)
   21.42                      {
   21.43                          treeNodeToSelect = actionNode;
   21.44 @@ -360,7 +370,14 @@
   21.45                      iTreeViewEvents.SelectedNode.Nodes[1].Nodes[
   21.46                          iTreeViewEvents.SelectedNode.Nodes[1].GetNodeCount(false) - 1];
   21.47              }
   21.48 -
   21.49 +            else if (iTreeViewEvents.SelectedNode == null && iTreeViewEvents.Nodes.Count > 0)
   21.50 +            {
   21.51 +                //Still no selected node select the first one then
   21.52 +                iTreeViewEvents.SelectedNode = iTreeViewEvents.Nodes[0];
   21.53 +            }
   21.54 +
   21.55 +
   21.56 +            UpdateEventView();
   21.57          }
   21.58  
   21.59          /// <summary>
   21.60 @@ -2727,12 +2744,13 @@
   21.61                  return;
   21.62              }
   21.63  
   21.64 -            string key = aEvent.GetType().Name;
   21.65 -            TreeNode[] res = iTreeViewEvents.Nodes.Find(key, false);
   21.66 -            if (res.Length > 0)
   21.67 +            foreach (TreeNode node in iTreeViewEvents.Nodes)
   21.68              {
   21.69 -                iTreeViewEvents.SelectedNode = res[0];
   21.70 -                iTreeViewEvents.Focus();
   21.71 +                if (node.Tag == aEvent)
   21.72 +                {
   21.73 +                    iTreeViewEvents.SelectedNode = node;
   21.74 +                    iTreeViewEvents.Focus();
   21.75 +                }
   21.76              }
   21.77          }
   21.78  
   21.79 @@ -2789,12 +2807,12 @@
   21.80                  return;
   21.81              }
   21.82  
   21.83 -            FormEditAction ea = new FormEditAction();
   21.84 +            FormEditObject<SharpLib.Ear.Action> ea = new FormEditObject<SharpLib.Ear.Action>();
   21.85              ea.Text = "Add action";
   21.86              DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea);
   21.87              if (res == DialogResult.OK)
   21.88              {
   21.89 -                selectedEvent.Actions.Add(ea.Action);
   21.90 +                selectedEvent.Actions.Add(ea.Object);
   21.91                  Properties.Settings.Default.Actions = ManagerEventAction.Current;
   21.92                  Properties.Settings.Default.Save();
   21.93                  PopulateEventsTreeView();
   21.94 @@ -2816,15 +2834,15 @@
   21.95                  return;
   21.96              }
   21.97  
   21.98 -            FormEditAction ea = new FormEditAction();
   21.99 +            FormEditObject<SharpLib.Ear.Action> ea = new FormEditObject<SharpLib.Ear.Action>();
  21.100              ea.Text = "Edit action";
  21.101 -            ea.Action = selectedAction;
  21.102 +            ea.Object = selectedAction;
  21.103              int actionIndex = iTreeViewEvents.SelectedNode.Index;
  21.104              DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea);
  21.105              if (res == DialogResult.OK)
  21.106              {
  21.107                  //Update our action
  21.108 -                selectedEvent.Actions[actionIndex]=ea.Action;
  21.109 +                selectedEvent.Actions[actionIndex]=ea.Object;
  21.110                  //Save and rebuild our event tree view
  21.111                  Properties.Settings.Default.Actions = ManagerEventAction.Current;
  21.112                  Properties.Settings.Default.Save();
  21.113 @@ -2863,8 +2881,7 @@
  21.114              SharpLib.Ear.Action a = CurrentAction();
  21.115              if (a != null)
  21.116              {
  21.117 -                Console.WriteLine("Action testing:");
  21.118 -                a.Execute();
  21.119 +                a.Test();
  21.120              }
  21.121              iTreeViewEvents.Focus();
  21.122          }
  21.123 @@ -2939,8 +2956,7 @@
  21.124              Event earEvent = CurrentEvent();
  21.125              if (earEvent != null)
  21.126              {
  21.127 -                Console.WriteLine("Event testing:");
  21.128 -                earEvent.Trigger();
  21.129 +                earEvent.Test();
  21.130              }
  21.131          }
  21.132  
  21.133 @@ -2951,9 +2967,22 @@
  21.134          /// <param name="e"></param>
  21.135          private void iTreeViewEvents_AfterSelect(object sender, TreeViewEventArgs e)
  21.136          {
  21.137 +            UpdateEventView();
  21.138 +        }
  21.139 +
  21.140 +        /// <summary>
  21.141 +        /// 
  21.142 +        /// </summary>
  21.143 +        private void UpdateEventView()
  21.144 +        {
  21.145 +            //One can always add an event
  21.146 +            buttonEventAdd.Enabled = true;
  21.147 +
  21.148              //Enable buttons according to selected item
  21.149              buttonActionAdd.Enabled =
  21.150              buttonEventTest.Enabled =
  21.151 +            buttonEventDelete.Enabled =
  21.152 +            buttonEventEdit.Enabled =
  21.153                  CurrentEvent() != null;
  21.154  
  21.155              SharpLib.Ear.Action currentAction = CurrentAction();
  21.156 @@ -2962,7 +2991,7 @@
  21.157              buttonActionDelete.Enabled =
  21.158              buttonActionMoveUp.Enabled =
  21.159              buttonActionMoveDown.Enabled =
  21.160 -            buttonActionEdit.Enabled = 
  21.161 +            buttonActionEdit.Enabled =
  21.162                      currentAction != null;
  21.163  
  21.164              if (currentAction != null)
  21.165 @@ -2972,8 +3001,65 @@
  21.166                  buttonActionMoveDown.Enabled = iTreeViewEvents.SelectedNode.Index <
  21.167                                                 iTreeViewEvents.SelectedNode.Parent.Nodes.Count - 1;
  21.168              }
  21.169 -
  21.170          }
  21.171  
  21.172 +        private void buttonEventAdd_Click(object sender, EventArgs e)
  21.173 +        {
  21.174 +            FormEditObject<SharpLib.Ear.Event> ea = new FormEditObject<SharpLib.Ear.Event>();
  21.175 +            ea.Text = "Add event";
  21.176 +            DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea);
  21.177 +            if (res == DialogResult.OK)
  21.178 +            {
  21.179 +                ManagerEventAction.Current.Events.Add(ea.Object);
  21.180 +                Properties.Settings.Default.Actions = ManagerEventAction.Current;
  21.181 +                Properties.Settings.Default.Save();
  21.182 +                PopulateEventsTreeView();
  21.183 +                SelectEvent(ea.Object);
  21.184 +            }
  21.185 +        }
  21.186 +
  21.187 +        private void buttonEventDelete_Click(object sender, EventArgs e)
  21.188 +        {
  21.189 +            SharpLib.Ear.Event currentEvent = CurrentEvent();
  21.190 +            if (currentEvent == null)
  21.191 +            {
  21.192 +                //Must select action node
  21.193 +                return;
  21.194 +            }
  21.195 +
  21.196 +            ManagerEventAction.Current.Events.Remove(currentEvent);
  21.197 +            Properties.Settings.Default.Actions = ManagerEventAction.Current;
  21.198 +            Properties.Settings.Default.Save();
  21.199 +            PopulateEventsTreeView();
  21.200 +        }
  21.201 +
  21.202 +        private void buttonEventEdit_Click(object sender, EventArgs e)
  21.203 +        {
  21.204 +            Event selectedEvent = CurrentEvent();
  21.205 +            if (selectedEvent == null)
  21.206 +            {
  21.207 +                //We did not find a corresponding event
  21.208 +                return;
  21.209 +            }
  21.210 +
  21.211 +            FormEditObject<SharpLib.Ear.Event> ea = new FormEditObject<SharpLib.Ear.Event>();
  21.212 +            ea.Text = "Edit event";
  21.213 +            ea.Object = selectedEvent;
  21.214 +            int actionIndex = iTreeViewEvents.SelectedNode.Index;
  21.215 +            DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea);
  21.216 +            if (res == DialogResult.OK)
  21.217 +            {
  21.218 +                //Save and rebuild our event tree view
  21.219 +                Properties.Settings.Default.Actions = ManagerEventAction.Current;
  21.220 +                Properties.Settings.Default.Save();
  21.221 +                PopulateEventsTreeView();
  21.222 +            }
  21.223 +        }
  21.224 +
  21.225 +        private void iTreeViewEvents_Leave(object sender, EventArgs e)
  21.226 +        {
  21.227 +            //Make sure our event tree never looses focus
  21.228 +            ((TreeView) sender).Focus();
  21.229 +        }
  21.230      }
  21.231  }
    22.1 --- a/Server/ItemActionType.cs	Sun Jul 31 12:03:52 2016 +0200
    22.2 +++ b/Server/ItemActionType.cs	Fri Aug 12 20:25:05 2016 +0200
    22.3 @@ -10,11 +10,11 @@
    22.4      /// <summary>
    22.5      /// Used to populate our action type combobox with friendly names
    22.6      /// </summary>
    22.7 -    class ItemActionType
    22.8 +    class ItemObjectType
    22.9      {
   22.10          public Type Type;
   22.11  
   22.12 -        public ItemActionType(Type type)
   22.13 +        public ItemObjectType(Type type)
   22.14          {
   22.15              this.Type = type;
   22.16          }
   22.17 @@ -23,7 +23,7 @@
   22.18          {
   22.19              //Get friendly action name from action attribute.
   22.20              //That we then show up in our combobox
   22.21 -            return SharpLib.Utils.Reflection.GetAttribute<AttributeAction>(Type).Name;
   22.22 +            return SharpLib.Utils.Reflection.GetAttribute<AttributeObject>(Type).Name;
   22.23          }
   22.24      }
   22.25  }
    23.1 --- a/Server/SharpDisplayManager.csproj	Sun Jul 31 12:03:52 2016 +0200
    23.2 +++ b/Server/SharpDisplayManager.csproj	Fri Aug 12 20:25:05 2016 +0200
    23.3 @@ -169,11 +169,11 @@
    23.4      <Compile Include="CecClient.cs" />
    23.5      <Compile Include="ConsumerElectronicControl.cs" />
    23.6      <Compile Include="ClientData.cs" />
    23.7 -    <Compile Include="FormEditAction.cs">
    23.8 +    <Compile Include="FormEditObject.cs">
    23.9        <SubType>Form</SubType>
   23.10      </Compile>
   23.11 -    <Compile Include="FormEditAction.Designer.cs">
   23.12 -      <DependentUpon>FormEditAction.cs</DependentUpon>
   23.13 +    <Compile Include="FormEditObject.Designer.cs">
   23.14 +      <DependentUpon>FormEditObject.cs</DependentUpon>
   23.15      </Compile>
   23.16      <Compile Include="FormMain.cs">
   23.17        <SubType>Form</SubType>
   23.18 @@ -210,8 +210,8 @@
   23.19      <Compile Include="Win32API.cs" />
   23.20      <Compile Include="WindowsHook.cs" />
   23.21      <Compile Include="WndProcRetHook.cs" />
   23.22 -    <EmbeddedResource Include="FormEditAction.resx">
   23.23 -      <DependentUpon>FormEditAction.cs</DependentUpon>
   23.24 +    <EmbeddedResource Include="FormEditObject.resx">
   23.25 +      <DependentUpon>FormEditObject.cs</DependentUpon>
   23.26      </EmbeddedResource>
   23.27      <EmbeddedResource Include="FormMain.resx">
   23.28        <DependentUpon>FormMain.cs</DependentUpon>
    24.1 --- a/SharpLibEar/Action.cs	Sun Jul 31 12:03:52 2016 +0200
    24.2 +++ b/SharpLibEar/Action.cs	Fri Aug 12 20:25:05 2016 +0200
    24.3 @@ -14,6 +14,15 @@
    24.4      {
    24.5          protected abstract void DoExecute();
    24.6  
    24.7 +        /// <summary>
    24.8 +        /// Allows testing from generic edit dialog.
    24.9 +        /// </summary>
   24.10 +        public void Test()
   24.11 +        {
   24.12 +            Console.WriteLine("Action test");
   24.13 +            Execute();
   24.14 +        }
   24.15 +
   24.16          public void Execute()
   24.17          {
   24.18              Console.WriteLine("Action executing: " + Brief());
   24.19 @@ -22,7 +31,7 @@
   24.20  
   24.21          public string Name {
   24.22              //Get the name of this object action attribute
   24.23 -            get { return Utils.Reflection.GetAttribute<AttributeAction>(GetType()).Name; }
   24.24 +            get { return Utils.Reflection.GetAttribute<AttributeObject>(GetType()).Name; }
   24.25              private set { }
   24.26          }
   24.27  
   24.28 @@ -34,7 +43,7 @@
   24.29          public int CompareTo(object obj)
   24.30          {
   24.31              //Sort by action name
   24.32 -            return Utils.Reflection.GetAttribute<AttributeAction>(GetType()).Name.CompareTo(obj.GetType());            
   24.33 +            return Utils.Reflection.GetAttribute<AttributeObject>(GetType()).Name.CompareTo(obj.GetType());            
   24.34          }
   24.35  
   24.36          private static IEnumerable<Type> DerivedTypes()
    25.1 --- a/SharpLibEar/ActionSleep.cs	Sun Jul 31 12:03:52 2016 +0200
    25.2 +++ b/SharpLibEar/ActionSleep.cs	Fri Aug 12 20:25:05 2016 +0200
    25.3 @@ -10,11 +10,11 @@
    25.4      
    25.5  
    25.6      [DataContract]
    25.7 -    [AttributeAction(Id = "Thread.Sleep", Name = "Sleep", Description = "Have the current thread sleep for the specified amount of milliseconds.")]
    25.8 +    [AttributeObject(Id = "Thread.Sleep", Name = "Sleep", Description = "Have the current thread sleep for the specified amount of milliseconds.")]
    25.9      public class ActionSleep : Action
   25.10      {
   25.11          [DataMember]
   25.12 -        [AttributeActionProperty
   25.13 +        [AttributeObjectProperty
   25.14              (
   25.15                  Id = "Thread.Sleep.Timeout",
   25.16                  Name = "Timeout (ms)",
    26.1 --- a/SharpLibEar/AttributeAction.cs	Sun Jul 31 12:03:52 2016 +0200
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,22 +0,0 @@
    26.4 -using System;
    26.5 -using System.Collections.Generic;
    26.6 -using System.Linq;
    26.7 -using System.Text;
    26.8 -using System.Threading.Tasks;
    26.9 -
   26.10 -namespace SharpLib.Ear
   26.11 -{
   26.12 -
   26.13 -    /// <summary>
   26.14 -    /// For action class to define name and description.
   26.15 -    /// </summary>
   26.16 -    [System.AttributeUsage(System.AttributeTargets.Class)]
   26.17 -    public class AttributeAction : System.Attribute
   26.18 -    {
   26.19 -        public string Id;
   26.20 -        public string Name;
   26.21 -        public string Description;
   26.22 -    }
   26.23 -
   26.24 -
   26.25 -}
    27.1 --- a/SharpLibEar/AttributeActionProperty.cs	Sun Jul 31 12:03:52 2016 +0200
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,27 +0,0 @@
    27.4 -using System;
    27.5 -using System.Collections.Generic;
    27.6 -using System.Linq;
    27.7 -using System.Text;
    27.8 -using System.Threading.Tasks;
    27.9 -
   27.10 -namespace SharpLib.Ear
   27.11 -{
   27.12 -    /// <summary>
   27.13 -    /// To expose an action property thus enabling user to edit it.
   27.14 -    /// </summary>
   27.15 -    [System.AttributeUsage(System.AttributeTargets.Property)]
   27.16 -    public class AttributeActionProperty : System.Attribute
   27.17 -    {
   27.18 -        public string Id;
   27.19 -        public string Name;
   27.20 -        public string Description;
   27.21 -        // For numerics
   27.22 -        public string Minimum;
   27.23 -        public string Maximum;
   27.24 -        public string Increment;
   27.25 -    }
   27.26 -
   27.27 -
   27.28 -
   27.29 -
   27.30 -}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/SharpLibEar/AttributeObject.cs	Fri Aug 12 20:25:05 2016 +0200
    28.3 @@ -0,0 +1,22 @@
    28.4 +using System;
    28.5 +using System.Collections.Generic;
    28.6 +using System.Linq;
    28.7 +using System.Text;
    28.8 +using System.Threading.Tasks;
    28.9 +
   28.10 +namespace SharpLib.Ear
   28.11 +{
   28.12 +
   28.13 +    /// <summary>
   28.14 +    /// For action class to define name and description.
   28.15 +    /// </summary>
   28.16 +    [System.AttributeUsage(System.AttributeTargets.Class)]
   28.17 +    public class AttributeObject : System.Attribute
   28.18 +    {
   28.19 +        public string Id;
   28.20 +        public string Name;
   28.21 +        public string Description;
   28.22 +    }
   28.23 +
   28.24 +
   28.25 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/SharpLibEar/AttributeObjectProperty.cs	Fri Aug 12 20:25:05 2016 +0200
    29.3 @@ -0,0 +1,27 @@
    29.4 +using System;
    29.5 +using System.Collections.Generic;
    29.6 +using System.Linq;
    29.7 +using System.Text;
    29.8 +using System.Threading.Tasks;
    29.9 +
   29.10 +namespace SharpLib.Ear
   29.11 +{
   29.12 +    /// <summary>
   29.13 +    /// To expose an action property thus enabling user to edit it.
   29.14 +    /// </summary>
   29.15 +    [System.AttributeUsage(System.AttributeTargets.Property)]
   29.16 +    public class AttributeObjectProperty : System.Attribute
   29.17 +    {
   29.18 +        public string Id;
   29.19 +        public string Name;
   29.20 +        public string Description;
   29.21 +        // For numerics
   29.22 +        public string Minimum;
   29.23 +        public string Maximum;
   29.24 +        public string Increment;
   29.25 +    }
   29.26 +
   29.27 +
   29.28 +
   29.29 +
   29.30 +}
    30.1 --- a/SharpLibEar/Event.cs	Sun Jul 31 12:03:52 2016 +0200
    30.2 +++ b/SharpLibEar/Event.cs	Fri Aug 12 20:25:05 2016 +0200
    30.3 @@ -8,26 +8,54 @@
    30.4  namespace SharpLib.Ear
    30.5  {
    30.6      [DataContract]
    30.7 -    public abstract class MEvent
    30.8 +    [KnownType("DerivedTypes")]
    30.9 +    public abstract class Event
   30.10      {
   30.11 -        public string Name { get; protected set; }
   30.12 -        public string Description { get; protected set; }
   30.13 +        [DataMember]
   30.14 +        [AttributeObjectProperty
   30.15 +            (
   30.16 +                Id = "Event.Enabled",
   30.17 +                Name = "Enabled",
   30.18 +                Description = "When enabled an event instance can be triggered."
   30.19 +            )
   30.20 +        ]
   30.21 +        public bool Enabled { get; set; }
   30.22  
   30.23 -        public abstract void Trigger();
   30.24 -    };
   30.25 -
   30.26 -    [DataContract]
   30.27 -    public abstract class Event : MEvent
   30.28 -    {
   30.29          [DataMember]
   30.30          public List<Action> Actions = new List<Action>();
   30.31  
   30.32 +        public string Name
   30.33 +        {
   30.34 +            //Get the name of this object attribute
   30.35 +            get { return Utils.Reflection.GetAttribute<AttributeObject>(GetType()).Name; }
   30.36 +            private set { }
   30.37 +        }
   30.38 +
   30.39 +        public string Description
   30.40 +        {
   30.41 +            //Get the description of this object attribute
   30.42 +            get { return Utils.Reflection.GetAttribute<AttributeObject>(GetType()).Description; }
   30.43 +            private set { }
   30.44 +        }
   30.45 +
   30.46 +
   30.47          protected Event()
   30.48          {
   30.49 -           
   30.50 +            Enabled = true;
   30.51          }
   30.52  
   30.53 -        public override void Trigger()
   30.54 +
   30.55 +        /// <summary>
   30.56 +        /// Allows testing from generic edit dialog.
   30.57 +        /// </summary>
   30.58 +        public void Test()
   30.59 +        {
   30.60 +            Console.WriteLine("Event test");
   30.61 +            Trigger();
   30.62 +        }
   30.63 +
   30.64 +
   30.65 +        public void Trigger()
   30.66          {
   30.67              Console.WriteLine("Event triggered: " + Name);
   30.68              foreach (Action action in Actions)
   30.69 @@ -35,6 +63,15 @@
   30.70                  action.Execute();
   30.71              }
   30.72          }
   30.73 -    }
   30.74 +
   30.75 +        /// <summary>
   30.76 +        /// So that data contract knows all our types.
   30.77 +        /// </summary>
   30.78 +        /// <returns></returns>
   30.79 +        private static IEnumerable<Type> DerivedTypes()
   30.80 +        {
   30.81 +            return SharpLib.Utils.Reflection.GetDerivedTypes<Event>();
   30.82 +        }
   30.83 +    };
   30.84  
   30.85  }
   30.86 \ No newline at end of file
    31.1 --- a/SharpLibEar/EventMonitorPowerOff.cs	Sun Jul 31 12:03:52 2016 +0200
    31.2 +++ b/SharpLibEar/EventMonitorPowerOff.cs	Fri Aug 12 20:25:05 2016 +0200
    31.3 @@ -6,12 +6,11 @@
    31.4  namespace SharpLib.Ear
    31.5  {
    31.6      [DataContract]
    31.7 +    [AttributeObject(Id = "Event.Monitor.PowerOff", Name = "Monitor Power Off", Description = "Windows is powering off your monitor.")]
    31.8      public class EventMonitorPowerOff : Event
    31.9      {
   31.10          public EventMonitorPowerOff()
   31.11          {
   31.12 -            Name = "Monitor Power Off";
   31.13 -            Description = "Windows is powering off your monitor.";
   31.14          }
   31.15      }
   31.16  
    32.1 --- a/SharpLibEar/EventMonitorPowerOn.cs	Sun Jul 31 12:03:52 2016 +0200
    32.2 +++ b/SharpLibEar/EventMonitorPowerOn.cs	Fri Aug 12 20:25:05 2016 +0200
    32.3 @@ -6,12 +6,11 @@
    32.4  namespace SharpLib.Ear
    32.5  {
    32.6      [DataContract]
    32.7 +    [AttributeObject(Id = "Event.Monitor.PowerOn", Name = "Monitor Power On", Description = "Windows is powering on your monitor.")]
    32.8      public class EventMonitorPowerOn : Event
    32.9      {
   32.10          public EventMonitorPowerOn()
   32.11          {
   32.12 -            Name = "Monitor Power On";
   32.13 -            Description = "Windows is powering on your monitor.";
   32.14          }
   32.15  
   32.16      }
    33.1 --- a/SharpLibEar/ManagerEventAction.cs	Sun Jul 31 12:03:52 2016 +0200
    33.2 +++ b/SharpLibEar/ManagerEventAction.cs	Fri Aug 12 20:25:05 2016 +0200
    33.3 @@ -16,10 +16,16 @@
    33.4      public class ManagerEventAction
    33.5      {
    33.6          public static ManagerEventAction Current = null;
    33.7 -        public IDictionary<string, Type> ActionTypes;
    33.8 -        public IDictionary<string, Event> Events;
    33.9 +        //public IDictionary<string, Type> ActionTypes;
   33.10 +        //public IDictionary<string, Type> EventTypes;
   33.11 +
   33.12 +        /// <summary>
   33.13 +        /// Our events instances.
   33.14 +        /// </summary>
   33.15          [DataMember]
   33.16 -        public Dictionary<string, List<Action>> ActionsByEvents = new Dictionary<string, List<Action>>();
   33.17 +        public List<Event> Events;
   33.18 +
   33.19 +
   33.20  
   33.21  
   33.22          public ManagerEventAction()
   33.23 @@ -28,47 +34,30 @@
   33.24          }
   33.25  
   33.26          /// <summary>
   33.27 -        /// 
   33.28 +        /// Executes after internalization took place.
   33.29          /// </summary>
   33.30          public void Init()
   33.31          {
   33.32 -            //Create our list of supported actions
   33.33 -            ActionTypes = Utils.Reflection.GetConcreteClassesDerivedFromByName<Action>();
   33.34 -            //Create our list or support events
   33.35 -            Events = Utils.Reflection.GetConcreteClassesInstanceDerivedFromByName<Event>();
   33.36 +            if (Events == null)
   33.37 +            {
   33.38 +                Events = new List<Event>();
   33.39 +            }
   33.40 +            
   33.41 +        }
   33.42  
   33.43 -            if (ActionsByEvents == null)
   33.44 -            {                
   33.45 -                ActionsByEvents = new Dictionary<string, List<Action>>();
   33.46 -            }
   33.47 -
   33.48 -            //Hook in loaded actions with corresponding events
   33.49 -            foreach (string key in Events.Keys)
   33.50 +        /// <summary>
   33.51 +        /// 
   33.52 +        /// </summary>
   33.53 +        /// <param name="aEventType"></param>
   33.54 +        public void TriggerEvent<T>() where T: class
   33.55 +        {
   33.56 +            //Only trigger enabled events matching the desired type
   33.57 +            foreach (Event e in Events.Where(e => e.GetType() == typeof(T) && e.Enabled))
   33.58              {
   33.59 -                Event e = Events[key];
   33.60 -                if (ActionsByEvents.ContainsKey(key))
   33.61 -                {
   33.62 -                    //We have actions for that event, hook them in then
   33.63 -                    e.Actions = ActionsByEvents[key];
   33.64 -                }
   33.65 -                else
   33.66 -                {
   33.67 -                    //We do not have actions for that event yet, create empty action list
   33.68 -                    e.Actions = new List<Action>();
   33.69 -                    ActionsByEvents[key] = e.Actions;
   33.70 -                }
   33.71 +                e.Trigger();
   33.72              }
   33.73          }
   33.74  
   33.75 -        /// <summary>
   33.76 -        /// Get and event instance from its type.
   33.77 -        /// </summary>
   33.78 -        /// <typeparam name="T"></typeparam>
   33.79 -        /// <returns></returns>
   33.80 -        public Event GetEvent<T>() where T : class
   33.81 -        {
   33.82 -            return Events[typeof(T).Name];
   33.83 -        }
   33.84  
   33.85          /// <summary>
   33.86          /// 
   33.87 @@ -76,17 +65,14 @@
   33.88          /// <param name="aAction"></param>
   33.89          public void RemoveAction(Action aAction)
   33.90          {
   33.91 -            foreach (string key in Events.Keys)
   33.92 +            foreach (Event e in Events)
   33.93              {
   33.94 -                Event e = Events[key];
   33.95                  if (e.Actions.Remove(aAction))
   33.96                  {
   33.97                      //We removed our action, we are done here.
   33.98                      return;
   33.99                  }
  33.100 -
  33.101              }
  33.102          }
  33.103 -
  33.104      }
  33.105  }
  33.106 \ No newline at end of file
    34.1 --- a/SharpLibEar/SharpLibEar.csproj	Sun Jul 31 12:03:52 2016 +0200
    34.2 +++ b/SharpLibEar/SharpLibEar.csproj	Fri Aug 12 20:25:05 2016 +0200
    34.3 @@ -45,8 +45,8 @@
    34.4      <Compile Include="ActionCallback.cs" />
    34.5      <Compile Include="ActionSleep.cs" />
    34.6      <Compile Include="ActionType.cs" />
    34.7 -    <Compile Include="AttributeAction.cs" />
    34.8 -    <Compile Include="AttributeActionProperty.cs" />
    34.9 +    <Compile Include="AttributeObject.cs" />
   34.10 +    <Compile Include="AttributeObjectProperty.cs" />
   34.11      <Compile Include="Event.cs" />
   34.12      <Compile Include="EventMonitorPowerOff.cs" />
   34.13      <Compile Include="EventMonitorPowerOn.cs" />