Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core.Views/3.3/OperatorGraphView.cs @ 2526

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

Refactored cloning (#806)

File size: 20.0 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.Windows.Forms;
29using HeuristicLab.PluginInfrastructure;
30using HeuristicLab.Common;
31using HeuristicLab.MainForm;
32
33namespace HeuristicLab.Core.Views {
34  /// <summary>
35  /// The visual representation of an <see cref="IOperatorGraph"/>.
36  /// </summary>
37  [Content(typeof(OperatorGraph), true)]
38  public partial class OperatorGraphView : ViewBase {
39    private ChooseOperatorDialog chooseOperatorDialog;
40    private Dictionary<IOperator, IList<TreeNode>> operatorNodeTable;
41
42    /// <summary>
43    /// Gets or sets the operator graph to represent visually.
44    /// </summary>
45    /// <remarks>Uses property <see cref="ViewBase.Item"/> of base class <see cref="ViewBase"/>.
46    /// No own data storage present.</remarks>
47    public IOperatorGraph OperatorGraph {
48      get { return (IOperatorGraph)Item; }
49      set { base.Item = value; }
50    }
51
52    /// <summary>
53    /// Initializes a new instance of <see cref="OperatorGraphView"/> with caption "Operator Graph".
54    /// </summary>
55    public OperatorGraphView() {
56      InitializeComponent();
57      operatorNodeTable = new Dictionary<IOperator, IList<TreeNode>>();
58      operatorsListView.Columns[0].Width = Math.Max(0, operatorsListView.Width - 25);
59      Caption = "Operator Graph";
60    }
61    /// <summary>
62    /// Initializes a new instance of <see cref="OperatorGraphView"/>
63    /// with the given <paramref name="operatorGraph"/>.
64    /// </summary>
65    /// <remarks>Calls <see cref="OperatorGraphView()"/>.</remarks>
66    /// <param name="operatorGraph">The operator graph to represent visually.</param>
67    public OperatorGraphView(IOperatorGraph operatorGraph)
68      : this() {
69      OperatorGraph = operatorGraph;
70    }
71
72    /// <summary>
73    /// Removes the eventhandlers from the underlying <see cref="IOperatorGraph"/>.
74    /// </summary>
75    /// <remarks>Calls <see cref="ViewBase.RemoveItemEvents"/> of base class <see cref="ViewBase"/>.</remarks>
76    protected override void RemoveItemEvents() {
77      OperatorGraph.OperatorAdded -= new EventHandler<EventArgs<IOperator>>(OperatorGraph_OperatorAdded);
78      OperatorGraph.OperatorRemoved -= new EventHandler<EventArgs<IOperator>>(OperatorGraph_OperatorRemoved);
79      OperatorGraph.InitialOperatorChanged -= new EventHandler(OperatorGraph_InitialOperatorChanged);
80      base.RemoveItemEvents();
81    }
82    /// <summary>
83    /// Adds eventhandlers to the underlying <see cref="IOperatorGraph"/>.
84    /// </summary>
85    /// <remarks>Calls <see cref="ViewBase.AddItemEvents"/> of base class <see cref="ViewBase"/>.</remarks>
86    protected override void AddItemEvents() {
87      base.AddItemEvents();
88      OperatorGraph.OperatorAdded += new EventHandler<EventArgs<IOperator>>(OperatorGraph_OperatorAdded);
89      OperatorGraph.OperatorRemoved += new EventHandler<EventArgs<IOperator>>(OperatorGraph_OperatorRemoved);
90      OperatorGraph.InitialOperatorChanged += new EventHandler(OperatorGraph_InitialOperatorChanged);
91    }
92
93    /// <summary>
94    /// Updates all controls with the latest data of the model.
95    /// </summary>
96    /// <remarks>Calls <see cref="ViewBase.UpdateControls"/> of base class <see cref="ViewBase"/>.</remarks>
97    protected override void UpdateControls() {
98      base.UpdateControls();
99      if (graphTreeView.Nodes.Count > 0)
100        RemoveTreeNode(graphTreeView.Nodes[0]);
101      graphTreeView.SelectedNode = null;
102      graphTreeView.Nodes.Clear();
103      graphTreeView.Enabled = false;
104      operatorsListView.Items.Clear();
105      removeButton.Enabled = false;
106      if (OperatorGraph == null) {
107        Caption = "Operator Graph";
108        operatorsListView.Enabled = false;
109        addOperatorButton.Enabled = false;
110      } else {
111        Caption = "Operator Graph (" + OperatorGraph.GetType().Name + ")";
112        foreach (IOperator op in OperatorGraph.Operators) {
113          operatorsListView.Items.Add(CreateListViewItem(op));
114        }
115        operatorsListView.Enabled = true;
116        addOperatorButton.Enabled = true;
117        if (OperatorGraph.InitialOperator != null) {
118          graphTreeView.Nodes.Add(CreateTreeNode(OperatorGraph.InitialOperator));
119          graphTreeView.Enabled = true;
120        }
121      }
122    }
123
124    private ListViewItem CreateListViewItem(IOperator op) {
125      ListViewItem item = new ListViewItem();
126      item.Text = op.Name;
127      item.Tag = op;
128      item.ImageIndex = 0;
129      if (op.GetType().Name == "CombinedOperator")
130        item.ImageIndex = 1;
131      else if (op.GetType().Name == "ProgrammableOperator")
132        item.ImageIndex = 2;
133      if (op == OperatorGraph.InitialOperator)
134        item.Font = new Font(operatorsListView.Font, FontStyle.Bold);
135      return item;
136    }
137
138    private TreeNode CreateTreeNode(IOperator op) {
139      TreeNode node = new TreeNode();
140      node.Text = op.Name;
141      node.Tag = op;
142      if (op.Breakpoint)
143        node.ForeColor = Color.Red;
144
145      if (!operatorNodeTable.ContainsKey(op)) {
146        operatorNodeTable.Add(op, new List<TreeNode>());
147        op.NameChanged += new EventHandler(Operator_NameChanged);
148        op.BreakpointChanged += new EventHandler(Operator_BreakpointChanged);
149        op.SubOperatorAdded += new EventHandler<EventArgs<IOperator, int>>(Operator_SubOperatorAdded);
150        op.SubOperatorRemoved += new EventHandler<EventArgs<IOperator, int>>(Operator_SubOperatorRemoved);
151      }
152      operatorNodeTable[op].Add(node);
153
154      for (int i = 0; i < op.SubOperators.Count; i++)
155        node.Nodes.Add(new TreeNode());
156      return node;
157    }
158
159    private void RemoveTreeNode(TreeNode node) {
160      foreach (TreeNode child in node.Nodes)
161        RemoveTreeNode(child);
162
163      IOperator op = (IOperator)node.Tag;
164      if (op != null) {
165        operatorNodeTable[op].Remove(node);
166        if (operatorNodeTable[op].Count == 0) {
167          op.NameChanged -= new EventHandler(Operator_NameChanged);
168          op.BreakpointChanged -= new EventHandler(Operator_BreakpointChanged);
169          op.SubOperatorAdded -= new EventHandler<EventArgs<IOperator, int>>(Operator_SubOperatorAdded);
170          op.SubOperatorRemoved -= new EventHandler<EventArgs<IOperator, int>>(Operator_SubOperatorRemoved);
171          operatorNodeTable.Remove(op);
172        }
173      }
174    }
175
176    #region ListView Events
177    private void operatorsListView_SelectedIndexChanged(object sender, EventArgs e) {
178      removeButton.Enabled = false;
179      if (operatorsListView.SelectedItems.Count > 0) {
180        removeButton.Enabled = true;
181      }
182    }
183    private void operatorsListView_DoubleClick(object sender, EventArgs e) {
184      if (operatorsListView.SelectedItems.Count == 1) {
185        IOperator op = (IOperator)operatorsListView.SelectedItems[0].Tag;
186        IView view = (IView)MainFormManager.CreateDefaultView(op);
187        if (view != null)
188          PluginManager.ControlManager.ShowControl(view);
189      }
190    }
191    #endregion
192
193    #region TreeView Events
194    private void graphTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e) {
195      TreeNode node = e.Node;
196      IOperator op = (IOperator)node.Tag;
197      for (int i = 0; i < node.Nodes.Count; i++) {
198        if (node.Nodes[i].Tag == null) {
199          node.Nodes[i].Remove();
200          node.Nodes.Insert(i, CreateTreeNode(op.SubOperators[i]));
201        }
202      }
203    }
204    private void graphTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
205      IOperator op = (IOperator)e.Node.Tag;
206      foreach (ListViewItem item in operatorsListView.Items)
207        item.Selected = item.Tag == op;
208    }
209    #endregion
210
211    #region Size Changed Events
212    private void operatorsListView_SizeChanged(object sender, EventArgs e) {
213      if (operatorsListView.Columns.Count > 0)
214        operatorsListView.Columns[0].Width = Math.Max(0, operatorsListView.Width - 25);
215    }
216    #endregion
217
218    #region Key Events
219    private void operatorsListView_KeyDown(object sender, KeyEventArgs e) {
220      if (e.KeyCode == Keys.Delete) {
221        if (operatorsListView.SelectedItems.Count > 0) {
222          foreach (ListViewItem item in operatorsListView.SelectedItems)
223            OperatorGraph.RemoveOperator((IOperator)item.Tag);
224        }
225      }
226      if (e.KeyCode == Keys.F2) {
227        if (operatorsListView.SelectedItems.Count == 1)
228          operatorsListView.SelectedItems[0].BeginEdit();
229      }
230    }
231    private void graphTreeView_KeyDown(object sender, KeyEventArgs e) {
232      if (e.KeyCode == Keys.Delete) {
233        TreeNode node = graphTreeView.SelectedNode;
234        if ((node != null) && (node.Parent != null)) {
235          IOperator parent = (IOperator)node.Parent.Tag;
236          parent.RemoveSubOperator(node.Index);
237        }
238      }
239    }
240    #endregion
241
242    #region Edit Events
243    private void operatorsListView_AfterLabelEdit(object sender, LabelEditEventArgs e) {
244      e.CancelEdit = false;
245
246      string name = e.Label;
247      if (name != null) {
248        IOperator op = (IOperator)operatorsListView.Items[e.Item].Tag;
249        op.Name = name;
250      }
251    }
252    #endregion
253
254    #region Button Events
255    private void addOperatorButton_Click(object sender, EventArgs e) {
256      if (chooseOperatorDialog == null) chooseOperatorDialog = new ChooseOperatorDialog();
257      if (chooseOperatorDialog.ShowDialog(this) == DialogResult.OK)
258        OperatorGraph.AddOperator(chooseOperatorDialog.Operator);
259    }
260    private void removeButton_Click(object sender, EventArgs e) {
261      if (operatorsListView.SelectedItems.Count > 0) {
262        foreach (ListViewItem item in operatorsListView.SelectedItems)
263          OperatorGraph.RemoveOperator((IOperator)item.Tag);
264      }
265    }
266    #endregion
267
268    #region Drag and Drop Events
269    private void operatorsListView_ItemDrag(object sender, ItemDragEventArgs e) {
270      ListViewItem item = (ListViewItem)e.Item;
271      IOperator op = (IOperator)item.Tag;
272      DataObject data = new DataObject();
273      data.SetData("IOperator", op);
274      data.SetData("DragSource", operatorsListView);
275      DoDragDrop(data, DragDropEffects.Copy);
276    }
277    private void operatorsListView_DragEnter(object sender, DragEventArgs e) {
278      e.Effect = DragDropEffects.None;
279      if (e.Data.GetDataPresent("IOperator"))
280        e.Effect = DragDropEffects.Copy;
281    }
282    private void operatorsListView_DragOver(object sender, DragEventArgs e) {
283      e.Effect = DragDropEffects.None;
284      if (e.Data.GetDataPresent("IOperator"))
285        e.Effect = DragDropEffects.Copy;
286    }
287    private void operatorsListView_DragDrop(object sender, DragEventArgs e) {
288      if (e.Effect != DragDropEffects.None) {
289        if (e.Data.GetDataPresent("IOperator")) {
290          IOperator op = (IOperator)e.Data.GetData("IOperator");
291          op = (IOperator)op.Clone();
292          OperatorGraph.AddOperator(op);
293        }
294      }
295    }
296    private void graphTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
297      TreeNode node = (TreeNode)e.Item;
298      if (node.Parent != null) {
299        IOperator op = (IOperator)node.Tag;
300        IOperator parent = (IOperator)node.Parent.Tag;
301        int index = node.Index;
302        DataObject data = new DataObject();
303        data.SetData("IOperator", op);
304        data.SetData("DragSource", graphTreeView);
305        data.SetData("ParentOperator", parent);
306        data.SetData("Index", index);
307        DoDragDrop(data, DragDropEffects.Move);
308      }
309    }
310    private void graphTreeView_DragEnter(object sender, DragEventArgs e) {
311      e.Effect = DragDropEffects.None;
312      if (e.Data.GetDataPresent("IOperator")) {
313        Point p = graphTreeView.PointToClient(new Point(e.X, e.Y));
314        TreeNode node = graphTreeView.GetNodeAt(p);
315        if (node != null) {
316          if ((e.Data.GetDataPresent("ParentOperator")) && (node.Parent != null)) {
317            if ((e.Data.GetDataPresent("DragSource")) && (e.Data.GetData("DragSource") == graphTreeView))
318              e.Effect = DragDropEffects.Move;
319          } else {
320            if ((e.Data.GetDataPresent("DragSource")) && (e.Data.GetData("DragSource") == operatorsListView))
321              e.Effect = DragDropEffects.Copy;
322          }
323        }
324      }
325    }
326    private void graphTreeView_DragOver(object sender, DragEventArgs e) {
327      e.Effect = DragDropEffects.None;
328      if (e.Data.GetDataPresent("IOperator")) {
329        Point p = graphTreeView.PointToClient(new Point(e.X, e.Y));
330        TreeNode node = graphTreeView.GetNodeAt(p);
331        if (node != null) {
332          if ((e.Data.GetDataPresent("ParentOperator")) && (node.Parent != null)) {
333            if ((e.Data.GetDataPresent("DragSource")) && (e.Data.GetData("DragSource") == graphTreeView))
334              e.Effect = DragDropEffects.Move;
335          } else {
336            if ((e.Data.GetDataPresent("DragSource")) && (e.Data.GetData("DragSource") == operatorsListView))
337              e.Effect = DragDropEffects.Copy;
338          }
339        }
340      }
341    }
342    private void graphTreeView_DragDrop(object sender, DragEventArgs e) {
343      if (e.Effect != DragDropEffects.None) {
344        if (e.Data.GetDataPresent("IOperator")) {
345          IOperator op = (IOperator)e.Data.GetData("IOperator");
346          Point p = graphTreeView.PointToClient(new Point(e.X, e.Y));
347          TreeNode node = graphTreeView.GetNodeAt(p);
348          if (e.Data.GetDataPresent("ParentOperator")) {
349            if (node.Parent != null) {
350              TreeNode parentNode = node.Parent;
351              IOperator oldParent = (IOperator)e.Data.GetData("ParentOperator");
352              int oldIndex = (int)e.Data.GetData("Index");
353              IOperator newParent = (IOperator)node.Parent.Tag;
354              int newIndex = node.Index;
355              oldParent.RemoveSubOperator(oldIndex);
356              newParent.AddSubOperator(op, newIndex);
357              graphTreeView.SelectedNode = parentNode.Nodes[newIndex];
358            }
359          } else {
360            if (node != null) {
361              IOperator parent = (IOperator)node.Tag;
362              parent.AddSubOperator(op);
363              graphTreeView.SelectedNode = node.Nodes[node.Nodes.Count - 1];
364            }
365          }
366        }
367      }
368    }
369    #endregion
370
371    #region Context Menu Events
372    private void operatorsContextMenuStrip_Opening(object sender, CancelEventArgs e) {
373      viewToolStripMenuItem.Enabled = false;
374      initialOperatorToolStripMenuItem.Enabled = false;
375      initialOperatorToolStripMenuItem.Checked = false;
376      if (operatorsListView.SelectedItems.Count == 1) {
377        IOperator op = (IOperator)operatorsListView.SelectedItems[0].Tag;
378        IView view = (IView)MainFormManager.CreateDefaultView(op);
379        if (view != null) {
380          viewToolStripMenuItem.Enabled = true;
381          viewToolStripMenuItem.Tag = view;
382        }
383        initialOperatorToolStripMenuItem.Enabled = true;
384        initialOperatorToolStripMenuItem.Tag = op;
385        if (op == OperatorGraph.InitialOperator)
386          initialOperatorToolStripMenuItem.Checked = true;
387      }
388    }
389    private void viewToolStripMenuItem_Click(object sender, EventArgs e) {
390      IView view = (IView)((ToolStripMenuItem)sender).Tag;
391      PluginManager.ControlManager.ShowControl(view);
392    }
393    private void initialOperatorToolStripMenuItem_Click(object sender, EventArgs e) {
394      if (initialOperatorToolStripMenuItem.Checked) {
395        foreach (ListViewItem item in operatorsListView.Items)
396          item.Font = operatorsListView.Font;
397        operatorsListView.SelectedItems[0].Font = new Font(operatorsListView.Font, FontStyle.Bold);
398        OperatorGraph.InitialOperator = (IOperator)initialOperatorToolStripMenuItem.Tag;
399      } else {
400        operatorsListView.SelectedItems[0].Font = operatorsListView.Font;
401        OperatorGraph.InitialOperator = null;
402      }
403    }
404    private void graphContextMenuStrip_Opening(object sender, CancelEventArgs e) {
405      viewToolStripMenuItem1.Enabled = false;
406      breakpointToolStripMenuItem.Enabled = false;
407      breakpointToolStripMenuItem.Checked = false;
408      if (graphTreeView.SelectedNode != null) {
409        IOperator op = (IOperator)graphTreeView.SelectedNode.Tag;
410        IView view = (IView)MainFormManager.CreateDefaultView(op);
411        if (view != null) {
412          viewToolStripMenuItem1.Enabled = true;
413          viewToolStripMenuItem1.Tag = view;
414        }
415        breakpointToolStripMenuItem.Enabled = true;
416        breakpointToolStripMenuItem.Tag = op;
417        if (op.Breakpoint)
418          breakpointToolStripMenuItem.Checked = true;
419      }
420    }
421    private void breakpointToolStripMenuItem_Click(object sender, EventArgs e) {
422      IOperator op = (IOperator)breakpointToolStripMenuItem.Tag;
423      op.Breakpoint = breakpointToolStripMenuItem.Checked;
424    }
425    #endregion
426
427    #region OperatorGraph Events
428    private void OperatorGraph_OperatorAdded(object sender, EventArgs<IOperator> e) {
429      operatorsListView.Items.Add(CreateListViewItem(e.Value));
430    }
431    private void OperatorGraph_OperatorRemoved(object sender, EventArgs<IOperator> e) {
432      ListViewItem itemToDelete = null;
433      foreach (ListViewItem item in operatorsListView.Items) {
434        if (item.Tag == e.Value)
435          itemToDelete = item;
436      }
437      itemToDelete.Remove();
438    }
439    private void OperatorGraph_InitialOperatorChanged(object sender, EventArgs e) {
440      Refresh();
441    }
442    #endregion
443
444    #region Operator Events
445    private void Operator_NameChanged(object sender, EventArgs e) {
446      IOperator op = (IOperator)sender;
447      foreach (TreeNode node in operatorNodeTable[op])
448        node.Text = op.Name;
449    }
450    private void Operator_BreakpointChanged(object sender, EventArgs e) {
451      IOperator op = (IOperator)sender;
452      foreach (TreeNode node in operatorNodeTable[op]) {
453        if (op.Breakpoint)
454          node.ForeColor = Color.Red;
455        else
456          node.ForeColor = graphTreeView.ForeColor;
457      }
458    }
459    private void Operator_SubOperatorAdded(object sender, EventArgs<IOperator, int> e) {
460      IOperator op = (IOperator)sender;
461      if (operatorNodeTable.ContainsKey(op)) {
462        TreeNode[] nodes = new TreeNode[operatorNodeTable[op].Count];
463        operatorNodeTable[op].CopyTo(nodes, 0);
464        foreach (TreeNode node in nodes)
465          node.Nodes.Insert(e.Value2, CreateTreeNode(e.Value));
466      }
467    }
468    private void Operator_SubOperatorRemoved(object sender, EventArgs<IOperator, int> e) {
469      IOperator op = (IOperator)sender;
470      if (operatorNodeTable.ContainsKey(op)) {
471        TreeNode[] nodes = new TreeNode[operatorNodeTable[op].Count];
472        operatorNodeTable[op].CopyTo(nodes, 0);
473        foreach (TreeNode node in nodes) {
474          RemoveTreeNode(node.Nodes[e.Value2]);
475          node.Nodes.RemoveAt(e.Value2);
476        }
477      }
478    }
479    #endregion
480
481    #region Mouse Events
482    private void graphTreeView_MouseDown(object sender, MouseEventArgs e) {
483      if (e.Button != MouseButtons.Right) return;
484      TreeNode clickedNode = graphTreeView.GetNodeAt(e.X, e.Y);
485      if (clickedNode != null) {
486        graphTreeView.SelectedNode = clickedNode;
487        graphTreeView.Refresh();
488      }
489    }
490    #endregion
491
492  }
493}
Note: See TracBrowser for help on using the repository browser.