Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs @ 15412

Last change on this file since 15412 was 15412, checked in by jkarder, 5 years ago

#2839:

  • worked on resources and projects views
  • changed resource selector to be able to select projects and assigned resources
  • updated service clients
File size: 18.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.ComponentModel;
24using System.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Clients.Access;
28using HeuristicLab.Clients.Hive.Views;
29using HeuristicLab.Collections;
30using HeuristicLab.Common.Resources;
31using HeuristicLab.Core;
32using HeuristicLab.Core.Views;
33using HeuristicLab.MainForm;
34
35namespace HeuristicLab.Clients.Hive.Administrator.Views {
36  [View("Resources View")]
37  [Content(typeof(IItemList<Resource>), false)]
38  public partial class ResourcesView : ItemView, IDisposable {
39    private const string UngroupedGroupName = "UNGROUPED";
40    private const int slaveImageIndex = 0;
41    private const int slaveGroupImageIndex = 1;
42
43    private readonly Color ownedResourceColor = Color.LightGreen;
44    private readonly object locker = new object();
45    private bool updatingResources = false;
46    private bool removingResources = false;
47    private bool savingResources = false;
48
49    public new IItemList<Resource> Content {
50      get { return (IItemList<Resource>)base.Content; }
51      set { base.Content = value; }
52    }
53
54    public ResourcesView() {
55      InitializeComponent();
56
57      treeSlaveGroup.ImageList.Images.Add(VSImageLibrary.MonitorLarge);
58      treeSlaveGroup.ImageList.Images.Add(VSImageLibrary.NetworkCenterLarge);
59
60      HiveAdminClient.Instance.Refreshing += HiveAdminClient_Instance_Refreshing;
61      HiveAdminClient.Instance.Refreshed += HiveAdminClient_Instance_Refreshed;
62      AccessClient.Instance.Refreshing += AccessClient_Instance_Refreshing;
63      AccessClient.Instance.Refreshed += AccessClient_Instance_Refreshed;
64    }
65
66    #region Overrides
67    protected override void OnClosing(FormClosingEventArgs e) {
68      AccessClient.Instance.Refreshed -= AccessClient_Instance_Refreshed;
69      AccessClient.Instance.Refreshing -= AccessClient_Instance_Refreshing;
70      HiveAdminClient.Instance.Refreshed -= HiveAdminClient_Instance_Refreshed;
71      HiveAdminClient.Instance.Refreshing -= HiveAdminClient_Instance_Refreshing;
72      base.OnClosing(e);
73    }
74
75    protected override void RegisterContentEvents() {
76      base.RegisterContentEvents();
77      Content.ItemsAdded += Content_ItemsAdded;
78      Content.ItemsRemoved += Content_ItemsRemoved;
79    }
80
81    protected override void DeregisterContentEvents() {
82      Content.ItemsRemoved -= Content_ItemsRemoved;
83      Content.ItemsAdded -= Content_ItemsAdded;
84      base.DeregisterContentEvents();
85    }
86
87    protected override void OnContentChanged() {
88      base.OnContentChanged();
89      if (Content == null) {
90        slaveView.Content = null;
91        scheduleView.Content = null;
92        treeSlaveGroup.Nodes.Clear();
93      } else {
94        treeSlaveGroup.Nodes.Clear();
95
96        //rebuild
97        TreeNode ungrp = new TreeNode(UngroupedGroupName);
98        ungrp.ImageIndex = slaveGroupImageIndex;
99        ungrp.SelectedImageIndex = ungrp.ImageIndex;
100        var newGroup = new SlaveGroup();
101        newGroup.Name = UngroupedGroupName;
102        newGroup.Id = Guid.NewGuid();
103        newGroup.Description = "Contains slaves which are in no group";
104        ungrp.Tag = newGroup;
105
106        foreach (Resource g in Content.OrderBy(x => x.Name)) {
107          if (g.GetType() == typeof(SlaveGroup)) {
108            //root node
109            if (g.ParentResourceId == null) {
110              TreeNode tn = new TreeNode();
111              tn.ImageIndex = slaveGroupImageIndex;
112              tn.SelectedImageIndex = tn.ImageIndex;
113
114              tn.Tag = g;
115              tn.Text = g.Name;
116              if (g.OwnerUserId == Access.UserInformation.Instance.User.Id) tn.BackColor = ownedResourceColor;
117
118              BuildSlaveGroupTree(g, tn);
119              treeSlaveGroup.Nodes.Add(tn);
120            }
121          } else if (g.GetType() == typeof(Slave)) {
122            if (g.ParentResourceId == null) {
123              var stn = new TreeNode(g.Name);
124              stn.ImageIndex = slaveImageIndex;
125              stn.SelectedImageIndex = stn.ImageIndex;
126              stn.Tag = g;
127              if (g.OwnerUserId == Access.UserInformation.Instance.User.Id) stn.BackColor = ownedResourceColor;
128              ungrp.Nodes.Add(stn);
129            }
130          }
131        }
132        treeSlaveGroup.Nodes.Add(ungrp);
133      }
134    }
135
136    protected override void SetEnabledStateOfControls() {
137      base.SetEnabledStateOfControls();
138      bool enabled = Content != null;
139      btnAddGroup.Enabled = enabled;
140      btnRemoveGroup.Enabled = enabled;
141      btnSave.Enabled = enabled;
142      scheduleView.SetEnabledStateOfSchedule(enabled && IsAuthorized(slaveView.Content));
143    }
144    #endregion
145
146    #region Event Handlers
147    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Resource>> e) {
148      if (InvokeRequired) Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<Resource>>>)Content_ItemsAdded, sender, e);
149      else {
150        OnContentChanged();
151      }
152    }
153
154    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Resource>> e) {
155      if (InvokeRequired) Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<Resource>>>)Content_ItemsRemoved, sender, e);
156      else {
157        OnContentChanged();
158      }
159    }
160
161    private void SlaveViewContent_PropertyChanged(object sender, PropertyChangedEventArgs e) {
162      if (InvokeRequired) Invoke((Action<object, PropertyChangedEventArgs>)SlaveViewContent_PropertyChanged, sender, e);
163      else {
164        OnContentChanged();
165        if (e.PropertyName == "HbInterval") {
166          UpdateChildHbIntervall(slaveView.Content);
167        }
168      }
169    }
170
171    private void HiveAdminClient_Instance_Refreshing(object sender, EventArgs e) {
172      if (InvokeRequired) Invoke((Action<object, EventArgs>)HiveAdminClient_Instance_Refreshing, sender, e);
173      else {
174        var mainForm = MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>();
175        mainForm.AddOperationProgressToView(this, "Refreshing ...");
176        SetEnabledStateOfControls();
177      }
178    }
179
180    private void HiveAdminClient_Instance_Refreshed(object sender, EventArgs e) {
181      if (InvokeRequired) Invoke((Action<object, EventArgs>)HiveAdminClient_Instance_Refreshed, sender, e);
182      else {
183        var mainForm = MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>();
184        mainForm.RemoveOperationProgressFromView(this);
185        SetEnabledStateOfControls();
186      }
187    }
188
189    private void AccessClient_Instance_Refreshing(object sender, EventArgs e) {
190      if (InvokeRequired) Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshing, sender, e);
191      else {
192        var mainForm = MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>();
193        mainForm.AddOperationProgressToView(this, "Refreshing ...");
194        SetEnabledStateOfControls();
195      }
196    }
197
198    private void AccessClient_Instance_Refreshed(object sender, EventArgs e) {
199      if (InvokeRequired) Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshed, sender, e);
200      else {
201        var mainForm = MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>();
202        mainForm.RemoveOperationProgressFromView(this);
203        SetEnabledStateOfControls();
204      }
205    }
206
207    private async void ResourcesView_Load(object sender, EventArgs e) {
208      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
209        action: () => UpdateResources());
210    }
211
212    private async void btnRefresh_Click(object sender, EventArgs e) {
213      lock (locker) {
214        if (updatingResources) return;
215        updatingResources = true;
216      }
217
218      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
219        action: () => UpdateResources(),
220        finallyCallback: () => updatingResources = false);
221    }
222
223    private void btnAddGroup_Click(object sender, EventArgs e) {
224      var group = new SlaveGroup {
225        Name = "New Group",
226        OwnerUserId = UserInformation.Instance.User.Id
227      };
228      Content.Add(group);
229    }
230
231    private async void btnRemoveGroup_Click(object sender, EventArgs e) {
232      lock (locker) {
233        if (removingResources) return;
234        removingResources = true;
235      }
236
237      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
238        action: () => RemoveResource(),
239        finallyCallback: () => removingResources = false);
240    }
241
242    private async void btnSave_Click(object sender, EventArgs e) {
243      lock (locker) {
244        if (savingResources) return;
245        savingResources = true;
246      }
247
248      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
249        action: () => {
250          var resourcesToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
251          foreach (var resource in resourcesToSave)
252            resource.Store();
253        },
254        finallyCallback: () => savingResources = false);
255    }
256
257    private async void treeSlaveGroup_AfterSelect(object sender, TreeViewEventArgs e) {
258      var selectedResource = (Resource)e.Node.Tag;
259
260      if (slaveView.Content != null && slaveView.Content is SlaveGroup)
261        slaveView.Content.PropertyChanged -= SlaveViewContent_PropertyChanged;
262
263      slaveView.Content = selectedResource;
264
265      if (selectedResource != null && selectedResource is SlaveGroup)
266        selectedResource.PropertyChanged += SlaveViewContent_PropertyChanged;
267
268      if (IsAuthorized(selectedResource)) {
269        if (!tabSlaveGroup.TabPages.Contains(tabSchedule))
270          tabSlaveGroup.TabPages.Add(tabSchedule);
271
272        HiveAdminClient.Instance.DowntimeForResourceId = selectedResource.Id;
273
274        if (tabSlaveGroup.SelectedIndex == 1) {
275          await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
276            action: () => UpdateSchedule(),
277            finallyCallback: () => scheduleView.Content = HiveAdminClient.Instance.Downtimes);
278        }
279      } else {
280        if (tabSlaveGroup.TabPages.Contains(tabSchedule))
281          tabSlaveGroup.TabPages.Remove(tabSchedule);
282        HiveAdminClient.Instance.DowntimeForResourceId = Guid.Empty;
283      }
284    }
285
286    private void treeSlaveGroup_DragDrop(object sender, DragEventArgs e) {
287      if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false)) {
288        Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
289        TreeNode destNode = ((TreeView)sender).GetNodeAt(pt);
290        TreeNode newNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
291
292        if (destNode.TreeView == newNode.TreeView) {
293          if (destNode.Text == UngroupedGroupName || (destNode.Parent != null && destNode.Parent.Text == UngroupedGroupName)) {
294            MessageBox.Show(string.Format("You can't drag items to the group \"{0}\".{1}This group only contains slaves which haven't yet been assigned to a real group.",
295              UngroupedGroupName, Environment.NewLine), "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Information);
296            return;
297          }
298
299          SlaveGroup sgrp = null;
300          TreeNode parentNode = null;
301          if (destNode.Tag != null && destNode.Tag is SlaveGroup) {
302            sgrp = (SlaveGroup)destNode.Tag;
303            parentNode = destNode;
304          } else if (destNode.Parent != null && destNode.Parent.Tag is SlaveGroup) {
305            sgrp = (SlaveGroup)destNode.Parent.Tag;
306            parentNode = destNode.Parent;
307          }
308
309          if (newNode.Tag is SlaveGroup && CheckParentsEqualsMovedNode(parentNode, newNode)) {
310            return;
311          }
312
313          SlaveGroup parent = (SlaveGroup)parentNode.Tag;
314
315          if (parent.OwnerUserId != null && !IsAuthorized(parent)) {
316            MessageBox.Show(string.Format("You don't have the permissions to drag items to the group \"{0}\".", ((Resource)parentNode.Tag).Name),
317              "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Error);
318            return;
319          }
320
321          if (sgrp != null && newNode.Tag != null) {
322            //save parent group to get an id
323            if (sgrp.Id == Guid.Empty) {
324              sgrp.Store();
325            }
326
327            if (newNode.Tag is Slave) {
328              Slave slave = (Slave)newNode.Tag;
329              if (slave.ParentResourceId == null || (slave.ParentResourceId != null && slave.ParentResourceId != sgrp.Id)) {
330                slave.ParentResourceId = sgrp.Id;
331                newNode.Remove();
332                parentNode.Nodes.Clear();
333                BuildSlaveGroupTree(sgrp, parentNode);
334              }
335            } else if (newNode.Tag is SlaveGroup) {
336              SlaveGroup slaveGroup = (SlaveGroup)newNode.Tag;
337              if (slaveGroup.ParentResourceId == null || (slaveGroup.ParentResourceId != null && slaveGroup.ParentResourceId != sgrp.Id)) {
338                slaveGroup.ParentResourceId = sgrp.Id;
339                newNode.Remove();
340                parentNode.Nodes.Clear();
341                BuildSlaveGroupTree(sgrp, parentNode);
342              }
343            }
344          }
345        }
346      }
347    }
348
349    private void treeSlaveGroup_ItemDrag(object sender, ItemDragEventArgs e) {
350      TreeNode sourceNode = (TreeNode)e.Item;
351      if (IsAuthorized((Resource)sourceNode.Tag))
352        DoDragDrop(sourceNode, DragDropEffects.All);
353    }
354
355    private void treeSlaveGroup_DragEnter(object sender, DragEventArgs e) {
356      e.Effect = DragDropEffects.Move;
357    }
358
359    private void treeSlaveGroup_DragOver(object sender, DragEventArgs e) {
360      e.Effect = DragDropEffects.Move;
361    }
362
363    private void treeSlaveGroup_QueryContinueDrag(object sender, QueryContinueDragEventArgs e) {
364      e.Action = DragAction.Continue;
365    }
366
367    private void tabSlaveGroup_SelectedIndexChanged(object sender, EventArgs e) {
368      if (tabSlaveGroup.SelectedIndex == 1) {
369        UpdateSchedule();
370      }
371    }
372    #endregion
373
374    #region Helpers
375    private void BuildSlaveGroupTree(Resource g, TreeNode tn) {
376      foreach (Resource r in Content.Where(s => s.ParentResourceId != null && s.ParentResourceId == g.Id).OrderBy(x => x.Name)) {
377        TreeNode stn = new TreeNode(r.Name);
378        if (r is Slave) {
379          stn.ImageIndex = slaveImageIndex;
380        } else if (r is SlaveGroup) {
381          stn.ImageIndex = slaveGroupImageIndex;
382        }
383        stn.SelectedImageIndex = stn.ImageIndex;
384        stn.Tag = r;
385        if (r.OwnerUserId == Access.UserInformation.Instance.User.Id) stn.BackColor = ownedResourceColor;
386        tn.Nodes.Add(stn);
387
388        BuildSlaveGroupTree(r, stn);
389      }
390    }
391
392    private void UpdateChildHbIntervall(Resource resource) {
393      foreach (Resource r in Content.Where(x => x.ParentResourceId == resource.Id)) {
394        r.HbInterval = resource.HbInterval;
395        if (r is SlaveGroup) {
396          UpdateChildHbIntervall(r);
397        }
398      }
399    }
400
401    private bool CheckParentsEqualsMovedNode(TreeNode dest, TreeNode movedNode) {
402      TreeNode tmp = dest;
403
404      while (tmp != null) {
405        if (tmp == movedNode) {
406          return true;
407        }
408        tmp = tmp.Parent;
409      }
410      return false;
411    }
412
413    private void ResetView() {
414      if (InvokeRequired) Invoke((Action)ResetView);
415      else {
416        treeSlaveGroup.Nodes.Clear();
417
418        if (slaveView.Content != null && slaveView.Content is SlaveGroup) {
419          slaveView.Content.PropertyChanged -= SlaveViewContent_PropertyChanged;
420        }
421
422        slaveView.Content = null;
423        if (scheduleView.Content != null) {
424          scheduleView.Content.Clear();
425        }
426
427        HiveAdminClient.Instance.ResetDowntime();
428      }
429    }
430
431    private void UpdateResources() {
432      HiveAdminClient.Instance.Refresh();
433      Content = HiveAdminClient.Instance.Resources;
434    }
435
436    private void RemoveResource() {
437      var selectedNode = treeSlaveGroup.SelectedNode;
438      if (selectedNode == null || selectedNode.Tag == null) return;
439
440      var resource = (Resource)selectedNode.Tag;
441      var result = MessageBox.Show(
442        "Do you really want to delete " + resource.Name + "?",
443        "HeuristicLab Hive Administrator",
444        MessageBoxButtons.YesNo,
445        MessageBoxIcon.Question);
446
447      if (result == DialogResult.Yes) {
448        if (resource is Slave) {
449          Content.Remove(resource);
450          HiveAdminClient.Delete(resource);
451        } else if (resource is SlaveGroup) {
452          if (Content.Any(x => x.ParentResourceId == resource.Id)) {
453            MessageBox.Show(
454              "Only empty resources can be deleted.",
455              "HeuristicLab Hive Administrator",
456              MessageBoxButtons.OK,
457              MessageBoxIcon.Error);
458          } else {
459            Content.Remove(resource);
460            HiveAdminClient.Delete(resource);
461          }
462        }
463      }
464    }
465
466    private void UpdateSchedule() {
467      try {
468        HiveAdminClient.Instance.RefreshCalendar();
469      } catch (AnonymousUserException) {
470        ShowHiveInformationDialog();
471      }
472    }
473
474    private bool IsAuthorized(Resource resource) {
475      return resource != null
476          && resource.Name != UngroupedGroupName
477          && resource.Id != Guid.Empty
478          && UserInformation.Instance.UserExists
479          && (resource.OwnerUserId == UserInformation.Instance.User.Id || HiveRoles.CheckAdminUserPermissions());
480    }
481
482    private void ShowHiveInformationDialog() {
483      if (InvokeRequired) Invoke((Action)ShowHiveInformationDialog);
484      else {
485        using (HiveInformationDialog dialog = new HiveInformationDialog()) {
486          dialog.ShowDialog(this);
487        }
488      }
489    }
490    #endregion
491  }
492}
Note: See TracBrowser for help on using the repository browser.