Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs @ 16209

Last change on this file since 16209 was 16209, checked in by jzenisek, 5 years ago

#2839:

  • adapted job execution implementation at ProjectJobsView
  • prohibited resource checking for non-admins
File size: 29.7 KB
RevLine 
[6976]1#region License Information
2/* HeuristicLab
[16117]3 * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[6976]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;
[8051]23using System.Collections.Generic;
[16117]24using System.ComponentModel;
[6976]25using System.Drawing;
26using System.Linq;
27using System.Windows.Forms;
[8051]28using HeuristicLab.Clients.Access;
[6976]29using HeuristicLab.Clients.Hive.Views;
[16117]30using HeuristicLab.Collections;
31using HeuristicLab.Common.Resources;
[6976]32using HeuristicLab.Core;
33using HeuristicLab.Core.Views;
34using HeuristicLab.MainForm;
35
36namespace HeuristicLab.Clients.Hive.Administrator.Views {
37  [View("Resources View")]
[7928]38  [Content(typeof(IItemList<Resource>), false)]
[6976]39  public partial class ResourcesView : ItemView, IDisposable {
40    private const int slaveImageIndex = 0;
41    private const int slaveGroupImageIndex = 1;
[16117]42    public const string UNGROUPED_GROUP_NAME = "UNGROUPED";
43    public const string UNGROUPED_GROUP_DESCRIPTION = "Contains slaves that are not assigned to any group.";
44    private const string SELECTED_TAG = ""; // " [selected]";
45    private const string NOT_STORED_TAG = "*"; // " [not stored]";
46    private const string CHANGES_NOT_STORED_TAG = "*"; // " [changes not stored]";
[6976]47
[16117]48    private readonly Color changedColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
49    private readonly Color selectedBackColor = Color.DodgerBlue;
50    private readonly Color selectedForeColor = Color.White;
51    private readonly Color calculatingColor = Color.FromArgb(255, 58, 114, 35); // #3a7223
52    private readonly Color offlineColor = Color.FromArgb(255, 187, 36, 36); // #bb2424
53    private readonly Color grayTextColor = SystemColors.GrayText;
[6976]54
55
[8051]56
[16117]57    private TreeNode ungroupedGroupNode;
58
59    private Resource selectedResource = null;
60    public Resource SelectedResource {
61      get { return selectedResource; }
62      set { if (selectedResource != value) ChangeSelectedResource(value); }
[6976]63    }
64
[16117]65    private readonly object locker = new object();
[6976]66
[16117]67    public new IItemList<Resource> Content {
68      get { return (IItemList<Resource>)base.Content; }
69      set { base.Content = value; }
[6976]70    }
71
[16117]72    public ResourcesView() {
73      InitializeComponent();
[6976]74
[16117]75      treeView.ImageList.Images.Add(VSImageLibrary.MonitorLarge);
76      treeView.ImageList.Images.Add(VSImageLibrary.NetworkCenterLarge);
77
78      HiveAdminClient.Instance.Refreshing += HiveAdminClient_Instance_Refreshing;
79      HiveAdminClient.Instance.Refreshed += HiveAdminClient_Instance_Refreshed;
80      AccessClient.Instance.Refreshing += AccessClient_Instance_Refreshing;
81      AccessClient.Instance.Refreshed += AccessClient_Instance_Refreshed;
[6976]82    }
83
[16117]84    #region Overrides
85    protected override void OnClosing(FormClosingEventArgs e) {
86      AccessClient.Instance.Refreshed -= AccessClient_Instance_Refreshed;
87      AccessClient.Instance.Refreshing -= AccessClient_Instance_Refreshing;
88      HiveAdminClient.Instance.Refreshed -= HiveAdminClient_Instance_Refreshed;
89      HiveAdminClient.Instance.Refreshing -= HiveAdminClient_Instance_Refreshing;
90      base.OnClosing(e);
[8051]91    }
92
[16117]93    protected override void RegisterContentEvents() {
94      base.RegisterContentEvents();
95      Content.ItemsAdded += Content_ItemsAdded;
96      Content.ItemsRemoved += Content_ItemsRemoved;
[8051]97    }
98
[6976]99    protected override void DeregisterContentEvents() {
[16117]100      Content.ItemsRemoved -= Content_ItemsRemoved;
101      Content.ItemsAdded -= Content_ItemsAdded;
[6976]102      base.DeregisterContentEvents();
103    }
104
105    protected override void OnContentChanged() {
106      base.OnContentChanged();
107      if (Content == null) {
[16117]108        treeView.Nodes.Clear();
109        viewHost.Content = null;
[8051]110        scheduleView.Content = null;
[6976]111      } else {
[16117]112        BuildResourceTree(Content);
113      }
[16122]114      SetEnabledStateOfControls();
[16117]115    }
[6976]116
[16117]117    protected override void SetEnabledStateOfControls() {
118      base.SetEnabledStateOfControls();
[6976]119
[16122]120      bool locked = Content == null || Locked || ReadOnly;
121      bool addLocked = locked
122                    || !IsAdmin()
123                    || (selectedResource is Slave && selectedResource.ParentResourceId != null)
124                    || (selectedResource != null && selectedResource.Id == Guid.Empty);
[6976]125
[16122]126      HashSet<Guid> descendantResources = null;
[16185]127      bool selectedRDeleteLocked = selectedResource == null
128                              || (selectedResource.Id != Guid.Empty && (!HiveAdminClient.Instance.ResourceDescendants.TryGetValue(selectedResource.Id, out descendantResources) || descendantResources.Any()));
[16122]129
[16185]130      var nodes = GetCheckedNodes(treeView.Nodes).ToList();
131      var checkedResources = nodes.Select(x => x.Tag).OfType<Resource>().ToList();
132      bool checkedRDeleteLocked = false;
133      for (int i = 0; !checkedRDeleteLocked && i < checkedResources.Count; i++) {
134        if (checkedResources[i].Id != Guid.Empty &&
135            (!HiveAdminClient.Instance.ResourceDescendants.TryGetValue(checkedResources[i].Id, out descendantResources) ||
136             descendantResources.Any()))
137          checkedRDeleteLocked = true;
138      }
139
[16122]140      bool deleteLocked = locked
[16185]141                          || !IsAdmin()
142                          || !Content.Any()
143                          || checkedResources.Any() && checkedRDeleteLocked
144                          || !checkedResources.Any() && selectedRDeleteLocked;
[16122]145
146      bool saveLocked = locked
147                       || !IsAdmin()
148                       || !Content.Any()
149                       || selectedResource == null;
150
[16117]151      btnAddGroup.Enabled = !addLocked;
152      btnRemoveGroup.Enabled = !deleteLocked;
[16122]153      btnSave.Enabled = !saveLocked;
154      viewHost.Locked = locked || !IsAdmin();
155      scheduleView.Locked = locked || !IsAdmin();
[16117]156    }
157    #endregion
[6976]158
[16117]159    #region Event Handlers
160    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Resource>> e) {
161      if (InvokeRequired) Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<Resource>>>)Content_ItemsAdded, sender, e);
162      else {
163        OnContentChanged();
[6976]164      }
165    }
166
[16117]167    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Resource>> e) {
168      if (InvokeRequired) Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<Resource>>>)Content_ItemsRemoved, sender, e);
169      else {
170        OnContentChanged();
171      }
172    }
173
174    private void SlaveViewContent_PropertyChanged(object sender, PropertyChangedEventArgs e) {
175      if (InvokeRequired) Invoke((Action<object, PropertyChangedEventArgs>)SlaveViewContent_PropertyChanged, sender, e);
176      else {
177        OnContentChanged();
178        if (e.PropertyName == "HbInterval") {
179          UpdateChildHbIntervall((Resource)viewHost.Content);
[6976]180        }
[16117]181      }
182    }
[6976]183
[16117]184    private void HiveAdminClient_Instance_Refreshing(object sender, EventArgs e) {
185      if (InvokeRequired) Invoke((Action<object, EventArgs>)HiveAdminClient_Instance_Refreshing, sender, e);
186      else {
187        var mainForm = MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>();
188        mainForm.AddOperationProgressToView(this, "Refreshing ...");
189        SetEnabledStateOfControls();
[6976]190      }
191    }
192
[16117]193    private void HiveAdminClient_Instance_Refreshed(object sender, EventArgs e) {
194      if (InvokeRequired) Invoke((Action<object, EventArgs>)HiveAdminClient_Instance_Refreshed, sender, e);
195      else {
196        var mainForm = MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>();
197        mainForm.RemoveOperationProgressFromView(this);
198        SetEnabledStateOfControls();
[7250]199      }
[6976]200    }
201
[16117]202    private void AccessClient_Instance_Refreshing(object sender, EventArgs e) {
203      if (InvokeRequired) Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshing, sender, e);
204      else {
205        var mainForm = MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>();
206        mainForm.AddOperationProgressToView(this, "Refreshing ...");
207        SetEnabledStateOfControls();
208      }
[8051]209    }
[6976]210
[16117]211    private void AccessClient_Instance_Refreshed(object sender, EventArgs e) {
212      if (InvokeRequired) Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshed, sender, e);
213      else {
214        var mainForm = MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>();
215        mainForm.RemoveOperationProgressFromView(this);
216        SetEnabledStateOfControls();
217      }
218    }
[6976]219
[16117]220    private async void ResourcesView_Load(object sender, EventArgs e) {
221      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
222        action: () => UpdateResources());
223    }
[8051]224
[16117]225    private async void btnRefresh_Click(object sender, EventArgs e) {
226      lock (locker) {
227        if (!btnRefresh.Enabled) return;
228        btnRefresh.Enabled = false;
229      }
[8051]230
[16117]231      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
232        action: () => UpdateResources(),
233        finallyCallback: () => btnRefresh.Enabled = true);
234    }
[8051]235
[16117]236    private void btnAddGroup_Click(object sender, EventArgs e) {
[16122]237      var parentResourceId = selectedResource is SlaveGroup ? selectedResource.Id : (Guid?)null;
[16117]238
239      var group = new SlaveGroup {
240        Name = "New Group",
241        OwnerUserId = UserInformation.Instance.User.Id,
242        ParentResourceId = parentResourceId
243      };
244
245      SelectedResource = group;
246      Content.Add(group);
[6976]247    }
248
[16185]249    private async void btnRemoveGroup_Click(object sender, EventArgs e) {     
250      var nodes = GetCheckedNodes(treeView.Nodes).ToList();
251      var checkedResources = nodes.Select(x => x.Tag).OfType<Resource>().ToList();
252      if (selectedResource == null && !checkedResources.Any()) return;
[16117]253
254      lock (locker) {
255        if (!btnRemoveGroup.Enabled) return;
256        btnRemoveGroup.Enabled = false;
[6976]257      }
[16117]258
[16185]259      if (checkedResources.Count > 0) {
260        var result = MessageBox.Show(
261          "Do you really want to delete all " + checkedResources.Count + " checked resources?",
262          "HeuristicLab Hive Administrator",
263          MessageBoxButtons.YesNo,
264          MessageBoxIcon.Question);
265        if (result == DialogResult.Yes) {
266          await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
267            action: () => {
268              RemoveResource(checkedResources);
269            });
270        }
271      } else {
272        var res = checkedResources.Any() ? checkedResources.First() : selectedResource;
273        var result = MessageBox.Show(
274          "Do you really want to delete the selected resource " + res.Name + "?",
275          "HeuristicLab Hive Administrator",
276          MessageBoxButtons.YesNo,
277          MessageBoxIcon.Question);
278        if (result == DialogResult.Yes) {
279          await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
280            action: () => {
281              RemoveResource(res);
282            });
283        }
284      }
[16122]285
[16185]286      OnContentChanged();
287      SetEnabledStateOfControls();
[6976]288    }
289
[16117]290    private async void btnSave_Click(object sender, EventArgs e) {
291      lock (locker) {
292        if (!btnSave.Enabled) return;
293        btnSave.Enabled = false;
[6976]294      }
[16117]295
296      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
297        action: () => {
298          var resourcesToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
299          foreach (var resource in resourcesToSave)
300            resource.Store();
301          UpdateResources();
[16122]302        });
[16117]303
304      OnContentChanged();
[16122]305      SetEnabledStateOfControls();
[6976]306    }
307
[16117]308    private void treeSlaveGroup_MouseDown(object sender, MouseEventArgs e) {
309      var node = treeView.GetNodeAt(e.Location);
310      if (node == null || node == ungroupedGroupNode) return;
311      var r = (Resource)node.Tag;
312      if (!HiveAdminClient.Instance.DisabledParentResources.Contains(r)) ChangeSelectedResourceNode(node);
[6976]313    }
314
[16117]315    private void treeSlaveGroup_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
316      e.Cancel = true;
[6976]317    }
318
[16117]319    private void treeSlaveGroup_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
[16209]320      if (!IsAdmin() || e.Node == ungroupedGroupNode) {
[16117]321        e.Cancel = true;
322      } else {
323        var r = (Resource)e.Node.Tag;
324        if (HiveAdminClient.Instance.DisabledParentResources.Contains(r)) {
325          e.Cancel = true;
326        }
327      }
328    }
329
[16185]330    private void treeSlaveGroup_AfterCheck(object sender, TreeViewEventArgs e) {
331      SetEnabledStateOfControls();
332    }
333
[16117]334    private void treeSlaveGroup_DragDrop(object sender, DragEventArgs e) {
335      if (e.Effect == DragDropEffects.None) return;
336
337      var targetNode = treeView.GetNodeAt(treeView.PointToClient(new Point(e.X, e.Y)));
338      var targetResource = (targetNode != null) ? (Resource)targetNode.Tag : null;
339      var resources = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IEnumerable<Resource>;
340
341      foreach (var r in resources) {
342        r.ParentResourceId = targetResource != null ? targetResource.Id : (Guid?)null;
343      }
344
345      // TODO
346      //HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
[6976]347      OnContentChanged();
348    }
349
[16117]350    private void treeSlaveGroup_ItemDrag(object sender, ItemDragEventArgs e) {
351      if (!IsAdmin()) return;
[6976]352
[16117]353      var nodes = GetCheckedNodes(treeView.Nodes).ToList();
354      TreeNode sourceNode = (TreeNode)e.Item;
355      if (!sourceNode.Checked) nodes.Add(sourceNode);
356      nodes.Remove(ungroupedGroupNode);
357      ungroupedGroupNode.Checked = false;
358      var resources = nodes.Select(x => x.Tag).OfType<Resource>().ToList();
359
360      if (resources.Count > 0) {
361        DataObject data = new DataObject();
362        data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, resources);
363        var action = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
364        if (action.HasFlag(DragDropEffects.Move)) {
365          foreach (var node in nodes) node.Remove();
366          StyleTreeNode(ungroupedGroupNode, (Resource)ungroupedGroupNode.Tag, resources);
[6976]367        }
368      }
369    }
370
[16117]371    private IEnumerable<TreeNode> GetCheckedNodes(TreeNodeCollection nodes) {
372      if (nodes != null) {
373        foreach (var node in nodes.OfType<TreeNode>()) {
374          if (node.Checked && node != ungroupedGroupNode) yield return node;
375          foreach (var child in GetCheckedNodes(node.Nodes))
376            yield return child;
[6976]377        }
378      }
379    }
380
[16117]381    private void treeSlaveGroup_DragEnterOver(object sender, DragEventArgs e) {
382      e.Effect = DragDropEffects.Move;
383      var resources = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IEnumerable<Resource>;
384      var targetNode = treeView.GetNodeAt(treeView.PointToClient(new Point(e.X, e.Y)));
385      var targetResource = (targetNode != null ? targetNode.Tag : null) as Resource;
[6976]386
[16117]387      if (!IsAdmin()
388        || resources == null
389        || !resources.Any()
390        || resources.Any(x => !HiveAdminClient.Instance.CheckParentChange(x, targetResource))
391        || (targetNode != null && (targetNode == ungroupedGroupNode || targetNode.Parent == ungroupedGroupNode))) {
392        e.Effect = DragDropEffects.None;
393      }
394    }
[6976]395
[16117]396    private void TabSlaveGroup_TabIndexChanged(object sender, EventArgs e) {
397      throw new NotImplementedException();
398    }
[6976]399
[16117]400    private async void TabSlaveGroup_Selected(object sender, System.Windows.Forms.TabControlEventArgs e) {
401      if (e.TabPage == tabSchedule) {
402        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
403          action: () => UpdateSchedule(),
404          finallyCallback: () => scheduleView.Content = HiveAdminClient.Instance.Downtimes);
405      }
406      SetEnabledStateOfControls();
407    }
408    #endregion
[6976]409
[16117]410    #region Helpers
411    private void BuildResourceTree(IEnumerable<Resource> resources) {
412      treeView.Nodes.Clear();
413      if (!resources.Any()) return;
[8051]414
[16117]415      var disabledParentResources = HiveAdminClient.Instance.DisabledParentResources;
416      var mainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
417        .Where(x => x.ParentResourceId == null));
418      //var parentedMainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
419      //  .Where(x => x.ParentResourceId.HasValue && !resources.Select(y => y.Id).Contains(x.ParentResourceId.Value)));
420      //mainResources.UnionWith(parentedMainResources);
421      var mainDisabledParentResources = new HashSet<Resource>(disabledParentResources.Where(x => x.ParentResourceId == null || x.ParentResourceId == Guid.Empty));
422      mainResources.UnionWith(mainDisabledParentResources);
423      var subResources = new HashSet<Resource>(resources.Union(disabledParentResources).Except(mainResources).OrderByDescending(x => x.Name));
[8051]424
[16117]425      var stack = new Stack<Resource>(mainResources.OrderByDescending(x => x.Name));
426      if (selectedResource != null) SelectedResource = resources.Where(x => x.Id == selectedResource.Id).FirstOrDefault();
427      bool nodeSelected = false;
[6976]428
[16117]429      TreeNode currentNode = null;
430      Resource currentResource = null;
431
432      while (stack.Any()) {
433        var newResource = stack.Pop();
434        var newNode = new TreeNode(newResource.Name) { Tag = newResource };
435        StyleTreeNode(newNode, newResource, resources);
436
437        if (selectedResource == null && !disabledParentResources.Contains(newResource)) {
438          SelectedResource = newResource;
439        }
440        if (!nodeSelected && selectedResource != null && newResource.Id == selectedResource.Id) {
441          newNode.BackColor = selectedBackColor;
442          newNode.ForeColor = selectedForeColor;
443          newNode.Text += SELECTED_TAG;
444          nodeSelected = true;
445        }
446
447        if (disabledParentResources.Contains(newResource)) {
448          newNode.Checked = false;
449          newNode.ForeColor = grayTextColor;
450        }
451
452        // search for parent node of newNode and save in currentNode
453        // necessary since newNodes (stack top items) might be siblings
454        // or grand..grandparents of previous node (currentNode)
455        while (currentNode != null && newResource.ParentResourceId != currentResource.Id) {
456          currentNode = currentNode.Parent;
457          currentResource = currentNode == null ? null : (Resource)currentNode.Tag;
458        }
459
460        if (currentNode == null) {
461          treeView.Nodes.Add(newNode);
462        } else {
463          currentNode.Nodes.Add(newNode);
464        }
465
466        if (newResource is SlaveGroup) {
467          var childResources = subResources.Where(x => x.ParentResourceId == newResource.Id);
468          if (childResources.Any()) {
469            foreach (var resource in childResources.OrderByDescending(x => x.Name)) {
470              subResources.Remove(resource);
471              stack.Push(resource);
[6976]472            }
[16117]473            currentNode = newNode;
474            currentResource = newResource;
[6976]475          }
476        }
[16117]477        newNode.SelectedImageIndex = newNode.ImageIndex;
[6976]478      }
479
[16117]480      // collapse slave-only nodes
481      foreach (TreeNode n in treeView.Nodes) {
482        CollapseSlaveOnlyNodes(n);
483      }
[6976]484
[16117]485      ungroupedGroupNode = new TreeNode(UNGROUPED_GROUP_NAME) {
486        ForeColor = SystemColors.GrayText,
[16122]487        ImageIndex = slaveGroupImageIndex,
[16117]488        Tag = new SlaveGroup() {
489          Name = UNGROUPED_GROUP_NAME,
490          Description = UNGROUPED_GROUP_DESCRIPTION
[6976]491        }
[16117]492      };
493
494      foreach (var slave in subResources.OfType<Slave>().OrderBy(x => x.Name)) {
495        var slaveNode = new TreeNode(slave.Name) { Tag = slave };
496        StyleTreeNode(slaveNode, slave, resources);
497        ungroupedGroupNode.Nodes.Add(slaveNode);
498        if (selectedResource == null) {
499          SelectedResource = slave;
500        }
501
502        if (slave.Id == selectedResource.Id && !nodeSelected) {
503          slaveNode.BackColor = selectedBackColor;
504          slaveNode.ForeColor = selectedForeColor;
505          slaveNode.Text += SELECTED_TAG;
506          nodeSelected = true;
507        }
[6976]508      }
509
[16117]510      if (ungroupedGroupNode.Nodes.Count > 0) {
511        ungroupedGroupNode.Text += " [" + ungroupedGroupNode.Nodes.Count.ToString() + "]";
512        ungroupedGroupNode.Expand();
[16122]513        treeView.Nodes.Add(ungroupedGroupNode);
[16117]514      }
[6976]515    }
516
[16117]517    private void CollapseSlaveOnlyNodes(TreeNode tn) {
518      Resource r = (Resource)tn.Tag;
519      var descendants = GetResourceDescendants();
520      if (descendants.ContainsKey(r.Id)) {
521        if (descendants[r.Id].OfType<SlaveGroup>().Any()) {
522          tn.Expand();
523          foreach (TreeNode n in tn.Nodes) CollapseSlaveOnlyNodes(n);
524        } else {
525          tn.Collapse();
526        }
527      }
[6976]528    }
529
[16117]530    private void ExpandResourceNodesOfInterest(TreeNodeCollection nodes) {
531      foreach (TreeNode n in nodes) {
532        Resource r = (Resource)n.Tag;
533        if (n.Nodes.Count > 0) {
534          if (HiveAdminClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()) {
535            n.Expand();
536            ExpandResourceNodesOfInterest(n.Nodes);
537          } else {
538            n.Collapse();
539          }
540        } else {
541          n.Collapse();
542        }
543      }
[6976]544    }
545
[16117]546    private void UpdateChildHbIntervall(Resource resource) {
547      foreach (Resource r in Content.Where(x => x.ParentResourceId == resource.Id)) {
548        r.HbInterval = resource.HbInterval;
549        if (r is SlaveGroup) {
550          UpdateChildHbIntervall(r);
[7256]551        }
[6976]552      }
553    }
554
555    private void UpdateResources() {
556      try {
557        HiveAdminClient.Instance.Refresh();
558        Content = HiveAdminClient.Instance.Resources;
[16117]559      } catch (AnonymousUserException) {
560        ShowHiveInformationDialog();
[6976]561      }
[16117]562    }
563
564    private void RemoveResource(Resource resource) {
565      if (resource == null) return;
566
567      try {
568        if (resource.Id != Guid.Empty) {
569          SelectedResource = HiveAdminClient.Instance.GetAvailableResourceAncestors(resource.Id).LastOrDefault();
[16185]570
571          // deal with all new, but not yet saved resources
572          var newResources = Content.Where(x => x.ParentResourceId == resource.Id).ToList();
573          if (newResources.Any(x => x.Id != Guid.Empty)) return;
574          foreach (var nr in newResources) Content.Remove(nr);
575
576          HiveAdminClient.Delete(resource);         
[16117]577          UpdateResources();
578        } else {
[16185]579          SelectedResource = Content.FirstOrDefault(x => x.Id == resource.ParentResourceId);
[16122]580          Content.Remove(resource);
[16117]581        }
582      } catch (AnonymousUserException) {
583        ShowHiveInformationDialog();
[6976]584      }
[16117]585    }
586
[16185]587    private void RemoveResource(IEnumerable<Resource> resources) {
588      if (resources == null || !resources.Any()) return;
589
590      var ids = resources.Select(x => x.Id).ToList();     
591      try {
592        bool update = false;
593        foreach (var r in resources) {         
594          if (r.Id != Guid.Empty)  {
595            if(r.Id == SelectedResource.Id)
596              SelectedResource = HiveAdminClient.Instance.GetAvailableResourceAncestors(r.Id).LastOrDefault();
597
598            // deal with all new, but not yet saved resources
599            var newResources = Content.Where(x => x.ParentResourceId == r.Id).ToList();
600            if (newResources.Any(x => x.Id != Guid.Empty)) return;
601            foreach (var nr in newResources) Content.Remove(nr);
602
603            HiveAdminClient.Delete(r);
604            update = true;
605          } else {
606            if (r.Id == SelectedResource.Id)
607              SelectedResource = Content.FirstOrDefault(x => x.Id == r.ParentResourceId);
608            Content.Remove(r);
609          }
610        }
611        if (update) UpdateResources();
612      } catch (AnonymousUserException) {
613        ShowHiveInformationDialog();
614      }
615    }
616
[16117]617    private void UpdateSchedule() {
618      try {
619        HiveAdminClient.Instance.RefreshCalendar();
620      } catch (AnonymousUserException) {
[7256]621        ShowHiveInformationDialog();
[7249]622      }
[6976]623    }
624
[16117]625    private bool IsAdmin() {
626      return HiveRoles.CheckAdminUserPermissions();
627    }
628
629    private void StyleTreeNode(TreeNode n, Resource r, IEnumerable<Resource> resources) {
630      n.Text = r.Name;
631      n.BackColor = Color.Transparent;
632      n.ForeColor = Color.Black;
633
634      if (HiveAdminClient.Instance.DisabledParentResources.Select(x => x.Id).Contains(r.Id)) {
635        n.ForeColor = grayTextColor;
636      } else if (r.Id == Guid.Empty && n != ungroupedGroupNode /*!r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
637        // not stored (i.e. new)
638        n.Text += NOT_STORED_TAG;
639      } else if (r.Modified && n != ungroupedGroupNode /*!r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
640        // changed
641        n.Text += CHANGES_NOT_STORED_TAG;
642      }
643
644      // slave count
645      int childSlavesCount = 0;
646      if (r.Id != Guid.Empty && r is SlaveGroup) {
647        var descendants = GetResourceDescendants();
648        if (descendants.ContainsKey(r.Id)) {
649          childSlavesCount = resources
650            .OfType<Slave>()
651            .Where(x => descendants[r.Id].Select(y => y.Id)
652              .Contains(x.Id))
653            .Count();
654        }
655      } else if (n == ungroupedGroupNode /*|| r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
656        childSlavesCount = resources
657          .OfType<Slave>()
658          .Where(x => x.ParentResourceId == null
659            || (x.ParentResourceId.HasValue && x.ParentResourceId.Value == Guid.Empty))
660          .Count();
661      }
662      if (childSlavesCount > 0)
663        n.Text += " [" + childSlavesCount.ToString() + "]";
664
665      // slave image index, state, utilization
666      if (r is Slave) {
667        n.ImageIndex = slaveImageIndex;
668        var s = r as Slave;
669        if (s.SlaveState == SlaveState.Calculating) {
670          n.ForeColor = calculatingColor;
671          n.Text += " [" + s.CpuUtilization.ToString("N2") + "%]";
672        } else if (s.SlaveState == SlaveState.Offline) {
673          n.ForeColor = offlineColor;
674          if (s.LastHeartbeat.HasValue)
675            n.Text += " [" + (s.LastHeartbeat != null ? s.LastHeartbeat.Value.ToString("g") : null) + "]";
676        }
[7256]677      } else {
[16117]678        n.ImageIndex = slaveGroupImageIndex;
[7256]679      }
[16117]680
681      // ungrouped
682      if (n == ungroupedGroupNode /*r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
683        n.ForeColor = SystemColors.GrayText;
684      }
[7256]685    }
686
[16117]687    private void ResetTreeNodes(TreeNodeCollection nodes, IEnumerable<Resource> resources) {
688      foreach (TreeNode n in nodes) {
689        StyleTreeNode(n, (Resource)n.Tag, resources);
690        if (n.Nodes.Count > 0) {
691          ResetTreeNodes(n.Nodes, resources);
[7256]692        }
693      }
694    }
695
[16117]696    private async void ChangeSelectedResource(Resource resource) {
697      selectedResource = resource;
698      viewHost.Content = selectedResource;
[6976]699
[16117]700      HiveAdminClient.Instance.DowntimeForResourceId = selectedResource != null ? selectedResource.Id : Guid.Empty;
701      if (tabSlaveGroup.SelectedTab == tabSchedule) {
702        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
703          action: () => UpdateSchedule(),
704          finallyCallback: () => scheduleView.Content = HiveAdminClient.Instance.Downtimes);
705      }
[6976]706
[16117]707      SetEnabledStateOfControls();
[6976]708    }
709
[16117]710    private void ChangeSelectedResourceNode(TreeNode resourceNode) {
711      if (resourceNode == null) return;
712      SelectedResource = (Resource)resourceNode.Tag;
713      ResetTreeNodes(treeView.Nodes, Content);
714      resourceNode.BackColor = selectedBackColor;
715      resourceNode.ForeColor = selectedForeColor;
716      resourceNode.Text += SELECTED_TAG;
[8051]717    }
718
[16117]719    private void ShowHiveInformationDialog() {
720      if (InvokeRequired) Invoke((Action)ShowHiveInformationDialog);
721      else {
722        using (HiveInformationDialog dialog = new HiveInformationDialog()) {
723          dialog.ShowDialog(this);
724        }
725      }
[8051]726    }
727
[16117]728    private void ResetView() {
729      if (InvokeRequired) Invoke((Action)ResetView);
730      else {
731        treeView.Nodes.Clear();
[8051]732
[16117]733        if (viewHost.Content != null && viewHost.Content is SlaveGroup) {
734          ((SlaveGroup)viewHost.Content).PropertyChanged -= SlaveViewContent_PropertyChanged;
735        }
[6976]736
[16117]737        viewHost.Content = null;
738        if (scheduleView.Content != null) {
739          scheduleView.Content.Clear();
740        }
741
742        HiveAdminClient.Instance.ResetDowntime();
[6976]743      }
744    }
745
[6994]746
[16117]747    private Dictionary<Guid, HashSet<Resource>> GetResourceDescendants() {
748      var resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
[16185]749      //var resources = Content.Where(x => x.Id != Guid.Empty).Union(HiveAdminClient.Instance.DisabledParentResources).ToList();     
[16117]750      var resources = Content.Union(HiveAdminClient.Instance.DisabledParentResources).ToList();
751
752      foreach (var r in resources) {
[16185]753        if(!resourceDescendants.ContainsKey(r.Id))
754          resourceDescendants.Add(r.Id, new HashSet<Resource>());
755      }
756      foreach (var r in resources) {
[16117]757        var parentResourceId = r.ParentResourceId;
758        while (parentResourceId != null) {
759          var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
760          if (parent != null) {
761            resourceDescendants[parent.Id].Add(r);
762            parentResourceId = parent.ParentResourceId;
763          } else {
764            parentResourceId = null;
765          }
766        }
767      }
768      return resourceDescendants;
[6994]769    }
[8051]770
[16117]771    #endregion
[6976]772  }
773}
Note: See TracBrowser for help on using the repository browser.