Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 6488 was 6488, checked in by mkommend, 13 years ago

#1555: Fixed docking issues with expanded nodes.

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