Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1324:

  • Added performance optimization in all other item collection views
  • Checked and refactored item event registration/deregistration
  • Enabled null items in item collection views
  • Moved non-default Dispose methods from designer files into user files
File size: 13.1 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      scopeNodeTable = new Dictionary<IScope, TreeNode>();
56      subScopesScopeTable = new Dictionary<ScopeList, IScope>();
57    }
58
59    /// <summary>
60    /// Clean up any resources being used.
61    /// </summary>
62    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
63    protected override void Dispose(bool disposing) {
64      if (disposing) {
65        if (scopesTreeView.Nodes.Count > 0) {
66          ClearTreeNode(scopesTreeView.Nodes[0]);
67        }
68        if (components != null) components.Dispose();
69      }
70      base.Dispose(disposing);
71    }
72
73    /// <summary>
74    /// Updates all controls with the latest data of the model.
75    /// </summary>
76    /// <remarks>Calls <see cref="ViewBase.UpdateControls"/> of base class <see cref="ViewBase"/>.</remarks>
77    protected override void OnContentChanged() {
78      base.OnContentChanged();
79      if (scopesTreeView.Nodes.Count > 0)
80        ClearTreeNode(scopesTreeView.Nodes[0]);
81      scopesTreeView.Nodes.Clear();
82      variableCollectionView.Content = null;
83      if (Content != null) {
84        scopesTreeView.Nodes.Add(CreateTreeNode(Content));
85      }
86    }
87
88    protected override void SetEnabledStateOfControls() {
89      base.SetEnabledStateOfControls();
90      scopesTreeView.Enabled = Content != null;
91      variableCollectionView.Enabled = scopesTreeView.SelectedNode != null;
92    }
93
94    #region TreeNode Management
95    private TreeNode CreateTreeNode(IScope scope) {
96      TreeNode node = new TreeNode();
97      node.Text = scope.Name;
98      node.Tag = scope;
99
100      scopeNodeTable.Add(scope, node);
101      scope.NameChanged += new EventHandler(Scope_NameChanged);
102      subScopesScopeTable.Add(scope.SubScopes, scope);
103      scope.SubScopes.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsAdded);
104      scope.SubScopes.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsRemoved);
105      scope.SubScopes.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsReplaced);
106      scope.SubScopes.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsMoved);
107      scope.SubScopes.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_CollectionReset);
108      if (scope.SubScopes.Count > 0)
109        node.Nodes.Add(new TreeNode());
110      return node;
111    }
112
113    private void ClearTreeNode(TreeNode node) {
114      if (scopesTreeView.SelectedNode == node) {
115        scopesTreeView.SelectedNode = null;
116        UpdateVariables();
117      }
118
119      foreach (TreeNode child in node.Nodes)
120        ClearTreeNode(child);
121
122      IScope scope = node.Tag as IScope;
123      if (scope != null) {
124        scope.NameChanged -= new EventHandler(Scope_NameChanged);
125        scopeNodeTable.Remove(scope);
126        scope.SubScopes.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsAdded);
127        scope.SubScopes.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsRemoved);
128        scope.SubScopes.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsReplaced);
129        scope.SubScopes.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsMoved);
130        scope.SubScopes.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_CollectionReset);
131        subScopesScopeTable.Remove(scope.SubScopes);
132      }
133    }
134    #endregion
135
136    #region TreeView Events
137    private void scopesTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
138      UpdateVariables();
139    }
140    private void scopesTreeView_MouseDown(object sender, MouseEventArgs e) {
141      TreeNode node = scopesTreeView.GetNodeAt(e.X, e.Y);
142      scopesTreeView.SelectedNode = node;
143      UpdateVariables();
144    }
145    private void scopesTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e) {
146      TreeNode node = e.Node;
147      IScope scope = (IScope)node.Tag;
148
149      node.Nodes.Clear();
150      for (int i = 0; i < scope.SubScopes.Count; i++)
151        node.Nodes.Add(CreateTreeNode(scope.SubScopes[i]));
152    }
153    private void scopesTreeView_AfterCollapse(object sender, System.Windows.Forms.TreeViewEventArgs e) {
154      TreeNode node = e.Node;
155      IScope scope = (IScope)node.Tag;
156
157      if (node.Nodes.Count > 0) {
158        for (int i = 0; i < node.Nodes.Count; i++)
159          ClearTreeNode(node.Nodes[i]);
160        node.Nodes.Clear();
161        node.Nodes.Add(new TreeNode());
162      }
163    }
164    private void scopesTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
165      if (!Locked) {
166        TreeNode node = (TreeNode)e.Item;
167        IScope scope = node.Tag as IScope;
168        if (scope != null) {
169          DataObject data = new DataObject();
170          data.SetData("Type", scope.GetType());
171          data.SetData("Value", scope);
172          DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
173        }
174      }
175    }
176    #endregion
177
178    #region Content Events
179    private void Scope_NameChanged(object sender, EventArgs e) {
180      if (InvokeRequired)
181        Invoke(new EventHandler(Scope_NameChanged), sender, e);
182      else {
183        IScope scope = (IScope)sender;
184        TreeNode node = null;
185        scopeNodeTable.TryGetValue(scope, out node);
186        if (node != null) node.Text = scope.Name;
187      }
188    }
189    private void SubScopes_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
190      if (InvokeRequired)
191        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsAdded), sender, e);
192      else {
193        IScope parentScope = null;
194        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
195        if (parentScope != null) {
196          TreeNode parentNode = null;
197          scopeNodeTable.TryGetValue(parentScope, out parentNode);
198          if (parentNode != null) {
199            scopesTreeView.BeginUpdate();
200            if (parentNode.IsExpanded) {
201              foreach (IndexedItem<IScope> item in e.Items) {
202                TreeNode node = CreateTreeNode(item.Value);
203                parentNode.Nodes.Insert(item.Index, node);
204              }
205            } else if (parentNode.Nodes.Count == 0) {
206              parentNode.Nodes.Add(new TreeNode());
207            }
208            scopesTreeView.EndUpdate();
209          }
210        }
211      }
212    }
213    private void SubScopes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
214      if (InvokeRequired)
215        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsRemoved), sender, e);
216      else {
217        IScope parentScope = null;
218        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
219        if (parentScope != null) {
220          TreeNode parentNode = null;
221          scopeNodeTable.TryGetValue(parentScope, out parentNode);
222          if (parentNode != null) {
223            scopesTreeView.BeginUpdate();
224            if (parentNode.IsExpanded) {
225              foreach (IndexedItem<IScope> item in e.Items) {
226                TreeNode node = scopeNodeTable[item.Value];
227                ClearTreeNode(node);
228                node.Remove();
229              }
230            } else if (parentScope.SubScopes.Count == 0) {
231              parentNode.Nodes.Clear();
232            }
233            scopesTreeView.EndUpdate();
234          }
235        }
236      }
237    }
238    private void SubScopes_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
239      if (InvokeRequired)
240        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsReplaced), sender, e);
241      else {
242        IScope parentScope = null;
243        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
244        if (parentScope != null) {
245          TreeNode parentNode = null;
246          scopeNodeTable.TryGetValue(parentScope, out parentNode);
247          if (parentNode != null) {
248            scopesTreeView.BeginUpdate();
249            if (parentNode.IsExpanded) {
250              foreach (IndexedItem<IScope> item in e.Items) {
251                TreeNode node = parentNode.Nodes[item.Index];
252                ClearTreeNode(node);
253                node.Remove();
254                node = CreateTreeNode(item.Value);
255                parentNode.Nodes.Insert(item.Index, node);
256              }
257              scopesTreeView.EndUpdate();
258            }
259          }
260        }
261      }
262    }
263    private void SubScopes_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
264      if (InvokeRequired)
265        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsMoved), sender, e);
266      else {
267        IScope parentScope = null;
268        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
269        if (parentScope != null) {
270          TreeNode parentNode = null;
271          scopeNodeTable.TryGetValue(parentScope, out parentNode);
272          if (parentNode != null) {
273            scopesTreeView.BeginUpdate();
274            if (parentNode.IsExpanded) {
275              parentNode.Nodes.Clear();
276              foreach (IndexedItem<IScope> item in e.Items)
277                parentNode.Nodes.Insert(item.Index, scopeNodeTable[item.Value]);
278            }
279            scopesTreeView.EndUpdate();
280          }
281        }
282      }
283    }
284    private void SubScopes_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
285      if (InvokeRequired)
286        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_CollectionReset), sender, e);
287      else {
288        IScope parentScope = null;
289        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
290        if (parentScope != null) {
291          TreeNode parentNode = null;
292          scopeNodeTable.TryGetValue(parentScope, out parentNode);
293          if (parentNode != null) {
294            scopesTreeView.BeginUpdate();
295            if (parentNode.IsExpanded) {
296              foreach (TreeNode node in parentNode.Nodes)
297                ClearTreeNode(node);
298              parentNode.Nodes.Clear();
299              foreach (IndexedItem<IScope> item in e.Items) {
300                TreeNode node = CreateTreeNode(item.Value);
301                parentNode.Nodes.Insert(item.Index, node);
302              }
303            } else {
304              parentNode.Nodes.Clear();
305              if (parentScope.SubScopes.Count > 0)
306                parentNode.Nodes.Add(new TreeNode());
307            }
308            scopesTreeView.EndUpdate();
309          }
310        }
311      }
312    }
313    #endregion
314
315    #region Helpers
316    private void UpdateVariables() {
317      if (scopesTreeView.SelectedNode == null) {
318        variableCollectionView.Content = null;
319        variableCollectionView.Enabled = false;
320      } else {
321        variableCollectionView.Enabled = true;
322        variableCollectionView.Content = ((IScope)scopesTreeView.SelectedNode.Tag).Variables;
323      }
324    }
325    #endregion
326  }
327}
Note: See TracBrowser for help on using the repository browser.