Free cookie consent management tool by TermsFeed Policy Generator

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

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

Fixed exceptions (#893)

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