source: branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.cs @ 15422

Last change on this file since 15422 was 15422, checked in by jkarder, 3 years ago

#2839: worked on resources and projects views

File size: 9.4 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.Clients.Access;
28using HeuristicLab.Common.Resources;
29using HeuristicLab.Core.Views;
30using HeuristicLab.MainForm;
31
32namespace HeuristicLab.Clients.Hive.Administrator.Views {
33  [View("ProjectView")]
34  [Content(typeof(Project), IsDefaultView = false)]
35  public partial class ProjectResourcesView : ItemView {
36    private const int slaveImageIndex = 0;
37    private const int slaveGroupImageIndex = 1;
38    public const string ungroupedGroupName = "UNGROUPED";
39    public const string ungroupedGroupDescription = "Contains slaves that are not assigned to any group.";
40
41    private readonly HashSet<Resource> assignedResources = new HashSet<Resource>();
42    private readonly HashSet<Resource> inheritedResources = new HashSet<Resource>();
43    private readonly Color ownedResourceColor = Color.LightGreen;
44
45    public new Project Content {
46      get { return (Project)base.Content; }
47      set { base.Content = value; }
48    }
49
50    public ProjectResourcesView() {
51      InitializeComponent();
52
53      treeView.ImageList.Images.Add(VSImageLibrary.MonitorLarge);
54      treeView.ImageList.Images.Add(VSImageLibrary.NetworkCenterLarge);
55    }
56
57    #region Overrides
58    protected override void OnContentChanged() {
59      base.OnContentChanged();
60      if (Content == null) {
61        assignedResources.Clear();
62        inheritedResources.Clear();
63        treeView.Nodes.Clear();
64        detailsViewHost.Content = null;
65      } else {
66        UpdateAssignedResources();
67        UpdateInheritedResources();
68        var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
69        detailsViewHost.Content = top;
70      }
71    }
72    #endregion
73
74    #region Event Handlers
75    private void ProjectResourcesView_Load(object sender, EventArgs e) {
76
77    }
78
79    private void refreshButton_Click(object sender, EventArgs e) {
80      UpdateAssignedResources();
81      UpdateInheritedResources();
82      var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
83      detailsViewHost.Content = top;
84    }
85
86    private void inheritButton_Click(object sender, EventArgs e) {
87      SetAssignedProjectResources(Content.Id, Enumerable.Empty<Guid>());
88      UpdateAssignedResources();
89      UpdateInheritedResources();
90      var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
91      detailsViewHost.Content = top;
92    }
93
94    private async void saveButton_Click(object sender, EventArgs e) {
95      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
96        action: () => SetAssignedProjectResources(Content.Id, assignedResources.Select(x => x.Id)));
97    }
98
99    private void treeView_AfterSelect(object sender, TreeViewEventArgs e) {
100      var selectedResource = (Resource)e.Node.Tag;
101      detailsViewHost.Content = selectedResource;
102    }
103
104    private void treeView_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
105      var checkedResource = (Resource)e.Node.Tag;
106      if (inheritedResources.Contains(checkedResource) || checkedResource.Id == Guid.Empty) e.Cancel = true;
107    }
108
109    private void treeView_AfterCheck(object sender, TreeViewEventArgs e) {
110      var checkedResource = (Resource)e.Node.Tag;
111      if (e.Node.Checked)
112        assignedResources.Add(checkedResource);
113      else
114        assignedResources.Remove(checkedResource);
115    }
116    #endregion
117
118    #region Helpers
119    private static IEnumerable<Resource> GetAssignedResourcesForProject(Guid projectId) {
120      var assignedProjectResources = HiveServiceLocator.Instance.CallHiveService(s => s.GetAssignedResourcesForProject(projectId));
121      var resourceIds = new HashSet<Guid>(assignedProjectResources.Select(x => x.ResourceId));
122      return HiveAdminClient.Instance.Resources.Where(x => resourceIds.Contains(x.Id));
123    }
124
125    private static void SetAssignedProjectResources(Guid projectId, IEnumerable<Guid> resourceIds) {
126      HiveServiceLocator.Instance.CallHiveService(s => {
127        var currentlyAssignedResources = s.GetAssignedResourcesForProject(projectId);
128        s.UnassignProjectResources(projectId, currentlyAssignedResources.Select(x => x.ResourceId).ToList());
129        s.AssignProjectResources(projectId, resourceIds.ToList());
130      });
131    }
132
133    private void UpdateAssignedResources() {
134      assignedResources.Clear();
135      foreach (var r in GetAssignedResourcesForProject(Content.Id))
136        assignedResources.Add(r);
137    }
138
139    private void UpdateInheritedResources() {
140      inheritedResources.Clear();
141      var parentProject = HiveAdminClient.Instance.Projects.SingleOrDefault(x => x.Id == Content.ParentProjectId);
142      while (parentProject != null) {
143        foreach (var r in GetAssignedResourcesForProject(parentProject.Id))
144          inheritedResources.Add(r);
145        parentProject = HiveAdminClient.Instance.Projects.SingleOrDefault(x => x.Id == parentProject.ParentProjectId);
146      }
147    }
148
149    private Resource BuildResourceTree(IEnumerable<Resource> resources) {
150      treeView.Nodes.Clear();
151      if (!resources.Any()) return null;
152
153      treeView.BeforeCheck -= treeView_BeforeCheck;
154      treeView.AfterCheck -= treeView_AfterCheck;
155
156      var slaveGroups = new HashSet<SlaveGroup>(resources.OfType<SlaveGroup>());
157      var slaves = new HashSet<Slave>(resources.OfType<Slave>());
158
159      var stack = new Stack<Resource>(slaveGroups.OrderByDescending(x => x.Name));
160      var top = stack.Peek();
161
162      TreeNode currentNode = null;
163      Resource currentResource = null;
164
165      while (stack.Any()) {
166        var newResource = stack.Pop();
167        var newNode = new TreeNode(newResource.Name) { Tag = newResource };
168
169        while (currentNode != null && newResource.ParentResourceId != currentResource.Id) {
170          currentNode = currentNode.Parent;
171          currentResource = currentNode == null ? null : (Resource)currentNode.Tag;
172        }
173
174        if (currentNode == null) {
175          treeView.Nodes.Add(newNode);
176        } else {
177          currentNode.Nodes.Add(newNode);
178        }
179
180        if (newResource is Slave) {
181          newNode.ImageIndex = slaveImageIndex;
182        } else {
183          newNode.ImageIndex = slaveGroupImageIndex;
184
185          var childSlaves = slaves.Where(x => x.ParentResourceId == newResource.Id);
186          foreach (var slave in childSlaves.OrderBy(x => x.Name)) {
187            slaves.Remove(slave);
188            var slaveNode = new TreeNode(slave.Name) { Tag = slave };
189
190            slaveNode.SelectedImageIndex = slaveNode.ImageIndex = slaveImageIndex;
191            if (slave.OwnerUserId == UserInformation.Instance.User.Id)
192              slaveNode.BackColor = ownedResourceColor;
193            if (inheritedResources.Contains(slave)) {
194              slaveNode.Checked = true;
195              slaveNode.Text += " (Inherited)";
196              slaveNode.ForeColor = SystemColors.GrayText;
197            } else if (assignedResources.Contains(slave))
198              slaveNode.Checked = true;
199
200            newNode.Nodes.Add(slaveNode);
201          }
202
203          var childSlaveGroups = slaveGroups.Where(x => x.ParentResourceId == newResource.Id);
204          if (childSlaveGroups.Any()) {
205            foreach (var slaveGroup in childSlaveGroups.OrderByDescending(x => x.Name)) {
206              slaveGroups.Remove(slaveGroup);
207              stack.Push(slaveGroup);
208            }
209            currentNode = newNode;
210            currentResource = newResource;
211          }
212        }
213
214        newNode.SelectedImageIndex = newNode.ImageIndex;
215        if (newResource.OwnerUserId == UserInformation.Instance.User.Id)
216          newNode.BackColor = ownedResourceColor;
217        if (inheritedResources.Contains(newResource)) {
218          newNode.Checked = true;
219          newNode.Text += " (Inherited)";
220          newNode.ForeColor = SystemColors.GrayText;
221        } else if (assignedResources.Contains(newResource))
222          newNode.Checked = true;
223      }
224
225      var ungroupedNode = new TreeNode(ungroupedGroupName) {
226        ForeColor = SystemColors.GrayText,
227        Tag = new SlaveGroup() {
228          Name = ungroupedGroupName,
229          Description = ungroupedGroupDescription
230        }
231      };
232
233      foreach (var slave in slaves.OrderBy(x => x.Name)) {
234        var slaveNode = new TreeNode(slave.Name) { Tag = slave };
235        ungroupedNode.Nodes.Add(slaveNode);
236      }
237
238      treeView.Nodes.Add(ungroupedNode);
239      treeView.BeforeCheck += treeView_BeforeCheck;
240      treeView.AfterCheck += treeView_AfterCheck;
241      treeView.ExpandAll();
242
243      return top;
244    }
245    #endregion
246  }
247}
Note: See TracBrowser for help on using the repository browser.