Free cookie consent management tool by TermsFeed Policy Generator

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

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

Group assemblies by plugin and replace assembly and namespace list boxes with tree views (#842)

File size: 10.1 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";
86        codeEditor.Suffix = @"
87    return null;
88  }
89}";
90        assembliesTreeView.Nodes.Clear();
91      } else {
92        codeEditor.Enabled = true;
93        addVariableInfoButton.Enabled = true;
94        removeVariableInfoButton.Enabled = operatorBaseVariableInfosView.SelectedVariableInfos.Count > 0;
95        descriptionTextBox.Text = ProgrammableOperator.Description;
96        descriptionTextBox.Enabled = true;
97        codeEditor.Prefix = GetGeneratedPrefix();
98        codeEditor.Suffix = @"
99    return null;
100  }
101}";
102        codeEditor.UserCode = ProgrammableOperator.Code;
103        if (codeEditor.UserCode == "")
104          codeEditor.UserCode = "\n\n\n";
105        InitializeAssemblyList();
106        InitializeNamespacesList();
107        foreach (var a in ProgrammableOperator.SelectedAssemblies) {
108          codeEditor.AddAssembly(a);
109        }
110        codeEditor.ScrollAfterPrefix();
111      }
112    }
113
114
115    private string GetGeneratedPrefix() {
116      StringBuilder prefix = new StringBuilder();
117      foreach (var ns in ProgrammableOperator.GetSelectedAndValidNamespaces()) {
118        prefix.Append("using ").Append(ns).AppendLine(";");
119      }
120      prefix.AppendLine();
121      prefix.Append("public class ").Append(ProgrammableOperator.CompiledTypeName).AppendLine(" {");
122      prefix.Append("  ").Append(ProgrammableOperator.Signature).AppendLine(" {");
123      return prefix.ToString();
124    }
125
126    private void operatorBaseVariableInfosView_SelectedVariableInfosChanged(object sender, EventArgs e) {
127      removeVariableInfoButton.Enabled = operatorBaseVariableInfosView.SelectedVariableInfos.Count > 0;
128    }
129    private void codeEditor_Validated(object sender, EventArgs e) {
130      ProgrammableOperator.Code = codeEditor.UserCode;
131    }
132    private void descriptionTextBox_Validated(object sender, EventArgs e) {
133      ProgrammableOperator.SetDescription(descriptionTextBox.Text);
134    }
135
136    private void addVariableInfoButton_Click(object sender, EventArgs e) {
137      AddVariableInfoDialog dialog = new AddVariableInfoDialog();
138      if (dialog.ShowDialog(this) == DialogResult.OK) {
139        if (ProgrammableOperator.GetVariableInfo(dialog.VariableInfo.FormalName) != null) {
140          Auxiliary.ShowErrorMessageBox("A variable info with the same formal name already exists.");
141        } else {
142          ProgrammableOperator.AddVariableInfo(dialog.VariableInfo);
143          Recompile();
144        }
145      }
146      dialog.Dispose();
147    }
148
149    private void removeVariableInfoButton_Click(object sender, EventArgs e) {
150      IVariableInfo[] selected = new IVariableInfo[operatorBaseVariableInfosView.SelectedVariableInfos.Count];
151      operatorBaseVariableInfosView.SelectedVariableInfos.CopyTo(selected, 0);
152      for (int i = 0; i < selected.Length; i++)
153        ProgrammableOperator.RemoveVariableInfo(selected[i].FormalName);
154      Recompile();
155    }
156
157    private void Recompile() {
158      try {
159        ProgrammableOperator.Compile();
160        MessageBox.Show("Compilation successful", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
161      } catch (Exception ex) {
162        Auxiliary.ShowErrorMessageBox(ex);
163      }
164      UpdateControls();
165      codeEditor.ShowCompileErrors(ProgrammableOperator.CompileErrors, "ProgrammableOperator");
166    }
167
168    private void compileButton_Click(object sender, EventArgs e) {
169      Recompile();
170    }
171
172    #region ProgrammableOperator Events
173    private void ProgrammableOperator_CodeChanged(object sender, EventArgs e) {
174      codeEditor.Text = ProgrammableOperator.Code;
175    }
176    private void ProgrammableOperator_DescriptionChanged(object sender, EventArgs e) {
177      descriptionTextBox.Text = ProgrammableOperator.Description;
178    }
179    #endregion
180
181    private void assembliesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
182      if (initializing)
183        return;
184      Assembly a = e.Node.Tag as Assembly;
185      if (a == null && e.Node.Nodes.Count > 0) {
186        foreach (TreeNode n in e.Node.Nodes)
187          n.Checked = e.Node.Checked;
188        return;
189      } else {
190        if (e.Node.Checked) {
191          ProgrammableOperator.SelectAssembly(a);
192          codeEditor.AddAssembly(a);
193        } else {
194          ProgrammableOperator.UnselectAssembly(a);
195          codeEditor.RemoveAssembly(a);
196        }
197      }
198      InitializeNamespacesList();
199      codeEditor.Prefix = GetGeneratedPrefix();
200    }
201
202    private bool initializing = false;
203    private void InitializeAssemblyList() {
204      initializing = true;
205      assembliesTreeView.BeginUpdate();
206      assembliesTreeView.Nodes.Clear();
207      var selectedAssemblies = new HashSet<Assembly>(ProgrammableOperator.SelectedAssemblies);
208      foreach (var p in ProgrammableOperator.Plugins) {
209        var node = assembliesTreeView.Nodes.Add(p.Key);
210        node.Tag = p;
211        foreach (var a in p.Value) {
212          var aNode = node.Nodes.Add(a.GetName().Name);
213          aNode.Tag = a;
214          if (selectedAssemblies.Contains(a))
215            aNode.Checked = true;
216        }
217        if (node.Nodes.Count == 1 && node.Nodes[0].Name == node.Nodes[0].Name) {
218          node.Tag = node.Nodes[0].Tag;
219          node.Nodes.Clear();
220        } else if (node.Nodes.Count > 0 && node.Nodes.Cast<TreeNode>().All(n => n.Checked)) {
221          node.Checked = true;
222        }
223      }
224      assembliesTreeView.EndUpdate();
225      initializing = false;
226    }
227
228    private void InitializeNamespacesList() {
229      initializing = true;
230      namespacesTreeView.Nodes.Clear();
231      var selectedNamespaces = new HashSet<string>(ProgrammableOperator.Namespaces);
232      foreach (var ns in ProgrammableOperator.GetAllNamespaces(true))
233        AddNamespace(namespacesTreeView.Nodes, ns, selectedNamespaces.Contains(ns));
234      codeEditor.Prefix = GetGeneratedPrefix();
235      initializing = false;
236    }
237
238    private void AddNamespace(TreeNodeCollection parentNodes, string ns, bool isSelected) {
239      int dotIndex = ns.IndexOf('.');
240      string prefix = ns;
241      if (dotIndex != -1)
242        prefix = ns.Substring(0, dotIndex);
243      TreeNode node = null;
244      if (parentNodes.ContainsKey(prefix)) {
245        node = parentNodes[prefix];
246      } else {
247        node = parentNodes.Add(prefix, prefix);
248      }
249      if (dotIndex != -1 && dotIndex + 1 < ns.Length) {
250        AddNamespace(node.Nodes, ns.Substring(dotIndex + 1, ns.Length - (dotIndex + 1)), isSelected);
251        if (isSelected)
252          node.Expand();
253      }  else
254        node.Checked = isSelected;
255    }
256
257    private void namespacesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
258      if (initializing)
259        return;
260      if (e.Node.Checked) {
261        ProgrammableOperator.SelectNamespace(e.Node.FullPath);
262      } else {
263        ProgrammableOperator.UnselectNamespace(e.Node.FullPath);
264      }
265      codeEditor.Prefix = GetGeneratedPrefix();
266    }
267
268    private void showCodeButton_Click(object sender, EventArgs e) {
269      new CodeViewer(ProgrammableOperator.CompilationUnitCode).ShowDialog(this);
270    }
271
272
273  }
274}
Note: See TracBrowser for help on using the repository browser.