Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Operators.Programmable/3.2/ProgrammableOperatorView.cs @ 2660

Last change on this file since 2660 was 2660, checked in by epitzer, 15 years ago

New ProgrammableOperator with syntax highlighting, code completion, configurable assemblies and namespaces (#842)

File size: 9.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
26using System.Data;
27using System.Text;
28using System.Linq;
29using System.Windows.Forms;
30using HeuristicLab.Core;
31using HeuristicLab.Operators;
32using System.CodeDom.Compiler;
33using System.Reflection;
34using HeuristicLab.CodeEditor;
35
36namespace HeuristicLab.Operators.Programmable {
37
38  public partial class ProgrammableOperatorView : ViewBase {
39
40    public ProgrammableOperator ProgrammableOperator {
41      get { return (ProgrammableOperator)Item; }
42      set { base.Item = value; }
43    }
44
45    public ProgrammableOperatorView() {
46      InitializeComponent();
47    }
48
49    public ProgrammableOperatorView(ProgrammableOperator programmableOperator)
50      : this() {
51      ProgrammableOperator = programmableOperator;
52    }
53   
54    protected override void RemoveItemEvents() {
55      operatorBaseVariableInfosView.Operator = null;
56      operatorBaseVariablesView.Operator = null;
57      constrainedItemBaseView.ConstrainedItem = null;
58      ProgrammableOperator.CodeChanged -= new EventHandler(ProgrammableOperator_CodeChanged);
59      ProgrammableOperator.DescriptionChanged -= new EventHandler(ProgrammableOperator_DescriptionChanged);
60      base.RemoveItemEvents();
61    }
62
63    protected override void AddItemEvents() {
64      base.AddItemEvents();
65      operatorBaseVariableInfosView.Operator = ProgrammableOperator;
66      operatorBaseVariablesView.Operator = ProgrammableOperator;
67      constrainedItemBaseView.ConstrainedItem = ProgrammableOperator;
68      ProgrammableOperator.CodeChanged += new EventHandler(ProgrammableOperator_CodeChanged);
69      ProgrammableOperator.DescriptionChanged += new EventHandler(ProgrammableOperator_DescriptionChanged);
70    }
71
72    protected override void UpdateControls() {
73      base.UpdateControls();
74      if (ProgrammableOperator == null) {
75        codeEditor.Text = "";
76        codeEditor.Enabled = false;
77        addVariableInfoButton.Enabled = false;
78        removeVariableInfoButton.Enabled = false;
79        descriptionTextBox.Text = "";
80        descriptionTextBox.Enabled = false;
81        codeEditor.Prefix = @"using System
82
83public class Operator {
84  public static IOperation Execute(IOperator op, IScope scope, parameters ...) {";
85        codeEditor.Suffix = @"
86    return null;
87  }
88}";   
89        assembliesListBox.DataSource = null;
90      } else {       
91        codeEditor.Enabled = true;
92        addVariableInfoButton.Enabled = true;
93        removeVariableInfoButton.Enabled = operatorBaseVariableInfosView.SelectedVariableInfos.Count > 0;
94        descriptionTextBox.Text = ProgrammableOperator.Description;
95        descriptionTextBox.Enabled = true;
96        codeEditor.Prefix = GetGeneratedPrefix();
97        codeEditor.Suffix = @"
98    return null;
99  }
100}";
101        codeEditor.UserCode = ProgrammableOperator.Code;
102        if (codeEditor.UserCode == "")
103          codeEditor.UserCode = "\n\n\n";
104        InitializeAssemblyList();
105        InitializeNamespacesList();
106        foreach (var a in ProgrammableOperator.SelectedAssemblies) {
107          codeEditor.AddAssembly(a);
108        }
109        codeEditor.ScrollAfterPrefix();
110      }     
111    }
112
113   
114    private string GetGeneratedPrefix() {
115      StringBuilder prefix = new StringBuilder();
116      foreach (var ns in ProgrammableOperator.GetSelectedAndValidNamespaces()) {
117        prefix.Append("using ").Append(ns).AppendLine(";");
118      }
119      prefix.AppendLine();
120      prefix.Append("public class ").Append(ProgrammableOperator.CompiledTypeName).AppendLine(" {");
121      prefix.Append("  ").Append(ProgrammableOperator.Signature).Append(" {");
122      return prefix.ToString();
123    }
124
125    private void operatorBaseVariableInfosView_SelectedVariableInfosChanged(object sender, EventArgs e) {
126      removeVariableInfoButton.Enabled = operatorBaseVariableInfosView.SelectedVariableInfos.Count > 0;
127    }
128    private void codeEditor_Validated(object sender, EventArgs e) {
129      ProgrammableOperator.Code = codeEditor.UserCode;
130    }
131    private void descriptionTextBox_Validated(object sender, EventArgs e) {
132      ProgrammableOperator.SetDescription(descriptionTextBox.Text);
133    }
134
135    private void addVariableInfoButton_Click(object sender, EventArgs e) {
136      AddVariableInfoDialog dialog = new AddVariableInfoDialog();
137      if (dialog.ShowDialog(this) == DialogResult.OK) {
138        if (ProgrammableOperator.GetVariableInfo(dialog.VariableInfo.FormalName) != null) {
139          Auxiliary.ShowErrorMessageBox("A variable info with the same formal name already exists.");
140        } else {
141          ProgrammableOperator.AddVariableInfo(dialog.VariableInfo);
142          Recompile();         
143        }
144      }
145      dialog.Dispose();
146    }
147
148    private void removeVariableInfoButton_Click(object sender, EventArgs e) {
149      IVariableInfo[] selected = new IVariableInfo[operatorBaseVariableInfosView.SelectedVariableInfos.Count];
150      operatorBaseVariableInfosView.SelectedVariableInfos.CopyTo(selected, 0);
151      for (int i = 0; i < selected.Length; i++)
152        ProgrammableOperator.RemoveVariableInfo(selected[i].FormalName);
153    }
154
155    private void Recompile() {
156      try {
157        ProgrammableOperator.Compile();       
158        MessageBox.Show("Compilation successful", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
159      } catch (Exception ex) {
160        Auxiliary.ShowErrorMessageBox(ex);
161      }
162      UpdateControls();
163      codeEditor.ShowCompileErrors(ProgrammableOperator.CompileErrors, "ProgrammableOperator");     
164    }
165
166    private void compileButton_Click(object sender, EventArgs e) {
167      Recompile();
168    }   
169
170    #region ProgrammableOperator Events
171    private void ProgrammableOperator_CodeChanged(object sender, EventArgs e) {
172      codeEditor.Text = ProgrammableOperator.Code;
173    }
174    private void ProgrammableOperator_DescriptionChanged(object sender, EventArgs e) {
175      descriptionTextBox.Text = ProgrammableOperator.Description;
176    }
177    #endregion
178
179    public static Assembly GetAssembly(CheckedListBox box, int index) {
180      return (Assembly)(((CheckedListBoxItem)box.Items[index]).Tag);
181    }
182
183    private void assembliesListBox_ItemCheck(object sender, ItemCheckEventArgs e) {
184      if (initializing)
185        return;
186      Assembly a = GetAssembly(assembliesListBox, e.Index);
187      if (e.NewValue == CheckState.Checked) {               
188        ProgrammableOperator.SelectAssembly(a);
189        codeEditor.AddAssembly(a);
190      } else if (e.NewValue == CheckState.Unchecked) {
191        ProgrammableOperator.UnselectAssembly(a);
192        codeEditor.RemoveAssembly(a);
193      } else {
194        return;
195      }
196      InitializeNamespacesList();     
197      codeEditor.Prefix = GetGeneratedPrefix();
198    }
199
200    private bool initializing = false;
201    private void InitializeAssemblyList() {
202      assembliesListBox.Items.Clear();
203      var selectedAssemblies = new HashSet<Assembly>(ProgrammableOperator.SelectedAssemblies);
204      initializing = true;
205      foreach (var a in ProgrammableOperator.AvailableAssemblies.ToList()) {
206        assembliesListBox.Items.Add(
207          new CheckedListBoxItem(a.GetName().Name, a),
208          selectedAssemblies.Contains(a));
209      }
210      initializing = false;
211    }
212
213    private void InitializeNamespacesList() {
214      initializing = true;
215      namespacesListBox.Items.Clear();
216      var selectedNamespaces = new HashSet<string>(ProgrammableOperator.Namespaces);
217      foreach (var ns in ProgrammableOperator.GetAllNamespaces(true)) {
218        namespacesListBox.Items.Add(ns, selectedNamespaces.Contains(ns));
219      }
220      codeEditor.Prefix = GetGeneratedPrefix();
221      initializing = false;
222    }
223
224    private void namespacesListBox_ItemCheck(object sender, ItemCheckEventArgs e) {
225      if (initializing)
226        return;
227      if (e.NewValue == CheckState.Checked) {
228        ProgrammableOperator.SelectNamespace((string)namespacesListBox.Items[e.Index]);
229      } else if (e.NewValue == CheckState.Unchecked) {
230        ProgrammableOperator.UnselectNamespace((string)namespacesListBox.Items[e.Index]);
231      }
232      codeEditor.Prefix = GetGeneratedPrefix();
233    }
234
235    private void showCodeButton_Click(object sender, EventArgs e) {
236      new CodeViewer(ProgrammableOperator.CompilationUnitCode).ShowDialog(this);
237    }
238
239  }
240
241  public class CheckedListBoxItem : IComparable {
242
243    public object Tag { get; private set; }
244    public string Text { get; private set; }
245
246    public CheckedListBoxItem(string text, object tag) {
247      Text = text;
248      Tag = tag;
249    }
250
251    public override string ToString() {
252      return Text;
253    }
254
255    public int CompareTo(object obj) {
256      if (obj == null)
257        throw new ArgumentException("cannot compare to null");
258      if (!(obj is CheckedListBoxItem))
259        throw new ArgumentException(string.Format(
260          "cannot compare CheckedListBoxItem to {0}",
261          obj.GetType().Name));
262      return Text.CompareTo(((CheckedListBoxItem)obj).Text);
263    }
264  }
265}
Note: See TracBrowser for help on using the repository browser.