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