Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OaaS/HeuristicLab.Clients.Hive.Views/3.3/TreeView/ItemTreeView.cs @ 13847

Last change on this file since 13847 was 8120, checked in by ascheibe, 13 years ago

#1827 implemented review comments

File size: 15.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Windows.Forms;
27using HeuristicLab.Collections;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Core.Views;
31using HeuristicLab.MainForm;
32using HeuristicLab.MainForm.WindowsForms;
33using HeuristicLab.PluginInfrastructure;
34
35namespace HeuristicLab.Clients.Hive.Views {
36  [View("ItemTree View")]
37  [Content(typeof(ItemCollection<>), IsDefaultView = false)]
38  public abstract partial class ItemTreeView<T> : ItemView where T : class, IItemTree<T> {
39    public new ItemCollection<T> Content {
40      get { return (ItemCollection<T>)base.Content; }
41      set { base.Content = value; }
42    }
43
44    public T SelectedItem {
45      get {
46        if (treeView.SelectedNode != null)
47          return (T)treeView.SelectedNode.Tag;
48        return null;
49      }
50    }
51
52    public ItemTreeView() {
53      InitializeComponent();
54    }
55
56    protected override void DeregisterContentEvents() {
57      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded);
58      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved);
59      Content.CollectionReset -= new CollectionItemsChangedEventHandler<T>(Content_CollectionReset);
60      foreach (TreeNode node in treeView.Nodes) {
61        DeregisterContentEvents((T)node.Tag, node);
62      }
63      base.DeregisterContentEvents();
64    }
65
66    protected virtual void DeregisterContentEvents(T item, TreeNode node) {
67      item.ItemsAdded -= new CollectionItemsChangedEventHandler<IItemTree<T>>(item_ItemsAdded);
68      item.ItemsRemoved -= new CollectionItemsChangedEventHandler<IItemTree<T>>(item_ItemsRemoved);
69      item.CollectionReset -= new CollectionItemsChangedEventHandler<IItemTree<T>>(item_CollectionReset);
70      item.ToStringChanged -= new EventHandler(item_ToStringChanged);
71      item.ItemImageChanged -= new EventHandler(item_ItemImageChanged);
72      foreach (TreeNode childNode in node.Nodes) {
73        DeregisterContentEvents((T)childNode.Tag, childNode);
74      }
75    }
76
77    protected override void RegisterContentEvents() {
78      base.RegisterContentEvents();
79      Content.ItemsAdded += new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded);
80      Content.ItemsRemoved += new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved);
81      Content.CollectionReset += new CollectionItemsChangedEventHandler<T>(Content_CollectionReset);
82      foreach (TreeNode node in treeView.Nodes) {
83        RegisterContentEvents((T)node.Tag, node);
84      }
85    }
86
87    protected virtual void RegisterContentEvents(T item, TreeNode node) {
88      item.ItemsAdded += new CollectionItemsChangedEventHandler<IItemTree<T>>(item_ItemsAdded);
89      item.ItemsRemoved += new CollectionItemsChangedEventHandler<IItemTree<T>>(item_ItemsRemoved);
90      item.CollectionReset += new CollectionItemsChangedEventHandler<IItemTree<T>>(item_CollectionReset);
91      item.ToStringChanged += new EventHandler(item_ToStringChanged);
92      item.ItemImageChanged += new EventHandler(item_ItemImageChanged);
93      foreach (TreeNode childNode in node.Nodes) {
94        RegisterContentEvents((T)childNode.Tag, childNode);
95      }
96    }
97
98    #region Event Handlers (Content)
99    protected virtual void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<T> e) {
100      if (InvokeRequired) {
101        Invoke(new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded), sender, e);
102      } else {
103        foreach (T item in e.Items) {
104          var node = AddChildNodes(item, treeView.Nodes, true);
105          UpdateNodeItemImage(node);
106        }
107      }
108    }
109    protected virtual void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<T> e) {
110      if (InvokeRequired) {
111        Invoke(new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved), sender, e);
112      } else {
113        foreach (T item in e.Items) {
114          RemoveChildNodes(item, treeView.Nodes);
115        }
116        RebuildImageList();
117      }
118    }
119    protected virtual void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<T> e) {
120      if (InvokeRequired) {
121        Invoke(new CollectionItemsChangedEventHandler<T>(Content_CollectionReset), sender, e);
122      } else {
123        foreach (T item in e.OldItems) {
124          RemoveChildNodes(item, treeView.Nodes);
125        }
126        RebuildImageList();
127        foreach (T item in e.Items) {
128          AddChildNodes(item, treeView.Nodes, true);
129        }
130      }
131    }
132
133    protected virtual void item_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IItemTree<T>> e) {
134      if (InvokeRequired) {
135        Invoke(new CollectionItemsChangedEventHandler<IItemTree<T>>(item_ItemsAdded), sender, e);
136      } else {
137        TreeNode node = GetNodeByItem(sender as T);
138        if (node != null) {
139          foreach (T item in e.Items) {
140            AddChildNodes(item, node.Nodes, true);
141            node.ExpandAll();
142            UpdateNodeItemImage(node);
143          }
144        }
145      }
146    }
147
148    protected virtual void item_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IItemTree<T>> e) {
149      if (InvokeRequired) {
150        Invoke(new CollectionItemsChangedEventHandler<IItemTree<T>>(item_ItemsRemoved), sender, e);
151      } else {
152        TreeNode node = GetNodeByItem(sender as T);
153        if (node != null) {
154          foreach (T item in e.Items) {
155            RemoveChildNodes(item, node.Nodes);
156          }
157          RebuildImageList();
158        }
159      }
160    }
161
162    protected virtual void item_CollectionReset(object sender, CollectionItemsChangedEventArgs<IItemTree<T>> e) {
163      if (InvokeRequired) {
164        Invoke(new CollectionItemsChangedEventHandler<IItemTree<T>>(item_CollectionReset), sender, e);
165      } else {
166        TreeNode node = GetNodeByItem(sender as T);
167        if (node != null) {
168          foreach (T item in e.OldItems) {
169            RemoveChildNodes(item, node.Nodes);
170          }
171          RebuildImageList();
172          foreach (T item in e.Items) {
173            AddChildNodes(item, node.Nodes, true);
174          }
175        }
176      }
177    }
178
179    protected virtual void item_ToStringChanged(object sender, EventArgs e) {
180      if (InvokeRequired) {
181        Invoke(new EventHandler(item_ToStringChanged), sender, e);
182      } else {
183        var item = sender as T;
184        TreeNode node = GetNodeByItem(item);
185        if (node != null && node.Text != item.ToString())
186          node.Text = item.ToString();
187      }
188    }
189
190    protected virtual void item_ItemImageChanged(object sender, EventArgs e) {
191      if (InvokeRequired) {
192        Invoke(new EventHandler(item_ItemImageChanged), sender, e);
193      } else {
194        var item = sender as T;
195        TreeNode node = GetNodeByItem(item);
196        if (node != null)
197          UpdateNodeItemImage(node);
198      }
199    }
200
201    protected virtual void treeView_DoubleClick(object sender, EventArgs e) {
202      if (InvokeRequired) {
203        Invoke(new EventHandler(treeView_DoubleClick), sender, e);
204      } else {
205        if (treeView.SelectedNode != null) {
206          var item = treeView.SelectedNode.Tag as T;
207          if (item != null) {
208            IContentView view = MainFormManager.MainForm.ShowContent(item);
209            if (view != null) {
210              view.ReadOnly = ReadOnly;
211              view.Locked = Locked;
212            }
213          }
214        }
215      }
216    }
217
218    protected virtual void treeView_MouseDown(object sender, MouseEventArgs e) {
219      if (e.Button == System.Windows.Forms.MouseButtons.Left) {
220        // enables deselection of treeNodes
221        if (treeView.SelectedNode == null) {
222          return;
223        }
224        detailsViewHost.Content = null;
225        treeView.SelectedNode = null;
226        SetEnabledStateOfControls();
227      }
228    }
229    private void treeView_MouseClick(object sender, MouseEventArgs e) {
230
231    }
232    private void treeView_Click(object sender, EventArgs e) {
233
234    }
235    #endregion
236
237    protected override void OnContentChanged() {
238      base.OnContentChanged();
239      if (Content == null) {
240        ClearNodes();
241        detailsViewHost.Content = null;
242      } else {
243        ClearNodes();
244        foreach (T itemTree in Content) {
245          AddChildNodes(itemTree, treeView.Nodes, false);
246        }
247        foreach (TreeNode node in treeView.Nodes) {
248          UpdateNodeItemImage(node);
249        }
250        detailsViewHost.Content = null;
251      }
252    }
253
254    protected virtual void ClearNodes() {
255      treeView.Nodes.Clear();
256    }
257
258    protected virtual TreeNode AddChildNodes(T item, TreeNodeCollection nodes, bool registerEvents) {
259      TreeNode node = CreateTreeViewNode(item);
260      nodes.Add(node);
261      RebuildImageList(node);
262      RegisterContentEvents(item, node);
263      var childItems = item.GetChildItems();
264      foreach (T childItem in childItems) {
265        AddChildNodes(childItem, node.Nodes, registerEvents);
266      }
267      node.ExpandAll();
268      return node;
269    }
270
271    protected virtual void RemoveChildNodes(T item, TreeNodeCollection treeNodeCollection) {
272      int idx = -1;
273      for (int i = 0; i < treeNodeCollection.Count; i++) {
274        if (treeNodeCollection[i].Tag == item) {
275          idx = i; break;
276        }
277      }
278      if (idx > -1) {
279        DeregisterContentEvents(item, treeNodeCollection[idx]);
280        treeNodeCollection.RemoveAt(idx);
281      }
282    }
283
284    protected virtual TreeNode GetNodeByItem(T item) {
285      TreeNode found = null;
286      foreach (TreeNode node in treeView.Nodes) {
287        found = GetNodeByItem(node, item);
288        if (found != null)
289          return found;
290      }
291      return null;
292    }
293
294    protected virtual TreeNode GetNodeByItem(TreeNode node, T item) {
295      if (node.Tag == item)
296        return node;
297      TreeNode found = null;
298      foreach (TreeNode childNode in node.Nodes) {
299        found = GetNodeByItem(childNode, item);
300        if (found != null)
301          return found;
302      }
303      return null;
304    }
305
306    protected virtual TreeNode CreateTreeViewNode(T item) {
307      var node = new TreeNode(item.ToString());
308      node.Tag = item;
309      return node;
310    }
311
312    protected virtual void UpdateNodeItemImage(TreeNode node) {
313      if (node == null) throw new ArgumentNullException();
314      var item = node.Tag as T;
315      int i = node.ImageIndex;
316      this.imageList.Images[i] = item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage;
317      node.ImageIndex = -1;
318      node.ImageIndex = i;
319      node.SelectedImageIndex = node.ImageIndex;
320      foreach (TreeNode childNode in node.Nodes) {
321        UpdateNodeItemImage(childNode);
322      }
323    }
324
325    protected virtual T GetParentItem(T selectedItem) {
326      var node = GetNodeByItem(selectedItem);
327      if (node == null || node.Parent == null)
328        return null;
329      else
330        return (T)node.Parent.Tag;
331    }
332
333    protected override void SetEnabledStateOfControls() {
334      base.SetEnabledStateOfControls();
335      addButton.Enabled = !this.ReadOnly;
336      removeButton.Enabled = !this.ReadOnly && treeView.SelectedNode != null;
337    }
338
339    #region Event Handlers (child controls)
340    // Put event handlers of child controls here.
341    protected virtual void treeView_AfterSelect(object sender, TreeViewEventArgs e) {
342      detailsViewHost.Content = (IContent)treeView.SelectedNode.Tag;
343      SetEnabledStateOfControls();
344    }
345
346    protected virtual void contextMenuStrip_Opening(object sender, CancelEventArgs e) {
347      if (treeView.SelectedNode == null) {
348        e.Cancel = true;
349      } else {
350        T selectedItem = treeView.SelectedNode.Tag as T;
351        T parentItem = GetParentItem(selectedItem);
352        var actions = GetTreeNodeItemActions(selectedItem);
353        contextMenuStrip.Items.Clear();
354        foreach (var action in actions) {
355          contextMenuStrip.Items.Add(new DelegateMenuItem<T>(action.Name, action.Image, new Action<T, T>(action.Execute), selectedItem, parentItem));
356        }
357        e.Cancel = contextMenuStrip.Items.Count == 0;
358      }
359    }
360
361    protected virtual void addButton_Click(object sender, EventArgs e) {
362      AddItem();
363    }
364
365    protected virtual void removeButton_Click(object sender, EventArgs e) {
366      if (treeView.SelectedNode != null) {
367        RemoveItem(treeView.SelectedNode.Tag as T);
368        detailsViewHost.Content = null;
369      }
370    }
371
372    protected abstract void AddItem();
373
374    protected abstract void RemoveItem(T item);
375
376    protected virtual void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
377      if (showDetailsCheckBox.Checked) {
378        splitContainer.Panel2Collapsed = false;
379        detailsGroupBox.Enabled = treeView.SelectedNode != null;
380        detailsViewHost.Content = treeView.SelectedNode != null ? (T)treeView.SelectedNode.Tag : null;
381      } else {
382        splitContainer.Panel2Collapsed = true;
383        detailsViewHost.Content = null;
384      }
385    }
386    #endregion
387
388    protected virtual void RebuildImageList() {
389      treeView.ImageList.Images.Clear();
390      foreach (TreeNode node in treeView.Nodes) {
391        RebuildImageList(node);
392      }
393    }
394
395    protected virtual void RebuildImageList(TreeNode node) {
396      var item = node.Tag as T;
397      treeView.ImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage);
398      node.ImageIndex = treeView.ImageList.Images.Count - 1;
399      node.SelectedImageIndex = node.ImageIndex;
400      foreach (TreeNode childNode in node.Nodes) {
401        RebuildImageList(childNode);
402      }
403    }
404
405    protected virtual ICollection<IItemTreeNodeAction<T>> GetTreeNodeItemActions(T selectedItem) {
406      return selectedItem.Actions;
407    }
408
409    protected virtual X CreateItem<X>() where X : class {
410      var typeSelectorDialog = new TypeSelectorDialog();
411      typeSelectorDialog.Caption = "Select Item";
412      typeSelectorDialog.TypeSelector.Caption = "Available Items";
413      typeSelectorDialog.TypeSelector.Configure(typeof(X), false, true);
414
415      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
416        try {
417          return (X)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
418        }
419        catch (Exception ex) {
420          ErrorHandling.ShowErrorDialog(this, ex);
421        }
422      }
423      return null;
424    }
425  }
426
427  public class DelegateMenuItem<T> : ToolStripMenuItem {
428    private Action<T, T> actionDelegate;
429    private T node;
430    private T parentNode;
431
432    public DelegateMenuItem(string name, Image image, Action<T, T> actionDelegate, T node, T parentNode) {
433      this.Name = name;
434      this.Text = name;
435      this.actionDelegate = actionDelegate;
436      this.node = node;
437      this.parentNode = parentNode;
438      this.Image = image;
439    }
440
441    protected override void OnClick(EventArgs e) {
442      base.OnClick(e);
443      actionDelegate.Invoke(node, parentNode);
444    }
445  }
446}
Note: See TracBrowser for help on using the repository browser.