Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core.Views/3.3/ScopeView.cs @ 3702

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

Worked on UI support for choosing generic type parameters (#42)

File size: 12.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Windows.Forms;
25using HeuristicLab.Collections;
26using HeuristicLab.MainForm;
27
28namespace HeuristicLab.Core.Views {
29  /// <summary>
30  /// The visual represenation of <see cref="Scope"/>.
31  /// </summary>
32  [View("Scope View")]
33  [Content(typeof(Scope), true)]
34  [Content(typeof(IScope), false)]
35  public sealed partial class ScopeView : ItemView {
36    private Dictionary<IScope, TreeNode> scopeNodeTable;
37    private Dictionary<ScopeList, IScope> subScopesScopeTable;
38
39    /// <summary>
40    /// Gets or sets the scope to represent visually.
41    /// </summary>
42    /// <remarks>Uses property <see cref="ViewBase.Item"/> of base class <see cref="ViewBase"/>.
43    /// No own data storage present.</remarks>
44    public new IScope Content {
45      get { return (IScope)base.Content; }
46      set { base.Content = value; }
47    }
48
49    /// <summary>
50    /// Initializes a new instance of <see cref="ScopeView"/> with caption "Scope" and
51    /// property <see cref="AutomaticUpdating"/> set to <c>false</c>.
52    /// </summary>
53    public ScopeView() {
54      InitializeComponent();
55      Caption = "Scope";
56      scopeNodeTable = new Dictionary<IScope, TreeNode>();
57      subScopesScopeTable = new Dictionary<ScopeList, IScope>();
58    }
59
60    /// <summary>
61    /// Updates all controls with the latest data of the model.
62    /// </summary>
63    /// <remarks>Calls <see cref="ViewBase.UpdateControls"/> of base class <see cref="ViewBase"/>.</remarks>
64    protected override void OnContentChanged() {
65      base.OnContentChanged();
66      if (scopesTreeView.Nodes.Count > 0)
67        ClearTreeNode(scopesTreeView.Nodes[0]);
68      scopesTreeView.Nodes.Clear();
69      variableCollectionView.Content = null;
70      Caption = "Scope";
71      if (Content != null) {
72        Caption = Content.Name + " (" + Content.ItemName + ")";
73        scopesTreeView.Nodes.Add(CreateTreeNode(Content));
74      }
75      SetEnabledStateOfControls();
76    }
77
78    protected override void OnReadOnlyChanged() {
79      base.OnReadOnlyChanged();
80      SetEnabledStateOfControls();
81    }
82
83    private void SetEnabledStateOfControls() {
84      scopesTreeView.Enabled = Content != null;
85      variableCollectionView.Enabled = scopesTreeView.SelectedNode != null;
86    }
87
88    #region TreeNode Management
89    private TreeNode CreateTreeNode(IScope scope) {
90      TreeNode node = new TreeNode();
91      node.Text = scope.Name;
92      node.Tag = scope;
93
94      scopeNodeTable.Add(scope, node);
95      scope.NameChanged += new EventHandler(Scope_NameChanged);
96      subScopesScopeTable.Add(scope.SubScopes, scope);
97      scope.SubScopes.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsAdded);
98      scope.SubScopes.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsRemoved);
99      scope.SubScopes.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsReplaced);
100      scope.SubScopes.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsMoved);
101      scope.SubScopes.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_CollectionReset);
102      if (scope.SubScopes.Count > 0)
103        node.Nodes.Add(new TreeNode());
104      return node;
105    }
106
107    private void ClearTreeNode(TreeNode node) {
108      if (scopesTreeView.SelectedNode == node) {
109        scopesTreeView.SelectedNode = null;
110        UpdateVariables();
111      }
112
113      foreach (TreeNode child in node.Nodes)
114        ClearTreeNode(child);
115
116      IScope scope = node.Tag as IScope;
117      if (scope != null) {
118        scope.NameChanged -= new EventHandler(Scope_NameChanged);
119        scopeNodeTable.Remove(scope);
120        scope.SubScopes.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsAdded);
121        scope.SubScopes.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsRemoved);
122        scope.SubScopes.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsReplaced);
123        scope.SubScopes.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsMoved);
124        scope.SubScopes.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_CollectionReset);
125        subScopesScopeTable.Remove(scope.SubScopes);
126      }
127    }
128    #endregion
129
130    #region TreeView Events
131    private void scopesTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
132      UpdateVariables();
133    }
134    private void scopesTreeView_MouseDown(object sender, MouseEventArgs e) {
135      TreeNode node = scopesTreeView.GetNodeAt(e.X, e.Y);
136      scopesTreeView.SelectedNode = node;
137      UpdateVariables();
138    }
139    private void scopesTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e) {
140      TreeNode node = e.Node;
141      IScope scope = (IScope)node.Tag;
142
143      node.Nodes.Clear();
144      for (int i = 0; i < scope.SubScopes.Count; i++)
145        node.Nodes.Add(CreateTreeNode(scope.SubScopes[i]));
146    }
147    private void scopesTreeView_AfterCollapse(object sender, System.Windows.Forms.TreeViewEventArgs e) {
148      TreeNode node = e.Node;
149      IScope scope = (IScope)node.Tag;
150
151      if (node.Nodes.Count > 0) {
152        for (int i = 0; i < node.Nodes.Count; i++)
153          ClearTreeNode(node.Nodes[i]);
154        node.Nodes.Clear();
155        node.Nodes.Add(new TreeNode());
156      }
157    }
158    private void scopesTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
159      if (!Locked) {
160        TreeNode node = (TreeNode)e.Item;
161        IScope scope = node.Tag as IScope;
162        if (scope != null) {
163          DataObject data = new DataObject();
164          data.SetData("Type", scope.GetType());
165          data.SetData("Value", scope);
166          DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
167        }
168      }
169    }
170    #endregion
171
172    #region Content Events
173    private void Scope_NameChanged(object sender, EventArgs e) {
174      if (InvokeRequired)
175        Invoke(new EventHandler(Scope_NameChanged), sender, e);
176      else {
177        IScope scope = (IScope)sender;
178        TreeNode node = null;
179        scopeNodeTable.TryGetValue(scope, out node);
180        if (node != null) node.Text = scope.Name;
181      }
182    }
183    private void SubScopes_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
184      if (InvokeRequired)
185        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsAdded), sender, e);
186      else {
187        IScope parentScope = null;
188        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
189        if (parentScope != null) {
190          TreeNode parentNode = null;
191          scopeNodeTable.TryGetValue(parentScope, out parentNode);
192          if (parentNode != null) {
193            scopesTreeView.BeginUpdate();
194            if (parentNode.IsExpanded) {
195              foreach (IndexedItem<IScope> item in e.Items) {
196                TreeNode node = CreateTreeNode(item.Value);
197                parentNode.Nodes.Insert(item.Index, node);
198              }
199            } else if (parentNode.Nodes.Count == 0) {
200              parentNode.Nodes.Add(new TreeNode());
201            }
202            scopesTreeView.EndUpdate();
203          }
204        }
205      }
206    }
207    private void SubScopes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
208      if (InvokeRequired)
209        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsRemoved), sender, e);
210      else {
211        IScope parentScope = null;
212        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
213        if (parentScope != null) {
214          TreeNode parentNode = null;
215          scopeNodeTable.TryGetValue(parentScope, out parentNode);
216          if (parentNode != null) {
217            scopesTreeView.BeginUpdate();
218            if (parentNode.IsExpanded) {
219              foreach (IndexedItem<IScope> item in e.Items) {
220                TreeNode node = scopeNodeTable[item.Value];
221                ClearTreeNode(node);
222                node.Remove();
223              }
224            } else if (parentScope.SubScopes.Count == 0) {
225              parentNode.Nodes.Clear();
226            }
227            scopesTreeView.EndUpdate();
228          }
229        }
230      }
231    }
232    private void SubScopes_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
233      if (InvokeRequired)
234        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsReplaced), sender, e);
235      else {
236        IScope parentScope = null;
237        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
238        if (parentScope != null) {
239          TreeNode parentNode = null;
240          scopeNodeTable.TryGetValue(parentScope, out parentNode);
241          if (parentNode != null) {
242            scopesTreeView.BeginUpdate();
243            if (parentNode.IsExpanded) {
244              foreach (IndexedItem<IScope> item in e.Items) {
245                TreeNode node = parentNode.Nodes[item.Index];
246                ClearTreeNode(node);
247                node.Remove();
248                node = CreateTreeNode(item.Value);
249                parentNode.Nodes.Insert(item.Index, node);
250              }
251              scopesTreeView.EndUpdate();
252            }
253          }
254        }
255      }
256    }
257    private void SubScopes_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
258      if (InvokeRequired)
259        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsMoved), sender, e);
260      else {
261        IScope parentScope = null;
262        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
263        if (parentScope != null) {
264          TreeNode parentNode = null;
265          scopeNodeTable.TryGetValue(parentScope, out parentNode);
266          if (parentNode != null) {
267            scopesTreeView.BeginUpdate();
268            if (parentNode.IsExpanded) {
269              parentNode.Nodes.Clear();
270              foreach (IndexedItem<IScope> item in e.Items)
271                parentNode.Nodes.Insert(item.Index, scopeNodeTable[item.Value]);
272            }
273            scopesTreeView.EndUpdate();
274          }
275        }
276      }
277    }
278    private void SubScopes_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
279      if (InvokeRequired)
280        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_CollectionReset), sender, e);
281      else {
282        IScope parentScope = null;
283        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
284        if (parentScope != null) {
285          TreeNode parentNode = null;
286          scopeNodeTable.TryGetValue(parentScope, out parentNode);
287          if (parentNode != null) {
288            scopesTreeView.BeginUpdate();
289            if (parentNode.IsExpanded) {
290              foreach (TreeNode node in parentNode.Nodes)
291                ClearTreeNode(node);
292              parentNode.Nodes.Clear();
293              foreach (IndexedItem<IScope> item in e.Items) {
294                TreeNode node = CreateTreeNode(item.Value);
295                parentNode.Nodes.Insert(item.Index, node);
296              }
297            } else {
298              parentNode.Nodes.Clear();
299              if (parentScope.SubScopes.Count > 0)
300                parentNode.Nodes.Add(new TreeNode());
301            }
302            scopesTreeView.EndUpdate();
303          }
304        }
305      }
306    }
307    #endregion
308
309    #region Helpers
310    private void UpdateVariables() {
311      if (scopesTreeView.SelectedNode == null) {
312        variableCollectionView.Content = null;
313        variableCollectionView.Enabled = false;
314      } else {
315        variableCollectionView.Enabled = true;
316        variableCollectionView.Content = ((IScope)scopesTreeView.SelectedNode.Tag).Variables;
317      }
318    }
319    #endregion
320  }
321}
Note: See TracBrowser for help on using the repository browser.