Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3443 was 3376, checked in by swagner, 14 years ago

Moved interfaces and classes for deep cloning from HeuristicLab.Core to HeuristicLab.Common (#975).

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