Free cookie consent management tool by TermsFeed Policy Generator

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

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

Continued work on Optimizer and on adapting all views to the new MainForm concept (#770)

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 : ItemViewBase {
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 = MainFormManager.CreateDefaultView(op);
187        if (view != null) MainFormManager.MainForm.ShowView(view);
188      }
189    }
190    #endregion
191
192    #region TreeView Events
193    private void graphTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e) {
194      TreeNode node = e.Node;
195      IOperator op = (IOperator)node.Tag;
196      for (int i = 0; i < node.Nodes.Count; i++) {
197        if (node.Nodes[i].Tag == null) {
198          node.Nodes[i].Remove();
199          node.Nodes.Insert(i, CreateTreeNode(op.SubOperators[i]));
200        }
201      }
202    }
203    private void graphTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
204      IOperator op = (IOperator)e.Node.Tag;
205      foreach (ListViewItem item in operatorsListView.Items)
206        item.Selected = item.Tag == op;
207    }
208    #endregion
209
210    #region Size Changed Events
211    private void operatorsListView_SizeChanged(object sender, EventArgs e) {
212      if (operatorsListView.Columns.Count > 0)
213        operatorsListView.Columns[0].Width = Math.Max(0, operatorsListView.Width - 25);
214    }
215    #endregion
216
217    #region Key Events
218    private void operatorsListView_KeyDown(object sender, KeyEventArgs e) {
219      if (e.KeyCode == Keys.Delete) {
220        if (operatorsListView.SelectedItems.Count > 0) {
221          foreach (ListViewItem item in operatorsListView.SelectedItems)
222            OperatorGraph.RemoveOperator((IOperator)item.Tag);
223        }
224      }
225      if (e.KeyCode == Keys.F2) {
226        if (operatorsListView.SelectedItems.Count == 1)
227          operatorsListView.SelectedItems[0].BeginEdit();
228      }
229    }
230    private void graphTreeView_KeyDown(object sender, KeyEventArgs e) {
231      if (e.KeyCode == Keys.Delete) {
232        TreeNode node = graphTreeView.SelectedNode;
233        if ((node != null) && (node.Parent != null)) {
234          IOperator parent = (IOperator)node.Parent.Tag;
235          parent.RemoveSubOperator(node.Index);
236        }
237      }
238    }
239    #endregion
240
241    #region Edit Events
242    private void operatorsListView_AfterLabelEdit(object sender, LabelEditEventArgs e) {
243      e.CancelEdit = false;
244
245      string name = e.Label;
246      if (name != null) {
247        IOperator op = (IOperator)operatorsListView.Items[e.Item].Tag;
248        op.Name = name;
249      }
250    }
251    #endregion
252
253    #region Button Events
254    private void addOperatorButton_Click(object sender, EventArgs e) {
255      if (chooseOperatorDialog == null) chooseOperatorDialog = new ChooseOperatorDialog();
256      if (chooseOperatorDialog.ShowDialog(this) == DialogResult.OK)
257        OperatorGraph.AddOperator(chooseOperatorDialog.Operator);
258    }
259    private void removeButton_Click(object sender, EventArgs e) {
260      if (operatorsListView.SelectedItems.Count > 0) {
261        foreach (ListViewItem item in operatorsListView.SelectedItems)
262          OperatorGraph.RemoveOperator((IOperator)item.Tag);
263      }
264    }
265    #endregion
266
267    #region Drag and Drop Events
268    private void operatorsListView_ItemDrag(object sender, ItemDragEventArgs e) {
269      ListViewItem item = (ListViewItem)e.Item;
270      IOperator op = (IOperator)item.Tag;
271      DataObject data = new DataObject();
272      data.SetData("IOperator", op);
273      data.SetData("DragSource", operatorsListView);
274      DoDragDrop(data, DragDropEffects.Copy);
275    }
276    private void operatorsListView_DragEnter(object sender, DragEventArgs e) {
277      e.Effect = DragDropEffects.None;
278      if (e.Data.GetDataPresent("IOperator"))
279        e.Effect = DragDropEffects.Copy;
280    }
281    private void operatorsListView_DragOver(object sender, DragEventArgs e) {
282      e.Effect = DragDropEffects.None;
283      if (e.Data.GetDataPresent("IOperator"))
284        e.Effect = DragDropEffects.Copy;
285    }
286    private void operatorsListView_DragDrop(object sender, DragEventArgs e) {
287      if (e.Effect != DragDropEffects.None) {
288        if (e.Data.GetDataPresent("IOperator")) {
289          IOperator op = (IOperator)e.Data.GetData("IOperator");
290          op = (IOperator)op.Clone();
291          OperatorGraph.AddOperator(op);
292        }
293      }
294    }
295    private void graphTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
296      TreeNode node = (TreeNode)e.Item;
297      if (node.Parent != null) {
298        IOperator op = (IOperator)node.Tag;
299        IOperator parent = (IOperator)node.Parent.Tag;
300        int index = node.Index;
301        DataObject data = new DataObject();
302        data.SetData("IOperator", op);
303        data.SetData("DragSource", graphTreeView);
304        data.SetData("ParentOperator", parent);
305        data.SetData("Index", index);
306        DoDragDrop(data, DragDropEffects.Move);
307      }
308    }
309    private void graphTreeView_DragEnter(object sender, DragEventArgs e) {
310      e.Effect = DragDropEffects.None;
311      if (e.Data.GetDataPresent("IOperator")) {
312        Point p = graphTreeView.PointToClient(new Point(e.X, e.Y));
313        TreeNode node = graphTreeView.GetNodeAt(p);
314        if (node != null) {
315          if ((e.Data.GetDataPresent("ParentOperator")) && (node.Parent != null)) {
316            if ((e.Data.GetDataPresent("DragSource")) && (e.Data.GetData("DragSource") == graphTreeView))
317              e.Effect = DragDropEffects.Move;
318          } else {
319            if ((e.Data.GetDataPresent("DragSource")) && (e.Data.GetData("DragSource") == operatorsListView))
320              e.Effect = DragDropEffects.Copy;
321          }
322        }
323      }
324    }
325    private void graphTreeView_DragOver(object sender, DragEventArgs e) {
326      e.Effect = DragDropEffects.None;
327      if (e.Data.GetDataPresent("IOperator")) {
328        Point p = graphTreeView.PointToClient(new Point(e.X, e.Y));
329        TreeNode node = graphTreeView.GetNodeAt(p);
330        if (node != null) {
331          if ((e.Data.GetDataPresent("ParentOperator")) && (node.Parent != null)) {
332            if ((e.Data.GetDataPresent("DragSource")) && (e.Data.GetData("DragSource") == graphTreeView))
333              e.Effect = DragDropEffects.Move;
334          } else {
335            if ((e.Data.GetDataPresent("DragSource")) && (e.Data.GetData("DragSource") == operatorsListView))
336              e.Effect = DragDropEffects.Copy;
337          }
338        }
339      }
340    }
341    private void graphTreeView_DragDrop(object sender, DragEventArgs e) {
342      if (e.Effect != DragDropEffects.None) {
343        if (e.Data.GetDataPresent("IOperator")) {
344          IOperator op = (IOperator)e.Data.GetData("IOperator");
345          Point p = graphTreeView.PointToClient(new Point(e.X, e.Y));
346          TreeNode node = graphTreeView.GetNodeAt(p);
347          if (e.Data.GetDataPresent("ParentOperator")) {
348            if (node.Parent != null) {
349              TreeNode parentNode = node.Parent;
350              IOperator oldParent = (IOperator)e.Data.GetData("ParentOperator");
351              int oldIndex = (int)e.Data.GetData("Index");
352              IOperator newParent = (IOperator)node.Parent.Tag;
353              int newIndex = node.Index;
354              oldParent.RemoveSubOperator(oldIndex);
355              newParent.AddSubOperator(op, newIndex);
356              graphTreeView.SelectedNode = parentNode.Nodes[newIndex];
357            }
358          } else {
359            if (node != null) {
360              IOperator parent = (IOperator)node.Tag;
361              parent.AddSubOperator(op);
362              graphTreeView.SelectedNode = node.Nodes[node.Nodes.Count - 1];
363            }
364          }
365        }
366      }
367    }
368    #endregion
369
370    #region Context Menu Events
371    private void operatorsContextMenuStrip_Opening(object sender, CancelEventArgs e) {
372      viewToolStripMenuItem.Enabled = false;
373      initialOperatorToolStripMenuItem.Enabled = false;
374      initialOperatorToolStripMenuItem.Checked = false;
375      if (operatorsListView.SelectedItems.Count == 1) {
376        IOperator op = (IOperator)operatorsListView.SelectedItems[0].Tag;
377        IView view = MainFormManager.CreateDefaultView(op);
378        if (view != null) {
379          viewToolStripMenuItem.Enabled = true;
380          viewToolStripMenuItem.Tag = view;
381        }
382        initialOperatorToolStripMenuItem.Enabled = true;
383        initialOperatorToolStripMenuItem.Tag = op;
384        if (op == OperatorGraph.InitialOperator)
385          initialOperatorToolStripMenuItem.Checked = true;
386      }
387    }
388    private void viewToolStripMenuItem_Click(object sender, EventArgs e) {
389      IView view = ((ToolStripMenuItem)sender).Tag as IView;
390      if (view != null) MainFormManager.MainForm.ShowView(view);
391    }
392    private void initialOperatorToolStripMenuItem_Click(object sender, EventArgs e) {
393      if (initialOperatorToolStripMenuItem.Checked) {
394        foreach (ListViewItem item in operatorsListView.Items)
395          item.Font = operatorsListView.Font;
396        operatorsListView.SelectedItems[0].Font = new Font(operatorsListView.Font, FontStyle.Bold);
397        OperatorGraph.InitialOperator = (IOperator)initialOperatorToolStripMenuItem.Tag;
398      } else {
399        operatorsListView.SelectedItems[0].Font = operatorsListView.Font;
400        OperatorGraph.InitialOperator = null;
401      }
402    }
403    private void graphContextMenuStrip_Opening(object sender, CancelEventArgs e) {
404      viewToolStripMenuItem1.Enabled = false;
405      breakpointToolStripMenuItem.Enabled = false;
406      breakpointToolStripMenuItem.Checked = false;
407      if (graphTreeView.SelectedNode != null) {
408        IOperator op = (IOperator)graphTreeView.SelectedNode.Tag;
409        IView view = MainFormManager.CreateDefaultView(op);
410        if (view != null) {
411          viewToolStripMenuItem1.Enabled = true;
412          viewToolStripMenuItem1.Tag = view;
413        }
414        breakpointToolStripMenuItem.Enabled = true;
415        breakpointToolStripMenuItem.Tag = op;
416        if (op.Breakpoint)
417          breakpointToolStripMenuItem.Checked = true;
418      }
419    }
420    private void breakpointToolStripMenuItem_Click(object sender, EventArgs e) {
421      IOperator op = (IOperator)breakpointToolStripMenuItem.Tag;
422      op.Breakpoint = breakpointToolStripMenuItem.Checked;
423    }
424    #endregion
425
426    #region OperatorGraph Events
427    private void OperatorGraph_OperatorAdded(object sender, EventArgs<IOperator> e) {
428      operatorsListView.Items.Add(CreateListViewItem(e.Value));
429    }
430    private void OperatorGraph_OperatorRemoved(object sender, EventArgs<IOperator> e) {
431      ListViewItem itemToDelete = null;
432      foreach (ListViewItem item in operatorsListView.Items) {
433        if (item.Tag == e.Value)
434          itemToDelete = item;
435      }
436      itemToDelete.Remove();
437    }
438    private void OperatorGraph_InitialOperatorChanged(object sender, EventArgs e) {
439      Refresh();
440    }
441    #endregion
442
443    #region Operator Events
444    private void Operator_NameChanged(object sender, EventArgs e) {
445      IOperator op = (IOperator)sender;
446      foreach (TreeNode node in operatorNodeTable[op])
447        node.Text = op.Name;
448    }
449    private void Operator_BreakpointChanged(object sender, EventArgs e) {
450      IOperator op = (IOperator)sender;
451      foreach (TreeNode node in operatorNodeTable[op]) {
452        if (op.Breakpoint)
453          node.ForeColor = Color.Red;
454        else
455          node.ForeColor = graphTreeView.ForeColor;
456      }
457    }
458    private void Operator_SubOperatorAdded(object sender, EventArgs<IOperator, int> e) {
459      IOperator op = (IOperator)sender;
460      if (operatorNodeTable.ContainsKey(op)) {
461        TreeNode[] nodes = new TreeNode[operatorNodeTable[op].Count];
462        operatorNodeTable[op].CopyTo(nodes, 0);
463        foreach (TreeNode node in nodes)
464          node.Nodes.Insert(e.Value2, CreateTreeNode(e.Value));
465      }
466    }
467    private void Operator_SubOperatorRemoved(object sender, EventArgs<IOperator, int> e) {
468      IOperator op = (IOperator)sender;
469      if (operatorNodeTable.ContainsKey(op)) {
470        TreeNode[] nodes = new TreeNode[operatorNodeTable[op].Count];
471        operatorNodeTable[op].CopyTo(nodes, 0);
472        foreach (TreeNode node in nodes) {
473          RemoveTreeNode(node.Nodes[e.Value2]);
474          node.Nodes.RemoveAt(e.Value2);
475        }
476      }
477    }
478    #endregion
479
480    #region Mouse Events
481    private void graphTreeView_MouseDown(object sender, MouseEventArgs e) {
482      if (e.Button != MouseButtons.Right) return;
483      TreeNode clickedNode = graphTreeView.GetNodeAt(e.X, e.Y);
484      if (clickedNode != null) {
485        graphTreeView.SelectedNode = clickedNode;
486        graphTreeView.Refresh();
487      }
488    }
489    #endregion
490
491  }
492}
Note: See TracBrowser for help on using the repository browser.