Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Operators.Programmable/3.3/ProgrammableOperatorView.cs @ 3172

Last change on this file since 3172 was 3014, checked in by epitzer, 14 years ago

Correctly update displayed method signature if operator parameters change (#842)

File size: 10.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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;
35using HeuristicLab.Core.Views;
36using HeuristicLab.Operators.Views;
37using HeuristicLab.MainForm;
38
39namespace HeuristicLab.Operators.Programmable {
40  [View("ProgrammableOperator View")]
41  [Content(typeof(ProgrammableOperator), true)]
42  public partial class ProgrammableOperatorView : NamedItemView {
43
44    public ProgrammableOperator ProgrammableOperator {
45      get { return (ProgrammableOperator)base.Content; }
46      set { base.Content = (ProgrammableOperator)value; }
47    }
48
49    public ProgrammableOperatorView() {
50      InitializeComponent();
51    }
52
53    public ProgrammableOperatorView(ProgrammableOperator programmableOperator)
54      : this() {
55      ProgrammableOperator = programmableOperator;
56    }
57
58    protected override void RegisterContentEvents() {
59      base.RegisterContentEvents();
60      ProgrammableOperator.CodeChanged += ProgrammableOperator_CodeChanged;
61      ProgrammableOperator.DescriptionChanged += ProgrammableOperator_DescriptionChanged;
62      ProgrammableOperator.SignatureChanged += ProgrammableOperator_SignatureChanged;
63    }
64
65    protected override void DeregisterContentEvents() {
66      ProgrammableOperator.CodeChanged -= ProgrammableOperator_CodeChanged;
67      ProgrammableOperator.DescriptionChanged -= ProgrammableOperator_DescriptionChanged;
68      ProgrammableOperator.SignatureChanged -= ProgrammableOperator_SignatureChanged;
69      base.DeregisterContentEvents();
70    }
71
72    protected override void OnContentChanged() {
73      base.OnContentChanged();
74      if (ProgrammableOperator == null) {
75        codeEditor.Text = "";
76        codeEditor.Enabled = false;
77        descriptionTextBox.Text = "";
78        descriptionTextBox.Enabled = false;
79        assembliesTreeView.Nodes.Clear();
80        parameterCollectionView.Content = null;
81      } else {
82        codeEditor.Enabled = true;
83        descriptionTextBox.Text = ProgrammableOperator.Description;
84        descriptionTextBox.Enabled = true;
85        codeEditor.Prefix = GetGeneratedPrefix();
86        codeEditor.Suffix = @"
87    return null;
88  }
89}";
90        codeEditor.UserCode = ProgrammableOperator.Code;
91        if (codeEditor.UserCode == "")
92          codeEditor.UserCode = "\n\n\n";
93        InitializeAssemblyList();
94        InitializeNamespacesList();
95        foreach (var a in ProgrammableOperator.SelectedAssemblies) {
96          codeEditor.AddAssembly(a);
97        }
98        codeEditor.ScrollAfterPrefix();
99        codeEditor.ShowCompileErrors(ProgrammableOperator.CompileErrors, "ProgrammableOperator");
100        showCodeButton.Enabled =
101          ProgrammableOperator.CompilationUnitCode != null &&
102          ProgrammableOperator.CompilationUnitCode.Length > 0;
103        parameterCollectionView.Content = ProgrammableOperator.Parameters;
104      }
105    }
106
107
108    private string GetGeneratedPrefix() {
109      StringBuilder prefix = new StringBuilder();
110      foreach (var ns in ProgrammableOperator.GetSelectedAndValidNamespaces()) {
111        prefix.Append("using ").Append(ns).AppendLine(";");
112      }
113      prefix.AppendLine();
114      prefix.Append("public class ").Append(ProgrammableOperator.CompiledTypeName).AppendLine(" {");
115      prefix.Append("  ").Append(ProgrammableOperator.Signature).AppendLine(" {");
116      return prefix.ToString();
117    }
118
119    private void codeEditor_Validated(object sender, EventArgs e) {
120      ProgrammableOperator.Code = codeEditor.UserCode;
121    }
122
123    private void Recompile() {
124      this.Enabled = false;
125      try {
126        ProgrammableOperator.Compile();
127        MessageBox.Show("Compilation successful", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
128      } catch (Exception ex) {
129        Auxiliary.ShowErrorMessageBox(ex);
130      }
131      OnContentChanged();
132      this.Enabled = true;
133    }
134
135    private void compileButton_Click(object sender, EventArgs e) {
136      Recompile();
137    }
138
139    #region ProgrammableOperator Events
140    private void ProgrammableOperator_CodeChanged(object sender, EventArgs e) {
141      codeEditor.Text = ProgrammableOperator.Code;
142    }
143    private void ProgrammableOperator_DescriptionChanged(object sender, EventArgs e) {
144      descriptionTextBox.Text = ProgrammableOperator.Description;
145    }
146    private void ProgrammableOperator_SignatureChanged(object sender, EventArgs args) {
147      codeEditor.Prefix = GetGeneratedPrefix();
148    }
149    #endregion
150
151    private void assembliesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
152      if (initializing)
153        return;
154      Assembly a = e.Node.Tag as Assembly;
155      if (a == null && e.Node.Nodes.Count > 0) {
156        foreach (TreeNode n in e.Node.Nodes)
157          n.Checked = e.Node.Checked;
158        return;
159      } else {
160        if (e.Node.Checked) {
161          ProgrammableOperator.SelectAssembly(a);
162          codeEditor.AddAssembly(a);
163        } else {
164          ProgrammableOperator.UnselectAssembly(a);
165          codeEditor.RemoveAssembly(a);
166        }
167      }
168      InitializeNamespacesList();
169      codeEditor.Prefix = GetGeneratedPrefix();
170    }
171
172    private bool initializing = false;
173    private void InitializeAssemblyList() {
174      initializing = true;
175      assembliesTreeView.Enabled = false;
176      namespacesTreeView.Enabled = false;
177      assembliesTreeView.BeginUpdate();
178      assembliesTreeView.Nodes.Clear();
179      var selectedAssemblies = new HashSet<Assembly>(ProgrammableOperator.SelectedAssemblies);
180      foreach (var p in ProgrammableOperator.Plugins) {
181        var node = assembliesTreeView.Nodes.Add(p.Key);
182        node.Tag = p;
183        foreach (var a in p.Value) {
184          var aNode = node.Nodes.Add(a.GetName().Name);
185          aNode.Tag = a;
186          if (selectedAssemblies.Contains(a))
187            aNode.Checked = true;
188        }
189        if (node.Nodes.Count == 1 && node.Nodes[0].Name == node.Nodes[0].Name) {
190          node.Tag = node.Nodes[0].Tag;
191          node.Nodes.Clear();
192        } else if (node.Nodes.Count > 0 && node.Nodes.Cast<TreeNode>().All(n => n.Checked)) {
193          node.Checked = true;
194        }
195      }
196      assembliesTreeView.EndUpdate();
197      assembliesTreeView.Enabled = true;
198      namespacesTreeView.Enabled = true;
199      initializing = false;
200    }
201
202    private void InitializeNamespacesList() {
203      initializing = true;
204      namespacesTreeView.Enabled = false;
205      namespacesTreeView.BeginUpdate();
206      TreeNode oldTree = new TreeNode("root");
207      CloneTreeNodeCollection(oldTree, namespacesTreeView.Nodes);
208      namespacesTreeView.Nodes.Clear();
209      var selectedNamespaces = new HashSet<string>(ProgrammableOperator.Namespaces);
210      foreach (var ns in ProgrammableOperator.GetAllNamespaces(true))
211        AddNamespace(namespacesTreeView.Nodes, ns, selectedNamespaces.Contains(ns), oldTree);
212      codeEditor.Prefix = GetGeneratedPrefix();
213      namespacesTreeView.EndUpdate();
214      namespacesTreeView.Enabled = true;
215      initializing = false;
216    }
217
218    private void CloneTreeNodeCollection(TreeNode root, TreeNodeCollection nodes) {
219      foreach (TreeNode n in nodes) {
220        TreeNode newNode = root.Nodes.Add(n.Text, n.Text);
221        newNode.Checked = n.Checked;
222        CloneTreeNodeCollection(newNode, n.Nodes);
223        if (n.IsExpanded)
224          newNode.Expand();
225      }
226    }
227
228    private bool AddNamespace(TreeNodeCollection parentNodes, string ns, bool isSelected, TreeNode oldTree) {
229      int dotIndex = ns.IndexOf('.');
230      string prefix = ns;
231      if (dotIndex != -1)
232        prefix = ns.Substring(0, dotIndex);
233      TreeNode node = GetOrCreateNode(parentNodes, prefix);
234      TreeNode oldNode = MaybeGetNode(oldTree, prefix);
235      bool isNew = oldNode == null;
236      if (dotIndex != -1 && dotIndex + 1 < ns.Length) {
237        isNew = AddNamespace(node.Nodes, ns.Substring(dotIndex + 1, ns.Length - (dotIndex + 1)), isSelected, oldNode);
238      } else {
239        node.Checked = isSelected;
240      }
241      if (isNew || oldNode != null && oldNode.IsExpanded)
242        node.Expand();
243      if (isNew)
244        namespacesTreeView.SelectedNode = node;
245      return isNew;
246    }
247
248    private static TreeNode MaybeGetNode(TreeNode parentNode, string key) {
249      if (parentNode == null)
250        return null;
251      if (parentNode.Nodes.ContainsKey(key))
252        return parentNode.Nodes[key];
253      return null;
254    }
255
256    private static TreeNode GetOrCreateNode(TreeNodeCollection parentNodes, string key) {
257      TreeNode node = null;
258      if (parentNodes.ContainsKey(key)) {
259        node = parentNodes[key];
260      } else {
261        node = parentNodes.Add(key, key);
262      }
263      return node;
264    }
265
266    private void namespacesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
267      if (initializing)
268        return;
269      if (e.Node.Checked) {
270        ProgrammableOperator.SelectNamespace(e.Node.FullPath);
271      } else {
272        ProgrammableOperator.UnselectNamespace(e.Node.FullPath);
273      }
274      codeEditor.Prefix = GetGeneratedPrefix();
275    }
276
277    private void showCodeButton_Click(object sender, EventArgs e) {
278      new CodeViewer(ProgrammableOperator.CompilationUnitCode).ShowDialog(this);
279    }
280
281    private void descriptionTextBox_TextChanged(object sender, EventArgs e) {
282      ProgrammableOperator.SetDescription(descriptionTextBox.Text);
283    }
284
285
286  }
287}
Note: See TracBrowser for help on using the repository browser.