Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Core.Views/3.3/ScopeView.cs @ 17204

Last change on this file since 17204 was 17181, checked in by swagner, 5 years ago

#2875: Merged r17180 from trunk to stable

File size: 13.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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(HeuristicLab.Common.Constants.DragDropDataFormat, scope);
171          DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
172        }
173      }
174    }
175    #endregion
176
177    #region Content Events
178    private void Scope_NameChanged(object sender, EventArgs e) {
179      if (InvokeRequired)
180        Invoke(new EventHandler(Scope_NameChanged), sender, e);
181      else {
182        IScope scope = (IScope)sender;
183        TreeNode node = null;
184        scopeNodeTable.TryGetValue(scope, out node);
185        if (node != null) node.Text = scope.Name;
186      }
187    }
188    private void SubScopes_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
189      if (InvokeRequired)
190        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsAdded), sender, e);
191      else {
192        IScope parentScope = null;
193        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
194        if (parentScope != null) {
195          TreeNode parentNode = null;
196          scopeNodeTable.TryGetValue(parentScope, out parentNode);
197          if (parentNode != null) {
198            scopesTreeView.BeginUpdate();
199            if (parentNode.IsExpanded) {
200              foreach (IndexedItem<IScope> item in e.Items) {
201                TreeNode node = CreateTreeNode(item.Value);
202                parentNode.Nodes.Insert(item.Index, node);
203              }
204            } else if (parentNode.Nodes.Count == 0) {
205              parentNode.Nodes.Add(new TreeNode());
206            }
207            scopesTreeView.EndUpdate();
208          }
209        }
210      }
211    }
212    private void SubScopes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
213      if (InvokeRequired)
214        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsRemoved), sender, e);
215      else {
216        IScope parentScope = null;
217        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
218        if (parentScope != null) {
219          TreeNode parentNode = null;
220          scopeNodeTable.TryGetValue(parentScope, out parentNode);
221          if (parentNode != null) {
222            scopesTreeView.BeginUpdate();
223            if (parentNode.IsExpanded) {
224              foreach (IndexedItem<IScope> item in e.Items) {
225                TreeNode node = scopeNodeTable[item.Value];
226                ClearTreeNode(node);
227                node.Remove();
228              }
229            } else if (parentScope.SubScopes.Count == 0) {
230              parentNode.Nodes.Clear();
231            }
232            scopesTreeView.EndUpdate();
233          }
234        }
235      }
236    }
237    private void SubScopes_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
238      if (InvokeRequired)
239        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsReplaced), sender, e);
240      else {
241        IScope parentScope = null;
242        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
243        if (parentScope != null) {
244          TreeNode parentNode = null;
245          scopeNodeTable.TryGetValue(parentScope, out parentNode);
246          if (parentNode != null) {
247            scopesTreeView.BeginUpdate();
248            if (parentNode.IsExpanded) {
249              foreach (IndexedItem<IScope> item in e.Items) {
250                TreeNode node = parentNode.Nodes[item.Index];
251                ClearTreeNode(node);
252                node.Remove();
253                node = CreateTreeNode(item.Value);
254                parentNode.Nodes.Insert(item.Index, node);
255              }
256              scopesTreeView.EndUpdate();
257            }
258          }
259        }
260      }
261    }
262    private void SubScopes_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
263      if (InvokeRequired)
264        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsMoved), sender, e);
265      else {
266        IScope parentScope = null;
267        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
268        if (parentScope != null) {
269          TreeNode parentNode = null;
270          scopeNodeTable.TryGetValue(parentScope, out parentNode);
271          if (parentNode != null) {
272            scopesTreeView.BeginUpdate();
273            if (parentNode.IsExpanded) {
274              parentNode.Nodes.Clear();
275              foreach (IndexedItem<IScope> item in e.Items)
276                parentNode.Nodes.Insert(item.Index, scopeNodeTable[item.Value]);
277            }
278            scopesTreeView.EndUpdate();
279          }
280        }
281      }
282    }
283    private void SubScopes_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
284      if (InvokeRequired)
285        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_CollectionReset), sender, e);
286      else {
287        IScope parentScope = null;
288        subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope);
289        if (parentScope != null) {
290          TreeNode parentNode = null;
291          scopeNodeTable.TryGetValue(parentScope, out parentNode);
292          if (parentNode != null) {
293            scopesTreeView.BeginUpdate();
294            if (parentNode.IsExpanded) {
295              foreach (TreeNode node in parentNode.Nodes)
296                ClearTreeNode(node);
297              parentNode.Nodes.Clear();
298              foreach (IndexedItem<IScope> item in e.Items) {
299                TreeNode node = CreateTreeNode(item.Value);
300                parentNode.Nodes.Insert(item.Index, node);
301              }
302            } else {
303              parentNode.Nodes.Clear();
304              if (parentScope.SubScopes.Count > 0)
305                parentNode.Nodes.Add(new TreeNode());
306            }
307            scopesTreeView.EndUpdate();
308          }
309        }
310      }
311    }
312    #endregion
313
314    #region Helpers
315    private void UpdateVariables() {
316      if (scopesTreeView.SelectedNode == null) {
317        variableCollectionView.Content = null;
318        variableCollectionView.Enabled = false;
319      } else {
320        variableCollectionView.Enabled = true;
321        variableCollectionView.Content = ((IScope)scopesTreeView.SelectedNode.Tag).Variables;
322      }
323    }
324    #endregion
325  }
326}
Note: See TracBrowser for help on using the repository browser.