source: trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs @ 6471

Last change on this file since 6471 was 6471, checked in by mkommend, 8 years ago

#1555: Implemented experiment tree view.

File size: 29.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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;
24using System.Collections.Generic;
25using System.Drawing;
26using System.Linq;
27using System.Windows.Forms;
28using HeuristicLab.Collections;
29using HeuristicLab.Common;
30using HeuristicLab.Core.Views;
31using HeuristicLab.PluginInfrastructure;
32
33namespace HeuristicLab.Optimization.Views {
34  public sealed partial class ExperimentTreeView : ItemView {
35    private TypeSelectorDialog typeSelectorDialog;
36    private Dictionary<IOptimizer, List<TreeNode>> optimizerTreeViewMapping;
37
38    public ExperimentTreeView() {
39      InitializeComponent();
40      optimizerTreeViewMapping = new Dictionary<IOptimizer, List<TreeNode>>();
41    }
42
43    protected override void Dispose(bool disposing) {
44      if (disposing) {
45        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
46        if (components != null) components.Dispose();
47      }
48      base.Dispose(disposing);
49    }
50
51    public new Experiment Content {
52      get { return (Experiment)base.Content; }
53      set { base.Content = value; }
54    }
55
56    #region events registration
57    protected override void RegisterContentEvents() {
58      base.RegisterContentEvents();
59      Content.ExecutionStateChanged += new EventHandler(Content_ExecutionStateChanged);
60      Content.Optimizers.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
61      Content.Optimizers.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsMoved);
62      Content.Optimizers.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
63      Content.Optimizers.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
64      Content.Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
65    }
66
67    protected override void DeregisterContentEvents() {
68      Content.ExecutionStateChanged -= new EventHandler(Content_ExecutionStateChanged);
69      Content.Optimizers.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
70      Content.Optimizers.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsMoved);
71      Content.Optimizers.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
72      Content.Optimizers.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
73      Content.Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
74      foreach (var optimizer in optimizerTreeViewMapping.Keys)
75        DeregisterOptimizerEvents(optimizer);
76      base.DeregisterContentEvents();
77    }
78
79    private void RegisterOptimizerEvents(IOptimizer optimizer) {
80      optimizer.ToStringChanged += new EventHandler(optimizer_ToStringChanged);
81      optimizer.ExecutionStateChanged += new EventHandler(optimizer_ExecutionStateChanged);
82
83      var batchRun = optimizer as BatchRun;
84      var experiment = optimizer as Experiment;
85      if (batchRun != null) {
86        batchRun.OptimizerChanged += new EventHandler(batchRun_OptimizerChanged);
87      }
88      if (experiment != null) {
89        experiment.Optimizers.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
90        experiment.Optimizers.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsMoved);
91        experiment.Optimizers.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
92        experiment.Optimizers.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
93        experiment.Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
94      }
95    }
96
97    private void DeregisterOptimizerEvents(IOptimizer optimizer) {
98      optimizer.ToStringChanged -= new EventHandler(optimizer_ToStringChanged);
99      optimizer.ExecutionStateChanged -= new EventHandler(optimizer_ExecutionStateChanged);
100
101      var batchRun = optimizer as BatchRun;
102      var experiment = optimizer as Experiment;
103      if (batchRun != null) {
104        batchRun.OptimizerChanged -= new EventHandler(batchRun_OptimizerChanged);
105      }
106      if (experiment != null) {
107        experiment.Optimizers.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
108        experiment.Optimizers.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsMoved);
109        experiment.Optimizers.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
110        experiment.Optimizers.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
111        experiment.Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
112      }
113    }
114    #endregion
115
116    protected override void OnContentChanged() {
117      base.OnContentChanged();
118      if (Content == null) {
119        optimizerTreeView.Nodes.Clear();
120      } else {
121        UpdateOptimizerTreeView();
122        optimizerTreeView.ExpandAll();
123      }
124    }
125
126    #region content events
127    private void Content_ExecutionStateChanged(object sender, EventArgs e) {
128      if (InvokeRequired) {
129        Invoke((Action<object, EventArgs>)Content_ExecutionStateChanged, sender, e);
130        return;
131      }
132      RebuildImageList();
133      SetEnabledStateOfControls();
134    }
135
136    private void optimizer_ExecutionStateChanged(object sender, EventArgs e) {
137      if (InvokeRequired) {
138        Invoke((Action<object, EventArgs>)optimizer_ExecutionStateChanged, sender, e);
139        return;
140      }
141      RebuildImageList();
142    }
143
144    private void batchRun_OptimizerChanged(object sender, EventArgs e) {
145      if (InvokeRequired) {
146        Invoke((Action<object, EventArgs>)batchRun_OptimizerChanged, sender, e);
147        return;
148      }
149      var batchRun = (BatchRun)sender;
150      foreach (TreeNode node in optimizerTreeViewMapping[batchRun]) {
151        foreach (TreeNode childNode in node.Nodes) {
152          DisposeTreeNode(childNode);
153          childNode.Remove();
154        }
155
156        if (batchRun.Optimizer != null) {
157          TreeNode childNode = CreateTreeNode(batchRun.Optimizer);
158          UpdateChildTreeNodes(childNode.Nodes, batchRun.Optimizer);
159          node.Nodes.Add(childNode);
160          node.Expand();
161        }
162      }
163      RebuildImageList();
164    }
165
166    private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
167      if (InvokeRequired) {
168        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_ItemsAdded, sender, e);
169        return;
170      }
171
172      var optimizerList = (OptimizerList)sender;
173      IEnumerable<TreeNodeCollection> parentNodes;
174      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { optimizerTreeView.Nodes };
175      else {
176        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
177        parentNodes = optimizerTreeViewMapping[experiment].Select(node => node.Nodes);
178      }
179
180      foreach (TreeNodeCollection parentNode in parentNodes) {
181        foreach (var childOptimizer in e.Items) {
182          TreeNode childNode = CreateTreeNode(childOptimizer.Value);
183          UpdateChildTreeNodes(childNode.Nodes, childOptimizer.Value);
184          parentNode.Insert(childOptimizer.Index, childNode);
185          childNode.ExpandAll();
186          if (childNode.Parent != null) childNode.Parent.ExpandAll();
187        }
188      }
189      RebuildImageList();
190    }
191    private void Optimizers_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
192      if (InvokeRequired) {
193        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_ItemsMoved, sender, e);
194        return;
195      }
196
197      var optimizerList = (OptimizerList)sender;
198      IEnumerable<TreeNodeCollection> parentNodes;
199      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { optimizerTreeView.Nodes };
200      else {
201        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
202        parentNodes = optimizerTreeViewMapping[experiment].Select(node => node.Nodes);
203      }
204
205      foreach (TreeNodeCollection parentNode in parentNodes) {
206        //get all effected child nodes
207        foreach (TreeNode childNode in parentNode.OfType<TreeNode>()
208          .Where(n => e.OldItems.Select(x => x.Value).Contains((IOptimizer)n.Tag)).ToList()) {
209          DisposeTreeNode(childNode);
210          childNode.Remove();
211        }
212
213        foreach (var childOptimizer in e.Items) {
214          TreeNode childNode = CreateTreeNode(childOptimizer.Value);
215          UpdateChildTreeNodes(childNode.Nodes, childOptimizer.Value);
216          childNode.ExpandAll();
217          parentNode.Insert(childOptimizer.Index, childNode);
218        }
219      }
220      RebuildImageList();
221    }
222    private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
223      if (InvokeRequired) {
224        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_ItemsRemoved, sender, e);
225        return;
226      }
227
228      var optimizerList = (OptimizerList)sender;
229      IEnumerable<TreeNodeCollection> parentNodes;
230      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { optimizerTreeView.Nodes };
231      else {
232        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
233        parentNodes = optimizerTreeViewMapping[experiment].Select(node => node.Nodes);
234      }
235
236      foreach (TreeNodeCollection parentNode in parentNodes) {
237        foreach (var childOptimizer in e.Items) {
238          TreeNode childNode = parentNode[childOptimizer.Index];
239          DisposeTreeNode(childNode);
240          childNode.Remove();
241        }
242      }
243      RebuildImageList();
244    }
245    private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
246      if (InvokeRequired) {
247        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_ItemsReplaced, sender, e);
248        return;
249      }
250
251      var optimizerList = (OptimizerList)sender;
252      IEnumerable<TreeNodeCollection> parentNodes;
253      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { optimizerTreeView.Nodes };
254      else {
255        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
256        parentNodes = optimizerTreeViewMapping[experiment].Select(node => node.Nodes);
257      }
258
259      foreach (TreeNodeCollection parentNode in parentNodes) {
260        foreach (var childOptimizer in e.OldItems) {
261          TreeNode childNode = parentNode.Cast<TreeNode>().Where(n => n.Tag == childOptimizer.Value && n.Index == childOptimizer.Index).First();
262          DisposeTreeNode(childNode);
263          childNode.Remove();
264        }
265        foreach (var childOptimizer in e.Items) {
266          TreeNode childNode = CreateTreeNode(childOptimizer.Value);
267          UpdateChildTreeNodes(childNode.Nodes, childOptimizer.Value);
268          parentNode.Insert(childOptimizer.Index, childNode);
269        }
270      }
271      RebuildImageList();
272    }
273    private void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
274      if (InvokeRequired) {
275        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_CollectionReset, sender, e);
276        return;
277      }
278
279      var optimizerList = (OptimizerList)sender;
280      IEnumerable<TreeNodeCollection> parentNodes;
281      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { optimizerTreeView.Nodes };
282      else {
283        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
284        parentNodes = optimizerTreeViewMapping[experiment].Select(node => node.Nodes);
285      }
286
287      foreach (TreeNodeCollection parentNode in parentNodes) {
288        foreach (var childOptimizer in e.OldItems) {
289          TreeNode childNode = parentNode.Cast<TreeNode>().Where(n => n.Tag == childOptimizer.Value && n.Index == childOptimizer.Index).First();
290          DisposeTreeNode(childNode);
291          childNode.Remove();
292        }
293        foreach (var childOptimizer in e.Items) {
294          TreeNode childNode = CreateTreeNode(childOptimizer.Value);
295          UpdateChildTreeNodes(childNode.Nodes, childOptimizer.Value);
296          parentNode.Insert(childOptimizer.Index, childNode);
297        }
298      }
299      RebuildImageList();
300    }
301
302    private void optimizer_ToStringChanged(object sender, EventArgs e) {
303      if (InvokeRequired) {
304        Invoke((Action<object, EventArgs>)optimizer_ToStringChanged, sender, e);
305        return;
306      }
307      var optimizer = (IOptimizer)sender;
308      foreach (TreeNode node in optimizerTreeViewMapping[optimizer])
309        node.Text = optimizer.ToString();
310    }
311    #endregion
312
313    protected override void SetEnabledStateOfControls() {
314      base.SetEnabledStateOfControls();
315      BatchRun batchRun = null;
316      BatchRun parentBatchRun = null;
317      Experiment experiment = null;
318      if (optimizerTreeView.SelectedNode != null) {
319        batchRun = optimizerTreeView.SelectedNode.Tag as BatchRun;
320        experiment = optimizerTreeView.SelectedNode.Tag as Experiment;
321        if (optimizerTreeView.SelectedNode.Parent != null)
322          parentBatchRun = optimizerTreeView.SelectedNode.Parent.Tag as BatchRun;
323      }
324
325      optimizerTreeView.Enabled = Content != null;
326      detailsViewHost.Enabled = Content != null && optimizerTreeView.SelectedNode != null;
327
328      addButton.Enabled = Content != null && !Locked && !ReadOnly &&
329        (optimizerTreeView.SelectedNode == null || experiment != null || (batchRun != null && batchRun.Optimizer == null));
330      moveUpButton.Enabled = Content != null && !Locked && !ReadOnly &&
331        optimizerTreeView.SelectedNode != null && optimizerTreeView.SelectedNode.PrevNode != null && parentBatchRun == null;
332      moveDownButton.Enabled = Content != null && !Locked && !ReadOnly &&
333        optimizerTreeView.SelectedNode != null && optimizerTreeView.SelectedNode.NextNode != null && parentBatchRun == null;
334      removeButton.Enabled = Content != null && !Locked && !ReadOnly &&
335        optimizerTreeView.SelectedNode != null;
336    }
337
338    private void UpdateOptimizerTreeView() {
339      optimizerTreeView.Nodes.Clear();
340      UpdateChildTreeNodes(optimizerTreeView.Nodes, Content);
341      RebuildImageList();
342    }
343
344
345    private void UpdateChildTreeNodes(TreeNodeCollection collection, IOptimizer optimizer) {
346      var batchRun = optimizer as BatchRun;
347      var experiment = optimizer as Experiment;
348      if (experiment != null) UpdateChildTreeNodes(collection, experiment.Optimizers);
349      else if (batchRun != null && batchRun.Optimizer != null) UpdateChildTreeNodes(collection, new List<IOptimizer>() { batchRun.Optimizer });
350    }
351    private void UpdateChildTreeNodes(TreeNodeCollection collection, IEnumerable<IOptimizer> optimizers) {
352      foreach (IOptimizer optimizer in optimizers) {
353        var node = CreateTreeNode(optimizer);
354        collection.Add(node);
355        UpdateChildTreeNodes(node.Nodes, optimizer);
356      }
357    }
358
359
360    #region drag & drop
361    private void optimizerTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
362      if (Locked) return;
363
364      TreeNode selectedNode = (TreeNode)e.Item;
365      var optimizer = (IOptimizer)selectedNode.Tag;
366      DataObject data = new DataObject();
367      data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, optimizer);
368      validDragOperation = true;
369
370      if (ReadOnly) {
371        DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
372      } else {
373        DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
374        if ((result & DragDropEffects.Move) == DragDropEffects.Move) {
375          if (selectedNode.Parent == null) Content.Optimizers.Remove(optimizer);
376          else {
377            var parentOptimizer = (IOptimizer)selectedNode.Parent.Tag;
378            var parentBatchRun = parentOptimizer as BatchRun;
379            var parentExperiment = parentOptimizer as Experiment;
380            if (parentBatchRun != null) parentBatchRun.Optimizer = null;
381            else if (parentExperiment != null) parentExperiment.Optimizers.Remove(optimizer);
382            else throw new NotSupportedException("Handling for specific type not implemented" + parentOptimizer.GetType());
383          }
384          if (optimizerTreeView.SelectedNode != null)
385            detailsViewHost.Content = (IOptimizer)optimizerTreeView.SelectedNode.Tag;
386          SetEnabledStateOfControls();
387          RebuildImageList();
388        }
389      }
390    }
391
392    private bool validDragOperation = false;
393    private void optimizerTreeView_DragEnter(object sender, DragEventArgs e) {
394      validDragOperation = false;
395      if (!ReadOnly) {
396        if ((e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IOptimizer)) validDragOperation = true;
397        else if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable) {
398          validDragOperation = true;
399          IEnumerable items = (IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
400          foreach (object item in items)
401            validDragOperation = validDragOperation && (item is IOptimizer);
402        }
403      }
404    }
405    private void optimizerTreeView_DragOver(object sender, DragEventArgs e) {
406      e.Effect = DragDropEffects.None;
407      if (validDragOperation) {
408        Point coordinates = optimizerTreeView.PointToClient(new Point(e.X, e.Y));
409        TreeNode node = optimizerTreeView.GetNodeAt(coordinates);
410        Experiment experiment = null;
411        BatchRun batchRun = null;
412
413        if (node == null) experiment = Content;
414        else {
415          experiment = node.Tag as Experiment;
416          batchRun = node.Tag as BatchRun;
417        }
418
419        if (batchRun == null && experiment == null) return;
420        if (batchRun != null) {
421          var optimizer = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IOptimizer;
422          if (optimizer == null) return;
423          if (batchRun.Optimizer != null) return;
424          if (optimizer.GetObjectGraphObjects().OfType<IOptimizer>().Contains(batchRun)) return;
425        }
426
427        //do not allow recursive nesting of contents
428        if (experiment != null) {
429          var optimizer = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IOptimizer;
430          IEnumerable<IOptimizer> optimizers = null;
431          var enumerable = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IEnumerable;
432          if (enumerable != null) optimizers = enumerable.Cast<IOptimizer>();
433
434          if (optimizer != null && optimizer.GetObjectGraphObjects().OfType<IOptimizer>().Contains(experiment)) return;
435          if (optimizers != null && optimizers.GetObjectGraphObjects().OfType<IOptimizer>().Contains(experiment)) return;
436        }
437
438        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
439        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
440        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
441        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
442        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
443      }
444    }
445    private void optimizerTreeView_DragDrop(object sender, DragEventArgs e) {
446      Point coordinates = optimizerTreeView.PointToClient(new Point(e.X, e.Y));
447      TreeNode node = optimizerTreeView.GetNodeAt(coordinates);
448      Experiment experiment = null;
449      BatchRun batchRun = null;
450
451      if (node == null) experiment = Content;
452      else {
453        experiment = node.Tag as Experiment;
454        batchRun = node.Tag as BatchRun;
455      }
456
457      if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IOptimizer) {
458        IOptimizer optimizer = (IOptimizer)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
459        if (e.Effect.HasFlag(DragDropEffects.Copy)) optimizer = (IOptimizer)optimizer.Clone();
460        if (batchRun != null) batchRun.Optimizer = optimizer;
461        else if (experiment != null) experiment.Optimizers.Add(optimizer);
462        else throw new NotSupportedException("Handling for specific type not implemented" + node.Tag.GetType());
463      } else if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable) {
464        IEnumerable<IOptimizer> optimizers = ((IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat)).Cast<IOptimizer>();
465        if (e.Effect.HasFlag(DragDropEffects.Copy)) {
466          Cloner cloner = new Cloner();
467          optimizers = optimizers.Select(o => (IOptimizer)o.Clone(cloner));
468        }
469        if (experiment != null) experiment.Optimizers.AddRange(optimizers);
470        else throw new NotSupportedException("Handling for specific type not implemented" + node.Tag.GetType());
471      }
472    }
473    #endregion
474
475    #region control events
476    private void optimizerTreeview_MouseClick(object sender, MouseEventArgs e) {
477      Point coordinates = new Point(e.X, e.Y);
478      TreeNode selectedNode = optimizerTreeView.GetNodeAt(coordinates);
479      if (selectedNode != null) {
480        optimizerTreeView.SelectedNode = selectedNode;
481        detailsViewHost.Content = (IOptimizer)selectedNode.Tag;
482        SetEnabledStateOfControls();
483      }
484    }
485    private void optimizerTreeView_MouseDown(object sender, MouseEventArgs e) {
486      // enables deselection of treeNodes
487      if (optimizerTreeView.SelectedNode == null) return;
488      Point coordinates = new Point(e.X, e.Y);
489      if (e.Button == System.Windows.Forms.MouseButtons.Left && optimizerTreeView.GetNodeAt(coordinates) == null) {
490        optimizerTreeView.SelectedNode = null;
491        detailsViewHost.Content = null;
492        SetEnabledStateOfControls();
493      }
494    }
495
496    private void addButton_Click(object sender, System.EventArgs e) {
497      if (typeSelectorDialog == null) {
498        typeSelectorDialog = new TypeSelectorDialog();
499        typeSelectorDialog.Caption = "Select Optimizer";
500        typeSelectorDialog.TypeSelector.Caption = "Available Optimizers";
501        typeSelectorDialog.TypeSelector.Configure(typeof(IOptimizer), false, true);
502      }
503
504      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
505        try {
506          IOptimizer optimizer = (IOptimizer)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
507          if (optimizerTreeView.SelectedNode == null) Content.Optimizers.Add(optimizer);
508          else {
509            var batchRun = optimizerTreeView.SelectedNode.Tag as BatchRun;
510            var experiment = optimizerTreeView.SelectedNode.Tag as Experiment;
511            if (batchRun != null) batchRun.Optimizer = optimizer;
512            else if (experiment != null) experiment.Optimizers.Add(optimizer);
513            else throw new NotSupportedException("Handling for specific type not implemented" + optimizerTreeView.SelectedNode.Tag.GetType());
514          }
515        }
516        catch (Exception ex) {
517          ErrorHandling.ShowErrorDialog(this, ex);
518        }
519      }
520    }
521
522    private void moveUpButton_Click(object sender, EventArgs e) {
523      var optimizer = optimizerTreeView.SelectedNode.Tag as IOptimizer;
524      Experiment experiment = null;
525      if (optimizerTreeView.SelectedNode.Parent == null) experiment = Content;
526      else experiment = (Experiment)optimizerTreeView.SelectedNode.Parent.Tag;
527
528      detailsViewHost.SuspendRepaint();
529      int index = optimizerTreeView.SelectedNode.Index;
530      experiment.Optimizers.Reverse(index - 1, 2);
531      optimizerTreeView.SelectedNode = optimizerTreeViewMapping[optimizer].First();
532      detailsViewHost.Content = (IOptimizer)optimizerTreeView.SelectedNode.Tag;
533      SetEnabledStateOfControls();
534      detailsViewHost.ResumeRepaint(true);
535    }
536    private void moveDownButton_Click(object sender, EventArgs e) {
537      var optimizer = optimizerTreeView.SelectedNode.Tag as IOptimizer;
538      Experiment experiment = null;
539      if (optimizerTreeView.SelectedNode.Parent == null) experiment = Content;
540      else experiment = (Experiment)optimizerTreeView.SelectedNode.Parent.Tag;
541
542      int index = optimizerTreeView.SelectedNode.Index;
543      experiment.Optimizers.Reverse(index, 2);
544      optimizerTreeView.SelectedNode = optimizerTreeViewMapping[optimizer].First();
545      detailsViewHost.Content = (IOptimizer)optimizerTreeView.SelectedNode.Tag;
546      SetEnabledStateOfControls();
547    }
548
549    private void removeButton_Click(object sender, System.EventArgs e) {
550      var treeNode = optimizerTreeView.SelectedNode;
551      var optimizer = (IOptimizer)treeNode.Tag;
552
553      if (treeNode.Parent == null)
554        Content.Optimizers.Remove(optimizer);
555      else {
556        var batchRun = treeNode.Parent.Tag as BatchRun;
557        var experiment = treeNode.Parent.Tag as Experiment;
558        if (batchRun != null) batchRun.Optimizer = null;
559        else if (experiment != null) experiment.Optimizers.Remove(optimizer);
560        else throw new NotSupportedException("Handling for specific type not implemented" + optimizerTreeView.SelectedNode.Tag.GetType());
561      }
562      SetEnabledStateOfControls();
563      detailsViewHost.Content = (IOptimizer)optimizerTreeView.SelectedNode.Tag;
564    }
565
566    private void showDetailsCheckBox_CheckedChanged(object sender, System.EventArgs e) {
567      if (showDetailsCheckBox.Checked) {
568        splitContainer.Panel2Collapsed = false;
569        detailsGroupBox.Enabled = optimizerTreeView.SelectedNode != null;
570        detailsViewHost.Content = optimizerTreeView.SelectedNode != null ? (IOptimizer)optimizerTreeView.SelectedNode.Tag : null;
571      } else {
572        splitContainer.Panel2Collapsed = true;
573        detailsViewHost.Content = null;
574      }
575    }
576    #endregion
577
578    #region helpers
579    private TreeNode CreateTreeNode(IOptimizer optimizer) {
580      TreeNode node = new TreeNode(optimizer.ToString());
581      node.Tag = optimizer;
582      List<TreeNode> nodes;
583      if (!optimizerTreeViewMapping.TryGetValue(optimizer, out nodes)) {
584        nodes = new List<TreeNode>();
585        optimizerTreeViewMapping.Add(optimizer, nodes);
586        RegisterOptimizerEvents(optimizer);
587      }
588      nodes.Add(node);
589      return node;
590    }
591
592    private void DisposeTreeNode(TreeNode node) {
593      var optimizer = (IOptimizer)node.Tag;
594      List<TreeNode> nodes;
595      if (!optimizerTreeViewMapping.TryGetValue(optimizer, out nodes))
596        throw new ArgumentException();
597      nodes.Remove(node);
598      if (nodes.Count == 0) {
599        optimizerTreeViewMapping.Remove(optimizer);
600        DeregisterOptimizerEvents(optimizer);
601      }
602    }
603
604    private IEnumerable<TreeNode> IterateTreeNodes(TreeNode node = null) {
605      TreeNodeCollection nodes;
606      if (node == null)
607        nodes = optimizerTreeView.Nodes;
608      else {
609        nodes = node.Nodes;
610        yield return node;
611      }
612
613      foreach (var childNode in nodes.OfType<TreeNode>())
614        foreach (var n in IterateTreeNodes(childNode))
615          yield return n;
616    }
617
618    private void RebuildImageList() {
619      if (InvokeRequired) {
620        Invoke((Action)RebuildImageList);
621        return;
622      }
623
624      optimizerTreeView.ImageList.Images.Clear();
625      foreach (TreeNode treeNode in IterateTreeNodes()) {
626        var optimizer = (IOptimizer)treeNode.Tag;
627        optimizerTreeView.ImageList.Images.Add(optimizer == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : optimizer.ItemImage);
628        treeNode.ImageIndex = optimizerTreeView.ImageList.Images.Count - 1;
629        treeNode.SelectedImageIndex = treeNode.ImageIndex;
630      }
631    }
632    #endregion
633  }
634}
Note: See TracBrowser for help on using the repository browser.