Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs @ 8146

Last change on this file since 8146 was 8145, checked in by ascheibe, 12 years ago

#1762 implemented review comments:

  • removed self disposing. The progress view now reacts if a progress is set and Finish() is now called on the progress object and not the view.
  • Moved Cancel event from ProgressView to Progress
  • throw ArgumentNullException if the parent view is null
File size: 12.9 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.Drawing;
25using System.Linq;
26using System.Text;
27using System.Windows.Forms;
28using HeuristicLab.Clients.Hive.JobManager.ExtensionMethods;
29using HeuristicLab.Core;
30using HeuristicLab.Core.Views;
31using HeuristicLab.MainForm;
32using HeuristicLab.MainForm.WindowsForms;
33
34namespace HeuristicLab.Clients.Hive.JobManager.Views {
35  [View("Hive Resource Selector View")]
36  [Content(typeof(IItemList<Resource>), true)]
37  public partial class HiveResourceSelector : ItemView, IDisposable {
38    private const int slaveImageIndex = 0;
39    private const int slaveGroupImageIndex = 1;
40    private string currentSearchString;
41    private ISet<TreeNode> mainTreeNodes;
42    private ISet<TreeNode> filteredTreeNodes;
43    private ISet<TreeNode> nodeStore;
44    private IProgress currentProgress;
45
46    private ISet<Resource> selectedResources;
47    public ISet<Resource> SelectedResources {
48      get { return selectedResources; }
49      set { selectedResources = value; }
50    }
51
52    private ProgressView progressView;
53    public ProgressView ProgressView {
54      get { return progressView; }
55      set { progressView = value; }
56    }
57
58    public new IItemList<Resource> Content {
59      get { return (IItemList<Resource>)base.Content; }
60      set { base.Content = value; }
61    }
62
63    public HiveResourceSelector() {
64      InitializeComponent();
65      mainTreeNodes = new HashSet<TreeNode>();
66      filteredTreeNodes = new HashSet<TreeNode>();
67      nodeStore = new HashSet<TreeNode>();
68      selectedResources = new HashSet<Resource>();
69      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.MonitorLarge);
70      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NetworkCenterLarge);
71      progressView = new ProgressView(this);
72    }
73
74    public void StartProgressView() {
75      if (InvokeRequired) {
76        Invoke(new Action(StartProgressView));
77      } else {
78        currentProgress = new Progress();
79        currentProgress.Status = "Downloading resources. Please be patient.";
80        progressView.Progress = currentProgress;
81      }
82    }
83
84    public void FinishProgressView() {
85      if (InvokeRequired) {
86        Invoke(new Action(FinishProgressView));
87      } else {
88        currentProgress.Finish();
89        SetEnabledStateOfControls();
90      }
91    }
92
93    protected override void OnContentChanged() {
94      base.OnContentChanged();
95
96      if (Content != null) {
97        selectedResources = new HashSet<Resource>(Content.Where(x => selectedResources.Any(y => x.Id == y.Id)));
98        UpdateMainTree();
99        ExtractStatistics();
100      } else {
101        mainTreeNodes.Clear();
102        UpdateFilteredTree();
103      }
104    }
105
106    #region MainTree Methods
107    private void UpdateMainTree() {
108      mainTreeNodes.Clear();
109
110      foreach (Resource g in Content) {
111        if (g.GetType() == typeof(SlaveGroup)) {
112          //root node
113          if (g.ParentResourceId == null) {
114            TreeNode tn = new TreeNode();
115            tn.ImageIndex = slaveGroupImageIndex;
116            tn.SelectedImageIndex = tn.ImageIndex;
117
118            tn.Tag = g;
119            tn.Text = g.Name;
120            tn.Checked = selectedResources.Any(x => x.Id == g.Id);
121
122            BuildMainTree(tn);
123            mainTreeNodes.Add(tn);
124          }
125        }
126      }
127      UpdateFilteredTree();
128    }
129
130    private void BuildMainTree(TreeNode tn) {
131      foreach (Resource r in Content.Where(s => s.ParentResourceId != null && s.ParentResourceId == ((Resource)tn.Tag).Id)) {
132        TreeNode stn = new TreeNode(r.Name);
133        if (r is Slave) stn.ImageIndex = slaveImageIndex;
134        else if (r is SlaveGroup) stn.ImageIndex = slaveGroupImageIndex;
135        stn.SelectedImageIndex = stn.ImageIndex;
136        stn.Tag = r;
137        stn.Checked = selectedResources.Any(x => x.Id == r.Id);
138        tn.Nodes.Add(stn);
139        mainTreeNodes.Add(stn);
140
141        BuildMainTree(stn);
142      }
143    }
144    #endregion
145
146    #region FilteredTree Methods
147    private void UpdateFilteredTree() {
148      filteredTreeNodes.Clear();
149      foreach (TreeNode n in mainTreeNodes) {
150        n.BackColor = SystemColors.Window;
151        if (currentSearchString == null || ((Resource)n.Tag).Name.ToLower().Contains(currentSearchString)) {
152          n.BackColor = string.IsNullOrEmpty(currentSearchString) ? SystemColors.Window : Color.LightBlue;
153          filteredTreeNodes.Add(n);
154          TraverseParentNodes(n);
155        }
156      }
157      UpdateResourceTree();
158    }
159
160    private void TraverseParentNodes(TreeNode node) {
161      if (node != null) {
162        for (TreeNode parent = node.Parent; parent != null; parent = parent.Parent)
163          filteredTreeNodes.Add(parent);
164      }
165    }
166    #endregion
167
168    #region ResourceTree Methods
169    private void UpdateResourceTree() {
170      resourcesTreeView.Nodes.Clear();
171      nodeStore.Clear();
172
173      foreach (TreeNode node in filteredTreeNodes) {
174        var clone = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
175        if (clone == null) {
176          clone = (TreeNode)node.Clone();
177          nodeStore.Add(clone);
178          clone.Nodes.Clear();
179        }
180        foreach (TreeNode child in node.Nodes)
181          if (filteredTreeNodes.Any(x => ((Resource)x.Tag).Id == ((Resource)child.Tag).Id)) {
182            var childClone = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)child.Tag).Id);
183            if (childClone == null) {
184              childClone = (TreeNode)child.Clone();
185              nodeStore.Add(childClone);
186              childClone.Nodes.Clear();
187            }
188            clone.Nodes.Add(childClone);
189          }
190      }
191      resourcesTreeView.Nodes.AddRange(nodeStore.Where(x => ((Resource)x.Tag).ParentResourceId == null).ToArray());
192      if (string.IsNullOrEmpty(currentSearchString)) ExpandSlaveGroupNodes();
193      else resourcesTreeView.ExpandAll();
194    }
195    #endregion
196
197    #region Events
198    private void resourcesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
199      if (e.Action != TreeViewAction.Unknown) {
200        if (e.Node.Checked) {
201          IncludeChildNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
202          IncludeParentNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
203        } else {
204          ExcludeChildNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
205          ExcludeParentNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
206        }
207        ExtractStatistics();
208      }
209    }
210
211    private void resourcesTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
212      if (e.Action != TreeViewAction.Unknown) {
213        ExtractStatistics(e.Node);
214      }
215    }
216
217    private void searchTextBox_TextChanged(object sender, System.EventArgs e) {
218      currentSearchString = searchTextBox.Text.ToLower();
219      UpdateFilteredTree();
220    }
221    #endregion
222
223    #region Helpers
224    private void IncludeChildNodes(TreeNode node) {
225      if (node != null) {
226        node.Checked = true;
227        selectedResources.Add((Resource)node.Tag);
228        AdjustNodeCheckedState(node);
229        foreach (TreeNode n in node.Nodes) IncludeChildNodes(n);
230      }
231    }
232
233    private void IncludeParentNodes(TreeNode node) {
234      if (node != null && node.Parent != null) {
235        TreeNode parent = node.Parent;
236        if (parent.Nodes.OfType<TreeNode>().All(x => x.Checked)) {
237          parent.Checked = true;
238          selectedResources.Add((Resource)parent.Tag);
239          AdjustNodeCheckedState(parent);
240          IncludeParentNodes(parent);
241        }
242      }
243    }
244
245    private void ExcludeChildNodes(TreeNode node) {
246      if (node != null) {
247        node.Checked = false;
248        selectedResources.Remove((Resource)node.Tag);
249        AdjustNodeCheckedState(node);
250        foreach (TreeNode n in node.Nodes) ExcludeChildNodes(n);
251      }
252    }
253
254    private void ExcludeParentNodes(TreeNode node) {
255      if (node != null) {
256        node.Checked = false;
257        selectedResources.Remove((Resource)node.Tag);
258        AdjustNodeCheckedState(node);
259        ExcludeParentNodes(node.Parent);
260      }
261    }
262
263    private void AdjustNodeCheckedState(TreeNode node) {
264      var filterdNode = filteredTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
265      var storedNode = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
266      if (filterdNode != null) filterdNode.Checked = node.Checked;
267      if (storedNode != null) storedNode.Checked = node.Checked;
268    }
269
270    private void ExpandSlaveGroupNodes() {
271      foreach (TreeNode n in nodeStore.Where(x => x.Tag is SlaveGroup)) {
272        TreeNode[] children = new TreeNode[n.Nodes.Count];
273        n.Nodes.CopyTo(children, 0);
274        if (children.Any(x => x.Tag is SlaveGroup)) n.Expand();
275      }
276    }
277
278    private void ExtractStatistics(TreeNode treeNode = null) {
279      StringBuilder sb = new StringBuilder();
280      Resource resource = treeNode == null ? null : treeNode.Tag as Resource;
281      ISet<Resource> resources = treeNode == null ? selectedResources : new HashSet<Resource>(treeNode.DescendantNodes().Select(x => x.Tag as Resource)); ;
282      IEnumerable<SlaveGroup> slaveGroups = resources.OfType<SlaveGroup>();
283      IEnumerable<Slave> slaves = resources.OfType<Slave>();
284      int cpuSpeed = 0, cores = 0, freeCores = 0, memory = 0, freeMemory = 0;
285      string contextString = treeNode == null ? "Selected" : "Included";
286
287      if (resources.Any() || resource != null) {
288        foreach (Slave s in slaves) {
289          cpuSpeed += s.CpuSpeed.GetValueOrDefault();
290          cores += s.Cores.GetValueOrDefault();
291          freeCores += s.FreeCores.GetValueOrDefault();
292          memory += s.Memory.GetValueOrDefault();
293          freeMemory += s.FreeMemory.GetValueOrDefault();
294        }
295        if (resource != null) {
296          if (resource is SlaveGroup) sb.Append("Slave group: ");
297          else if (resource is Slave) {
298            sb.Append("Slave: ");
299            if (!resources.Any()) {
300              Slave s = resource as Slave;
301              cpuSpeed = s.CpuSpeed.GetValueOrDefault();
302              cores = s.Cores.GetValueOrDefault();
303              freeCores = s.FreeCores.GetValueOrDefault();
304              memory = s.Memory.GetValueOrDefault();
305              freeMemory = s.FreeMemory.GetValueOrDefault();
306            }
307          }
308          sb.AppendLine(string.Format("{0}", resource.Name));
309        }
310        if (resource == null || resource is SlaveGroup) {
311          if (resources.Any()) {
312            sb.AppendFormat("{0} slave groups ({1}): ", contextString, slaveGroups.Count());
313            foreach (SlaveGroup sg in slaveGroups) sb.AppendFormat("{0}; ", sg.Name);
314            sb.AppendLine();
315            sb.AppendFormat("{0} slaves ({1}): ", contextString, slaves.Count());
316            foreach (Slave s in slaves) sb.AppendFormat("{0}; ", s.Name);
317            sb.AppendLine();
318          } else {
319            sb.Append("The selection does not inlcude any further resources.");
320          }
321        }
322        sb.AppendLine();
323        sb.AppendLine(string.Format("CPU speed: {0} MHz", cpuSpeed));
324        if (resources.Any()) sb.AppendLine(string.Format("Avg. CPU speed: {0:0.00} MHz", (double)cpuSpeed / resources.Count()));
325        sb.AppendLine(string.Format("Cores: {0}", cores));
326        sb.AppendLine(string.Format("Free cores: {0}", freeCores));
327        if (resources.Any()) sb.AppendLine(string.Format("Avg. free cores: {0:0.00}", (double)freeCores / resources.Count()));
328        sb.AppendLine(string.Format("Memory: {0} MB", memory));
329        sb.AppendFormat("Free memory: {0} MB", freeMemory);
330        if (resources.Any()) sb.Append(string.Format("{0}Avg. free memory: {1:0.00} MB", Environment.NewLine, (double)freeMemory / resources.Count()));
331      } else {
332        sb.Append("No resources selected.");
333      }
334
335      descriptionTextBox.Text = sb.ToString();
336    }
337    #endregion
338  }
339}
Note: See TracBrowser for help on using the repository browser.