Server/FormEditAction.cs
author StephaneLenclud
Fri, 29 Jul 2016 14:33:47 +0200
changeset 228 6a84d8282226
parent 227 4a03cc6f41b0
permissions -rw-r--r--
Adding test action button to edit action form.
Action.DoExecute now protected.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.ComponentModel;
     4 using System.Data;
     5 using System.Diagnostics;
     6 using System.Drawing;
     7 using System.Linq;
     8 using System.Text;
     9 using System.Threading.Tasks;
    10 using System.Windows.Forms;
    11 using SharpLib.Display;
    12 using SharpLib.Ear;
    13 using System.Reflection;
    14 
    15 namespace SharpDisplayManager
    16 {
    17     /// <summary>
    18     /// Action edit dialog form.
    19     /// </summary>
    20     public partial class FormEditAction : Form
    21     {
    22         public SharpLib.Ear.Action Action = null;
    23 
    24         public FormEditAction()
    25         {
    26             InitializeComponent();
    27         }
    28 
    29         /// <summary>
    30         /// 
    31         /// </summary>
    32         /// <param name="sender"></param>
    33         /// <param name="e"></param>
    34         private void FormEditAction_Load(object sender, EventArgs e)
    35         {
    36             // Populate registered actions
    37             foreach (string key in ManagerEventAction.Current.ActionTypes.Keys)
    38             {
    39                 ItemActionType item = new ItemActionType(ManagerEventAction.Current.ActionTypes[key]);
    40                 comboBoxActionType.Items.Add(item);
    41             }
    42 
    43             if (Action == null)
    44             {
    45                 // Creating new issue, select our first item
    46                 comboBoxActionType.SelectedIndex = 0;
    47             }
    48             else
    49             {
    50                 // Editing existing issue
    51                 // Look up our item in our combobox 
    52                 foreach (ItemActionType item in comboBoxActionType.Items)
    53                 {
    54                     if (item.Type == Action.GetType())
    55                     {
    56                         comboBoxActionType.SelectedItem = item;
    57                     }
    58                 }
    59             }            
    60         }
    61 
    62         private void buttonOk_Click(object sender, EventArgs e)
    63         {
    64             FetchPropertiesValue(Action);
    65         }
    66 
    67         private void FormEditAction_Validating(object sender, CancelEventArgs e)
    68         {
    69 
    70         }
    71 
    72         private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
    73         {
    74             //Instantiate an action corresponding to our type
    75             Type actionType = ((ItemActionType) comboBoxActionType.SelectedItem).Type;
    76             //Create another type of action only if needed
    77             if (Action == null || Action.GetType() != actionType)
    78             {
    79                 Action = (SharpLib.Ear.Action)Activator.CreateInstance(actionType);
    80             }
    81             
    82             //Create input fields
    83             UpdateTableLayoutPanel(Action);
    84         }
    85 
    86 
    87         /// <summary>
    88         /// Get properties values from our generated input fields
    89         /// </summary>
    90         private void FetchPropertiesValue(SharpLib.Ear.Action aAction)
    91         {
    92             int ctrlIndex = 0;
    93             foreach (PropertyInfo pi in aAction.GetType().GetProperties())
    94             {
    95                 AttributeActionProperty[] attributes =
    96                     ((AttributeActionProperty[]) pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
    97                 if (attributes.Length != 1)
    98                 {
    99                     continue;
   100                 }
   101 
   102                 AttributeActionProperty attribute = attributes[0];
   103 
   104                 if (!IsPropertyTypeSupported(pi))
   105                 {
   106                     continue;
   107                 }
   108 
   109                 GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aAction); //+1 otherwise we get the label
   110 
   111                 ctrlIndex+=2; //Jump over the label too
   112             }
   113         }
   114 
   115         /// <summary>
   116         /// Extend this function to support reading new types of properties.
   117         /// </summary>
   118         /// <param name="aAction"></param>
   119         private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, SharpLib.Ear.Action aAction)
   120         {
   121             if (aInfo.PropertyType == typeof(int))
   122             {
   123                 NumericUpDown ctrl=(NumericUpDown)aControl;
   124                 aInfo.SetValue(aAction,(int)ctrl.Value);
   125             }
   126             else if (aInfo.PropertyType.IsEnum)
   127             {
   128                 // Instantiate our enum
   129                 object enumValue= Activator.CreateInstance(aInfo.PropertyType);
   130                 // Parse our enum from combo box
   131                 enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
   132                 //enumValue = ((ComboBox)aControl).SelectedValue;
   133                 // Set enum value
   134                 aInfo.SetValue(aAction, enumValue);
   135             }
   136             else if (aInfo.PropertyType == typeof(bool))
   137             {
   138                 CheckBox ctrl = (CheckBox)aControl;
   139                 aInfo.SetValue(aAction, ctrl.Checked);
   140             }
   141             else if (aInfo.PropertyType == typeof(string))
   142             {
   143                 TextBox ctrl = (TextBox)aControl;
   144                 aInfo.SetValue(aAction, ctrl.Text);
   145             }
   146             //TODO: add support for other types here
   147         }
   148 
   149         /// <summary>
   150         /// 
   151         /// </summary>
   152         /// <param name="aInfo"></param>
   153         /// <param name="action"></param>
   154         private Control CreateControlForProperty(PropertyInfo aInfo, AttributeActionProperty aAttribute, SharpLib.Ear.Action aAction)
   155         {
   156             if (aInfo.PropertyType == typeof(int))
   157             {
   158                 //Integer properties are using numeric editor
   159                 NumericUpDown ctrl = new NumericUpDown();
   160                 ctrl.AutoSize = true;
   161                 ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
   162                 ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
   163                 ctrl.Increment = Int32.Parse(aAttribute.Increment);
   164                 ctrl.Value = (int)aInfo.GetValue(aAction);
   165                 return ctrl;
   166             }
   167             else if (aInfo.PropertyType.IsEnum)
   168             {
   169                 //Enum properties are using combo box
   170                 ComboBox ctrl = new ComboBox();
   171                 ctrl.AutoSize = true;                
   172                 ctrl.Sorted = true;                
   173                 ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
   174                 //Data source is fine but it gives us duplicate entries for duplicated enum values
   175                 //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
   176 
   177                 //Therefore we need to explicitly create our items
   178                 Size cbSize = new Size(0,0);
   179                 foreach (string name in aInfo.PropertyType.GetEnumNames())
   180                 {
   181                     ctrl.Items.Add(name.ToString());
   182                     Graphics g = this.CreateGraphics();
   183                     //Since combobox autosize would not work we need to get measure text ourselves
   184                     SizeF size=g.MeasureString(name.ToString(), ctrl.Font);
   185                     cbSize.Width = Math.Max(cbSize.Width,(int)size.Width);
   186                     cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
   187                 }
   188 
   189                 //Make sure our combobox is large enough
   190                 ctrl.MinimumSize = cbSize;
   191 
   192                 // Instantiate our enum
   193                 object enumValue = Activator.CreateInstance(aInfo.PropertyType);
   194                 enumValue = aInfo.GetValue(aAction);
   195                 //Set the current item
   196                 ctrl.SelectedItem = enumValue.ToString();
   197 
   198                 return ctrl;
   199             }
   200             else if (aInfo.PropertyType == typeof(bool))
   201             {
   202                 CheckBox ctrl = new CheckBox();
   203                 ctrl.AutoSize = true;
   204                 ctrl.Text = aAttribute.Description;
   205                 ctrl.Checked = (bool)aInfo.GetValue(aAction);                
   206                 return ctrl;
   207             }
   208             else if (aInfo.PropertyType == typeof(string))
   209             {
   210                 TextBox ctrl = new TextBox();
   211                 ctrl.AutoSize = true;
   212                 ctrl.Text = (string)aInfo.GetValue(aAction);
   213                 return ctrl;
   214             }
   215             //TODO: add support for other control type here
   216 
   217             return null;
   218         }
   219 
   220         /// <summary>
   221         /// Don't forget to extend that one and adding types
   222         /// </summary>
   223         /// <returns></returns>
   224         private bool IsPropertyTypeSupported(PropertyInfo aInfo)
   225         {
   226             if (aInfo.PropertyType == typeof(int))
   227             {
   228                 return true;
   229             }
   230             else if (aInfo.PropertyType.IsEnum)
   231             {
   232                 return true;
   233             }
   234             else if (aInfo.PropertyType == typeof(bool))
   235             {
   236                 return true;
   237             }
   238             else if (aInfo.PropertyType == typeof(string))
   239             {
   240                 return true;
   241             }
   242             //TODO: add support for other type here
   243 
   244             return false;
   245         }
   246 
   247         /// <summary>
   248         /// Update our table layout.
   249         /// Will instantiated every field control as defined by our action.
   250         /// Fields must be specified by rows from the left.
   251         /// </summary>
   252         /// <param name="aLayout"></param>
   253         private void UpdateTableLayoutPanel(SharpLib.Ear.Action aAction)
   254         {
   255             toolTip.RemoveAll();
   256             //Debug.Print("UpdateTableLayoutPanel")
   257             //First clean our current panel
   258             iTableLayoutPanel.Controls.Clear();
   259             iTableLayoutPanel.RowStyles.Clear();
   260             iTableLayoutPanel.ColumnStyles.Clear();
   261             iTableLayoutPanel.RowCount = 0;
   262 
   263             //We always want two columns: one for label and one for the field
   264             iTableLayoutPanel.ColumnCount = 2;
   265             iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
   266             iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
   267 
   268 
   269             if (aAction == null)
   270             {
   271                 //Just drop it
   272                 return;
   273             }
   274             
   275             //IEnumerable<PropertyInfo> properties = aAction.GetType().GetProperties().Where(
   276             //    prop => Attribute.IsDefined(prop, typeof(AttributeActionProperty)));
   277 
   278 
   279             foreach (PropertyInfo pi in aAction.GetType().GetProperties())
   280             {
   281                 AttributeActionProperty[] attributes = ((AttributeActionProperty[])pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
   282                 if (attributes.Length != 1)
   283                 {
   284                     continue;
   285                 }
   286 
   287                 AttributeActionProperty attribute = attributes[0];
   288 
   289                 //Before anything we need to check if that kind of property is supported by our UI
   290                 //Create the editor
   291                 Control ctrl = CreateControlForProperty(pi, attribute, aAction);
   292                 if (ctrl == null)
   293                 {
   294                     //Property type not supported
   295                     continue;
   296                 }
   297 
   298                 //Add a new row
   299                 iTableLayoutPanel.RowCount++;
   300                 iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
   301                 //Create the label
   302                 Label label = new Label();
   303                 label.AutoSize = true;
   304                 label.Dock = DockStyle.Fill;
   305                 label.TextAlign = ContentAlignment.MiddleCenter;
   306                 label.Text = attribute.Name;
   307                 toolTip.SetToolTip(label, attribute.Description);
   308                 iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
   309 
   310                 //Add our editor to our form
   311                 iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
   312                 //Add tooltip to editor too
   313                 toolTip.SetToolTip(ctrl, attribute.Description);
   314 
   315             }        
   316 
   317         }
   318 
   319         private void buttonTest_Click(object sender, EventArgs e)
   320         {
   321             FetchPropertiesValue(Action);
   322             Action.Execute();
   323         }
   324     }
   325 }