source: branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs @ 15913

Last change on this file since 15913 was 15913, checked in by jzenisek, 4 years ago

#2839: updated genealogy computation for hive job administrator

File size: 25.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2017 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.Windows.Forms;
27using HeuristicLab.Collections;
28using HeuristicLab.Common.Resources;
29using HeuristicLab.Core;
30using HeuristicLab.Core.Views;
31using HeuristicLab.MainForm;
32using HeuristicLab.MainForm.WindowsForms;
33
34namespace HeuristicLab.Clients.Hive.JobManager.Views {
35  [View("Hive Project Selector View")]
36  [Content(typeof(IItemList<Project>), true)]
37  public partial class HiveProjectSelector : ItemView, IDisposable {
38    private const int greenFlagImageIndex = 0;
39    private const int redFlagImageIndex = 1;
40    private const int slaveImageIndex = 0;
41    private const int slaveGroupImageIndex = 1;
42    public const string additionalSlavesGroupName = "Additional Slaves";
43    public const string additionalSlavesGroupDescription = "Contains additional slaves which are either ungrouped or the parenting slave group is not assigned to the selected project.";
44
45    private const string CURRENT_SELECTION_TAG = " [current selection]";
46    private const string NEW_SELECTION_TAG = " [new selection]";
47    private const string CHANGED_SELECTION_TAG = " [changed selection]";
48
49    private readonly HashSet<TreeNode> mainTreeNodes = new HashSet<TreeNode>();
50    private readonly HashSet<TreeNode> filteredTreeNodes = new HashSet<TreeNode>();
51    private readonly HashSet<TreeNode> nodeStore = new HashSet<TreeNode>();
52
53    private readonly HashSet<Resource> availableResources = new HashSet<Resource>();
54    private readonly HashSet<Resource> assignedResources = new HashSet<Resource>();
55    private readonly HashSet<Resource> includedResources = new HashSet<Resource>();
56    private readonly HashSet<Resource> newAssignedResources = new HashSet<Resource>();
57    private readonly HashSet<Resource> newIncludedResources = new HashSet<Resource>();
58
59    private IEnumerable<Resource> addedResources;
60    private IEnumerable<Resource> removedResources;
61    private IEnumerable<Resource> addedIncludes;
62    private IEnumerable<Resource> removedIncludes;
63
64    private readonly Color addedAssignmentColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
65    private readonly Color removedAssignmentColor = Color.FromArgb(255, 236, 159, 72); // #ec9f48
66    private readonly Color addedIncludeColor = Color.FromArgb(25, 169, 221, 221); // #a9dddd
67    private readonly Color removedIncludeColor = Color.FromArgb(25, 249, 210, 145); // #f9d291
68    private readonly Color selectedBackColor = Color.DodgerBlue;
69    private readonly Color selectedForeColor = Color.White;
70
71    private string currentSearchString;
72
73    private void resetHiveResourceSelector() {
74      lastSelectedProject = null;
75      selectedProject = null;
76      projectId = null;
77    }
78
79    private Guid jobId;
80    public Guid JobId {
81      get { return jobId; }
82      set {
83        if (jobId == value) return;
84        jobId = value;
85        resetHiveResourceSelector();
86      }
87    }
88
89    private Guid? projectId;
90    public Guid? ProjectId {
91      get { return projectId; }
92      set {
93        if (projectId == value) return;
94        projectId = value;
95      }
96    }
97
98    private Guid? selectedProjectId;
99    public Guid? SelectedProjectId {
100      get { return selectedProjectId; }
101      set {
102        if (selectedProjectId == value) return;
103        selectedProjectId = value;
104      }
105    }
106
107    private IEnumerable<Guid> selectedResourceIds;
108    public IEnumerable<Guid> SelectedResourceIds {
109      get { return selectedResourceIds; }
110      set {
111        if (selectedResourceIds == value) return;
112        selectedResourceIds = value;
113      }
114    }
115
116    public bool ChangedProjectSelection {
117      get {
118        if ((lastSelectedProject == null && selectedProject != null)
119          || (lastSelectedProject != null && selectedProject == null)
120          || (lastSelectedProject != null && selectedProject != null && lastSelectedProject.Id != selectedProject.Id))
121          return true;
122        else return false;
123      }
124    }
125
126    public bool ChangedResources {
127      get { return !assignedResources.SetEquals(newAssignedResources); }
128    }
129
130    private Project lastSelectedProject;
131    private Project selectedProject;
132    public Project SelectedProject {
133      get { return selectedProject; }
134      set {
135        lastSelectedProject = selectedProject;
136        if (selectedProject == value) return;
137        selectedProject = value;
138        UpdateResourceTree();
139        ExtractStatistics();
140        OnSelectedProjectChanged();
141      }
142    }
143
144    public IEnumerable<Resource> AssignedResources {
145      get { return newAssignedResources; }
146      set {
147        if (newAssignedResources == value) return;
148        newAssignedResources.Clear();
149        foreach(var resource in value) {
150          newAssignedResources.Add(resource);
151        }
152      }
153    }
154
155
156    public new IItemList<Project> Content {
157      get { return (IItemList<Project>)base.Content; }
158      set { base.Content = value; }
159    }
160
161    public HiveProjectSelector() {
162      InitializeComponent();
163
164      projectsImageList.Images.Add(VSImageLibrary.FlagGreen);
165      projectsImageList.Images.Add(VSImageLibrary.FlagRed);
166      resourcesImageList.Images.Add(VSImageLibrary.MonitorLarge);
167      resourcesImageList.Images.Add(VSImageLibrary.NetworkCenterLarge);
168    }
169
170    #region Overrides
171    protected override void OnContentChanged() {
172      base.OnContentChanged();
173
174      if (Content != null) {               
175        if (SelectedProjectId.HasValue && SelectedProjectId.Value != Guid.Empty) {
176          SelectedProject = GetSelectedProjectById(SelectedProjectId.Value);
177        } else {
178          SelectedProject = null;
179        }
180        //ExtractStatistics();
181        UpdateProjectTree();
182
183      } else {
184        lastSelectedProject = null;
185        selectedProject = null;
186        selectedProjectId = null;
187        projectsTreeView.Nodes.Clear();
188        resourcesTreeView.Nodes.Clear();
189      }
190    }
191
192    #endregion
193
194    #region Event Handlers
195    private void HiveProjectSelector_Load(object sender, EventArgs e) {
196      projectsTreeView.Nodes.Clear();
197      resourcesTreeView.Nodes.Clear();
198    }
199
200    private void searchTextBox_TextChanged(object sender, EventArgs e) {
201      currentSearchString = searchTextBox.Text.ToLower();
202      //UpdateFilteredTree();
203      UpdateProjectTree();
204    }
205
206    private void projectsTreeView_MouseDoubleClick(object sender, MouseEventArgs e) {
207      OnProjectsTreeViewDoubleClicked();
208    }
209
210    private void projectsTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
211      var node = (Project)e.Node.Tag;
212     
213      if (node == null) {
214        projectsTreeView.SelectedNode = null;
215      } else {
216        ResetTreeNodes(projectsTreeView.Nodes);
217        e.Node.BackColor = selectedBackColor;
218        e.Node.ForeColor = selectedForeColor;
219       
220        if(node.Id == projectId) {
221          e.Node.Text += CURRENT_SELECTION_TAG;
222        } else if(projectId == null || projectId == Guid.Empty) {
223          e.Node.Text += NEW_SELECTION_TAG;
224        } else {
225          e.Node.Text += CHANGED_SELECTION_TAG;
226        }
227
228       
229      }
230      SelectedProject = node;
231      //ExtractStatistics();
232    }
233
234    private void resourcesTreeView_MouseDown(object sender, MouseEventArgs e) {
235      var node = resourcesTreeView.GetNodeAt(new Point(e.X, e.Y));
236
237      if (node == null) {
238        resourcesTreeView.SelectedNode = null;
239      }
240
241      ExtractStatistics((Resource)node?.Tag);
242    }
243
244    private void resourcesTreeView_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
245      var checkedResource = (Resource)e.Node.Tag;
246      if (newIncludedResources.Contains(checkedResource) || checkedResource.Id == Guid.Empty) e.Cancel = true;
247    }
248
249    private void resourcesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
250      var checkedResource = (Resource)e.Node.Tag;
251      if (e.Node.Checked) {
252        newAssignedResources.Add(checkedResource);
253      } else {
254        newAssignedResources.Remove(checkedResource);
255      }
256
257      UpdateNewResourceTree();
258      ExtractStatistics();
259      //ExtractStatistics((Resource)resourcesTreeView.SelectedNode?.Tag);
260      OnAssignedResourcesChanged();
261    }
262
263    private void resourcesTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
264      return;
265    }
266    #endregion
267
268    #region Helpers
269
270    private Project GetSelectedProjectById(Guid projectId) {
271      return Content.Where(x => x.Id == projectId).SingleOrDefault();
272    }
273
274    private void UpdateProjectTree() {
275
276      if (string.IsNullOrEmpty(currentSearchString)) {
277        BuildProjectTree(Content);
278      } else {
279        HashSet<Project> filteredProjects = new HashSet<Project>();
280        foreach(var project in Content) {
281          if(project.Name.ToLower().Contains(currentSearchString.ToLower())) {
282            filteredProjects.Add(project);
283            filteredProjects.UnionWith(Content.Where(p => HiveClient.Instance.ProjectAncestors[project.Id].Contains(p.Id)));
284          }
285        }
286        BuildProjectTree(filteredProjects);
287      }
288    }
289
290    private void BuildProjectTree(IEnumerable<Project> projects) {
291      projectsTreeView.Nodes.Clear();
292      if (!projects.Any()) return;
293
294      // select all top level projects (withouth parent, or without any ancestor within current project collection)
295      var mainProjects = new HashSet<Project>(projects.Where(x => x.ParentProjectId == null));
296      var parentedMainProjects = new HashSet<Project>(projects
297        .Where(x => x.ParentProjectId.HasValue
298        && !projects.Select(y => y.Id).Contains(x.ParentProjectId.Value)
299        && !projects.SelectMany(y => HiveClient.Instance.ProjectAncestors[y.Id]).Contains(x.ParentProjectId.Value)));
300      mainProjects.UnionWith(parentedMainProjects);
301      var subProbjects = new HashSet<Project>(projects.Except(mainProjects));
302      foreach(var p in subProbjects) {
303        p.ParentProjectId = HiveClient.Instance.ProjectAncestors[p.Id].Where(x => projects.Select(y => y.Id).Contains(x)).FirstOrDefault();
304      }
305
306      var stack = new Stack<Project>(mainProjects.OrderByDescending(x => x.Name));
307
308      TreeNode currentNode = null;
309      Project currentProject = null;
310
311      while(stack.Any()) {
312        var newProject = stack.Pop();
313        var newNode = new TreeNode(newProject.Name) { Tag = newProject };
314
315        while (currentNode != null && newProject.ParentProjectId != currentProject.Id) {
316          currentNode = currentNode.Parent;
317          currentProject = currentNode == null ? null : (Project)currentNode.Tag;
318        }
319
320        if (currentNode == null) {
321          projectsTreeView.Nodes.Add(newNode);
322          newNode.ImageIndex = greenFlagImageIndex;
323        } else {
324          currentNode.Nodes.Add(newNode);
325          newNode.ImageIndex = redFlagImageIndex;
326        }
327
328        newNode.SelectedImageIndex = newNode.ImageIndex;
329
330        if (SelectedProject != null && SelectedProject.Id.Equals(newProject.Id)) {
331          newNode.BackColor = selectedBackColor;
332          newNode.ForeColor = selectedForeColor;
333          if(SelectedProject.Id == projectId) {
334            newNode.Text += CURRENT_SELECTION_TAG;
335          } else if (projectId == null || projectId == Guid.Empty) {
336            newNode.Text += NEW_SELECTION_TAG;
337          } else {
338            newNode.Text += CHANGED_SELECTION_TAG;
339          }
340        }
341
342        if (!string.IsNullOrEmpty(currentSearchString) && newProject.Name.ToLower().Contains(currentSearchString.ToLower())) {
343          newNode.BackColor = Color.LightBlue;
344        }
345
346        var childProjects = subProbjects.Where(x => x.ParentProjectId == newProject.Id);
347        if (childProjects.Any()) {
348          foreach (var project in childProjects.OrderByDescending(x => x.Name)) {
349            subProbjects.Remove(project);
350            stack.Push(project);
351          }
352          currentNode = newNode;
353          currentProject = newProject;
354        }
355      }
356
357      projectsTreeView.ExpandAll();
358    }
359
360    private static IEnumerable<Resource> GetAssignedResourcesForProject(Guid projectId) {
361      var assignedProjectResources = HiveServiceLocator.Instance.CallHiveService(s => s.GetAssignedResourcesForProject(projectId));
362      return HiveClient.Instance.Resources.Where(x => assignedProjectResources.Select(y => y.ResourceId).Contains(x.Id));
363    }
364
365    private static IEnumerable<Resource> GetAssignedResourcesForJob(Guid jobId) {
366      var assignedJobResources = HiveServiceLocator.Instance.CallHiveService(s => s.GetAssignedResourcesForJob(jobId));
367      return HiveClient.Instance.Resources.Where(x => assignedJobResources.Select(y => y.ResourceId).Contains(x.Id));
368    }
369
370    private void UpdateResourceTree() {
371      UpdateAvailableResources();
372      UpdateAssignedResources();
373      UpdateIncludedResources();
374      BuildResourceTree(availableResources);
375    }
376
377    private void UpdateNewResourceTree() {
378      UpdateNewAssignedResources();
379      UpdateNewIncludedResources();
380      BuildResourceTree(availableResources);
381    }
382
383    private void UpdateAvailableResources() {
384      availableResources.Clear();
385      if (selectedProject != null) {
386        var assignedProjectResources = GetAssignedResourcesForProject(selectedProject.Id);
387        foreach (var resource in assignedProjectResources) {
388          availableResources.Add(resource);
389          foreach(var descendant in HiveClient.Instance.Resources.Where(x => HiveClient.Instance.ResourceDescendants[resource.Id].Contains(x.Id))) {
390            availableResources.Add(descendant);
391          }
392        }
393      }
394      //ExtractStatistics();
395      //OnAssignedResourcesChanged();
396    }
397
398    private void UpdateAssignedResources() {
399      assignedResources.Clear();
400      newAssignedResources.Clear();
401
402      if (JobId == Guid.Empty || JobId == null) { // new, unchanged jobs get all avaialable resources
403        // update new assigned resources
404        if(selectedResourceIds == null) {
405          foreach (var resource in availableResources
406            .Where(x => !x.ParentResourceId.HasValue
407            || !availableResources.Select(y => y.Id).Contains(x.ParentResourceId.Value))) {
408            newAssignedResources.Add(resource);
409          }
410        } else {
411          foreach(var resource in availableResources.Where(x => selectedResourceIds.Contains(x.Id))) {
412            newAssignedResources.Add(resource);
413          }
414        }
415      } else { // existent, unchanged jobs get all assigned resources
416        // update assigned resources
417        var assignedJobResources = GetAssignedResourcesForJob(JobId);
418        foreach (var resource in assignedJobResources) {
419          assignedResources.Add(resource);
420          if (selectedResourceIds == null) {
421            newAssignedResources.Add(resource);
422          }
423        }
424
425        if(selectedResourceIds != null) {
426          foreach (var resource in availableResources.Where(x => selectedResourceIds.Contains(x.Id))) {
427            newAssignedResources.Add(resource);
428          }
429        }
430      }
431
432      //ExtractStatistics();
433      OnAssignedResourcesChanged();
434    }
435
436    private void UpdateNewAssignedResources() {
437      for(int i = newAssignedResources.Count-1; i>=0; i--) {
438        if(newAssignedResources.Intersect(HiveClient.Instance.GetAvailableParentResources(newAssignedResources.ElementAt(i).Id)).Any()) {
439          newAssignedResources.Remove(newAssignedResources.ElementAt(i));
440        }
441      }
442    }
443
444    private void UpdateIncludedResources() {
445      includedResources.Clear();
446      newIncludedResources.Clear();
447
448      if (JobId != Guid.Empty) {
449        foreach (var item in assignedResources) {
450          foreach (var descendant in HiveClient.Instance.GetAvailableChildResources(item.Id)) {
451            includedResources.Add(descendant);
452          }
453        }
454      }
455
456      foreach (var item in newAssignedResources) {
457        foreach (var descendant in HiveClient.Instance.GetAvailableChildResources(item.Id)) {
458          newIncludedResources.Add(descendant);
459        }
460      }
461    }
462
463    private void UpdateNewIncludedResources() {
464      newIncludedResources.Clear();
465      foreach (var item in newAssignedResources) {
466        foreach (var descendant in HiveClient.Instance.GetAvailableChildResources(item.Id)) {
467          newIncludedResources.Add(descendant);
468        }
469      }
470    }
471
472    private void BuildResourceTree(IEnumerable<Resource> resources) {
473      resourcesTreeView.Nodes.Clear();
474      if (!resources.Any()) return;
475
476      resourcesTreeView.BeforeCheck -= resourcesTreeView_BeforeCheck;
477      resourcesTreeView.AfterCheck -= resourcesTreeView_AfterCheck;
478
479      var mainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>().Where(x => x.ParentResourceId == null));
480      var parentedMainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
481        .Where(x => x.ParentResourceId.HasValue && !resources.Select(y => y.Id).Contains(x.ParentResourceId.Value)));
482      mainResources.UnionWith(parentedMainResources);
483      var subResources = new HashSet<Resource>(resources.Except(mainResources));
484
485      var addedAssignments = newAssignedResources.Except(assignedResources);
486      var removedAssignments = assignedResources.Except(newAssignedResources);
487      var addedIncludes = newIncludedResources.Except(includedResources);
488      var removedIncludes = includedResources.Except(newIncludedResources);
489
490      HashSet<TreeNode> expandedNodes = new HashSet<TreeNode>();
491      TreeNode currentNode = null;
492      Resource currentResource = null;
493
494      var stack = new Stack<Resource>(mainResources.OrderByDescending(x => x.Name));
495
496      while (stack.Any()) {
497        var newResource = stack.Pop();
498        var newNode = new TreeNode(newResource.Name) { Tag = newResource };
499
500        // search for parent node of newNode and save in currentNode
501        // necessary since newNodes (stack top items) might be siblings
502        // or grand..grandparents of previous node (currentNode)
503        while (currentNode != null && newResource.ParentResourceId != currentResource.Id) {
504          currentNode = currentNode.Parent;
505          currentResource = currentNode == null ? null : (Resource)currentNode.Tag;
506        }
507
508        if (currentNode == null) {
509          resourcesTreeView.Nodes.Add(newNode);
510        } else {
511          currentNode.Nodes.Add(newNode);
512        }
513
514        if(newAssignedResources.Select(x => x.Id).Contains(newResource.Id)
515          || assignedResources.Select(x => x.Id).Contains(newResource.Id)
516          || newIncludedResources.Select(x => x.Id).Contains(newResource.Id)
517          || includedResources.Select(x => x.Id).Contains(newResource.Id)) {
518          expandedNodes.Add(newNode);
519        }
520
521        if (newAssignedResources.Select(x => x.Id).Contains(newResource.Id)) {
522          newNode.Checked = true;
523        } else if (newIncludedResources.Select(x => x.Id).Contains(newResource.Id)) {
524          newNode.Checked = true;
525          newNode.ForeColor = SystemColors.GrayText;
526        }
527
528        if (includedResources.Select(x => x.Id).Contains(newResource.Id) && newIncludedResources.Select(x => x.Id).Contains(newResource.Id)) {
529          newNode.Text += " [included]";
530        } else if (addedIncludes.Select(x => x.Id).Contains(newResource.Id)) {
531          newNode.BackColor = addedIncludeColor;
532          newNode.ForeColor = SystemColors.GrayText;
533          newNode.Text += " [added include]";
534        } else if (removedIncludes.Select(x => x.Id).Contains(newResource.Id)) {
535          newNode.BackColor = removedIncludeColor;
536          newNode.Text += " [removed include]";
537        }
538
539        if (addedAssignments.Select(x => x.Id).Contains(newResource.Id)) {
540          newNode.BackColor = addedAssignmentColor;
541          newNode.ForeColor = SystemColors.ControlText;
542          newNode.Text += " [added selection]";
543        } else if (removedAssignments.Select(x => x.Id).Contains(newResource.Id)) {
544          newNode.BackColor = removedAssignmentColor;
545          newNode.ForeColor = SystemColors.ControlText;
546          newNode.Text += " [removed selection]";
547        }
548
549        if (newResource is Slave) {
550          newNode.ImageIndex = slaveImageIndex;
551        } else {
552          newNode.ImageIndex = slaveGroupImageIndex;
553
554          var childResources = subResources.Where(x => x.ParentResourceId == newResource.Id);
555          if (childResources.Any()) {
556            foreach (var resource in childResources.OrderByDescending(x => x.Name)) {
557              subResources.Remove(resource);
558              stack.Push(resource);
559            }
560            currentNode = newNode;
561            currentResource = newResource;
562          }
563        }
564        newNode.SelectedImageIndex = newNode.ImageIndex;
565      }
566
567      var singleSlaves = subResources.OfType<Slave>();
568      if (singleSlaves.Any()) {
569
570        var additionalNode = new TreeNode(additionalSlavesGroupName) {
571          ForeColor = SystemColors.GrayText,
572          Tag = new SlaveGroup() {
573            Name = additionalSlavesGroupName,
574            Description = additionalSlavesGroupDescription
575          }
576        };
577
578        foreach (var slave in singleSlaves.OrderBy(x => x.Name)) {
579          var slaveNode = new TreeNode(slave.Name) { Tag = slave };
580          additionalNode.Nodes.Add(slaveNode);
581        }
582
583        resourcesTreeView.Nodes.Add(additionalNode);
584      }
585
586     
587      foreach (var node in expandedNodes) {
588        node.Expand();
589        var parent = node.Parent;
590        while(parent != null) {
591          parent.Expand();
592          parent = parent.Parent;
593        }
594      }
595
596      resourcesTreeView.BeforeCheck += resourcesTreeView_BeforeCheck;
597      resourcesTreeView.AfterCheck += resourcesTreeView_AfterCheck;
598      //resourcesTreeView.ExpandAll();
599    }
600
601    private void ExpandSlaveGroupNodes() {
602      foreach (TreeNode n in nodeStore.Where(x => x.Tag is SlaveGroup)) {
603        TreeNode[] children = new TreeNode[n.Nodes.Count];
604        n.Nodes.CopyTo(children, 0);
605        if (children.Any(x => x.Tag is SlaveGroup)) n.Expand();
606      }
607    }
608
609    private void ExtractStatistics(Resource resource = null) {
610      HashSet<Slave> newAssignedSlaves = new HashSet<Slave>(newAssignedResources.OfType<Slave>());
611      foreach (var slaveGroup in newAssignedResources.OfType<SlaveGroup>()) {
612        foreach(var slave in HiveClient.Instance.ResourceDescendants[slaveGroup.Id].OfType<Slave>()) {
613          newAssignedSlaves.Add(slave);
614        }
615      }
616
617      HashSet<Slave> selectedSlaves = null;
618
619      if (resource != null) {
620        var slaveGroup = resource as SlaveGroup;
621        if (slaveGroup != null) {
622          selectedSlaves = new HashSet<Slave>(HiveClient.Instance.ResourceDescendants[slaveGroup.Id].OfType<Slave>());
623          //selectedSlaves.IntersectWith(newAssignedSlaves);
624        } else {
625          selectedSlaves = new HashSet<Slave>(new[] { resource as Slave });
626        }
627      } else {
628        selectedSlaves = newAssignedSlaves;
629      }
630
631      int sumCores = selectedSlaves.Sum(x => x.Cores.GetValueOrDefault());
632      int sumFreeCores = selectedSlaves.Sum(x => x.FreeCores.GetValueOrDefault());
633      double sumMemory = selectedSlaves.Sum(x => x.Memory.GetValueOrDefault()) / 1024.0;
634      double sumFreeMemory = selectedSlaves.Sum(x => x.FreeMemory.GetValueOrDefault()) / 1024.0;
635
636      coresSummaryLabel.Text = $"{sumCores} Total ({sumFreeCores} Free / {sumCores - sumFreeCores} Used)";
637      memorySummaryLabel.Text = $"{sumMemory:0.00} GB Total ({sumFreeMemory:0.00} GB Free / {(sumMemory - sumFreeMemory):0.00} GB Used)";
638    }
639
640    private void StyleTreeNode(TreeNode n, string name) {
641      n.Text = name;
642      n.BackColor = Color.Transparent;
643      n.ForeColor = Color.Black;
644    }
645
646    private void ResetTreeNodes(TreeNodeCollection nodes) {
647      foreach (TreeNode n in nodes) {
648        string name = "";
649        if (n.Tag is Project) name = ((Project)n.Tag).Name;
650        else if (n.Tag is Resource) name = ((Resource)n.Tag).Name;
651        StyleTreeNode(n, name);
652        if (n.Nodes.Count > 0) {
653          ResetTreeNodes(n.Nodes);
654        }
655      }
656    }
657
658    #endregion
659
660    #region Events
661    public event EventHandler SelectedProjectChanged;
662    private void OnSelectedProjectChanged() {
663      SelectedProjectChanged?.Invoke(this, EventArgs.Empty);
664    }
665
666    public event EventHandler AssignedResourcesChanged;
667    private void OnAssignedResourcesChanged() {
668      AssignedResourcesChanged?.Invoke(this, EventArgs.Empty);
669    }
670
671    public event EventHandler ProjectsTreeViewDoubleClicked;
672    private void OnProjectsTreeViewDoubleClicked() {
673      ProjectsTreeViewDoubleClicked?.Invoke(this, EventArgs.Empty);
674    }
675    #endregion
676  }
677}
Note: See TracBrowser for help on using the repository browser.