Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 16430 was 16430, checked in by pfleck, 6 years ago

#2845 merged branch into trunk
Reviewed by mkommenda

File size: 29.3 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 {
[16430]187        Progress.Show(this, "Refreshing ...", ProgressMode.Indeterminate);
[16117]188        SetEnabledStateOfControls();
[6976]189      }
190    }
191
[16117]192    private void HiveAdminClient_Instance_Refreshed(object sender, EventArgs e) {
193      if (InvokeRequired) Invoke((Action<object, EventArgs>)HiveAdminClient_Instance_Refreshed, sender, e);
194      else {
[16430]195        Progress.Hide(this);
[16117]196        SetEnabledStateOfControls();
[7250]197      }
[6976]198    }
199
[16117]200    private void AccessClient_Instance_Refreshing(object sender, EventArgs e) {
201      if (InvokeRequired) Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshing, sender, e);
202      else {
[16430]203        Progress.Show(this, "Refreshing ...", ProgressMode.Indeterminate);
[16117]204        SetEnabledStateOfControls();
205      }
[8051]206    }
[6976]207
[16117]208    private void AccessClient_Instance_Refreshed(object sender, EventArgs e) {
209      if (InvokeRequired) Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshed, sender, e);
210      else {
[16430]211        Progress.Hide(this);
[16117]212        SetEnabledStateOfControls();
213      }
214    }
[6976]215
[16117]216    private async void ResourcesView_Load(object sender, EventArgs e) {
217      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
218        action: () => UpdateResources());
219    }
[8051]220
[16117]221    private async void btnRefresh_Click(object sender, EventArgs e) {
222      lock (locker) {
223        if (!btnRefresh.Enabled) return;
224        btnRefresh.Enabled = false;
225      }
[8051]226
[16117]227      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
228        action: () => UpdateResources(),
229        finallyCallback: () => btnRefresh.Enabled = true);
230    }
[8051]231
[16117]232    private void btnAddGroup_Click(object sender, EventArgs e) {
[16122]233      var parentResourceId = selectedResource is SlaveGroup ? selectedResource.Id : (Guid?)null;
[16117]234
235      var group = new SlaveGroup {
236        Name = "New Group",
237        OwnerUserId = UserInformation.Instance.User.Id,
238        ParentResourceId = parentResourceId
239      };
240
241      SelectedResource = group;
242      Content.Add(group);
[6976]243    }
244
[16430]245    private async void btnRemoveGroup_Click(object sender, EventArgs e) {
[16185]246      var nodes = GetCheckedNodes(treeView.Nodes).ToList();
247      var checkedResources = nodes.Select(x => x.Tag).OfType<Resource>().ToList();
248      if (selectedResource == null && !checkedResources.Any()) return;
[16117]249
250      lock (locker) {
251        if (!btnRemoveGroup.Enabled) return;
252        btnRemoveGroup.Enabled = false;
[6976]253      }
[16117]254
[16185]255      if (checkedResources.Count > 0) {
256        var result = MessageBox.Show(
257          "Do you really want to delete all " + checkedResources.Count + " checked resources?",
258          "HeuristicLab Hive Administrator",
259          MessageBoxButtons.YesNo,
260          MessageBoxIcon.Question);
261        if (result == DialogResult.Yes) {
262          await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
263            action: () => {
264              RemoveResource(checkedResources);
265            });
266        }
267      } else {
268        var res = checkedResources.Any() ? checkedResources.First() : selectedResource;
269        var result = MessageBox.Show(
270          "Do you really want to delete the selected resource " + res.Name + "?",
271          "HeuristicLab Hive Administrator",
272          MessageBoxButtons.YesNo,
273          MessageBoxIcon.Question);
274        if (result == DialogResult.Yes) {
275          await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
276            action: () => {
277              RemoveResource(res);
278            });
279        }
280      }
[16122]281
[16185]282      OnContentChanged();
283      SetEnabledStateOfControls();
[6976]284    }
285
[16117]286    private async void btnSave_Click(object sender, EventArgs e) {
287      lock (locker) {
288        if (!btnSave.Enabled) return;
289        btnSave.Enabled = false;
[6976]290      }
[16117]291
292      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
293        action: () => {
294          var resourcesToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
295          foreach (var resource in resourcesToSave)
296            resource.Store();
297          UpdateResources();
[16122]298        });
[16117]299
300      OnContentChanged();
[16122]301      SetEnabledStateOfControls();
[6976]302    }
303
[16117]304    private void treeSlaveGroup_MouseDown(object sender, MouseEventArgs e) {
305      var node = treeView.GetNodeAt(e.Location);
306      if (node == null || node == ungroupedGroupNode) return;
307      var r = (Resource)node.Tag;
308      if (!HiveAdminClient.Instance.DisabledParentResources.Contains(r)) ChangeSelectedResourceNode(node);
[6976]309    }
310
[16117]311    private void treeSlaveGroup_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
312      e.Cancel = true;
[6976]313    }
314
[16117]315    private void treeSlaveGroup_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
[16209]316      if (!IsAdmin() || e.Node == ungroupedGroupNode) {
[16117]317        e.Cancel = true;
318      } else {
319        var r = (Resource)e.Node.Tag;
320        if (HiveAdminClient.Instance.DisabledParentResources.Contains(r)) {
321          e.Cancel = true;
322        }
323      }
324    }
325
[16185]326    private void treeSlaveGroup_AfterCheck(object sender, TreeViewEventArgs e) {
327      SetEnabledStateOfControls();
328    }
329
[16117]330    private void treeSlaveGroup_DragDrop(object sender, DragEventArgs e) {
331      if (e.Effect == DragDropEffects.None) return;
332
333      var targetNode = treeView.GetNodeAt(treeView.PointToClient(new Point(e.X, e.Y)));
334      var targetResource = (targetNode != null) ? (Resource)targetNode.Tag : null;
335      var resources = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IEnumerable<Resource>;
336
337      foreach (var r in resources) {
338        r.ParentResourceId = targetResource != null ? targetResource.Id : (Guid?)null;
339      }
340
341      // TODO
342      //HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
[6976]343      OnContentChanged();
344    }
345
[16117]346    private void treeSlaveGroup_ItemDrag(object sender, ItemDragEventArgs e) {
347      if (!IsAdmin()) return;
[6976]348
[16117]349      var nodes = GetCheckedNodes(treeView.Nodes).ToList();
350      TreeNode sourceNode = (TreeNode)e.Item;
351      if (!sourceNode.Checked) nodes.Add(sourceNode);
352      nodes.Remove(ungroupedGroupNode);
353      ungroupedGroupNode.Checked = false;
354      var resources = nodes.Select(x => x.Tag).OfType<Resource>().ToList();
355
356      if (resources.Count > 0) {
357        DataObject data = new DataObject();
358        data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, resources);
359        var action = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
360        if (action.HasFlag(DragDropEffects.Move)) {
361          foreach (var node in nodes) node.Remove();
362          StyleTreeNode(ungroupedGroupNode, (Resource)ungroupedGroupNode.Tag, resources);
[6976]363        }
364      }
365    }
366
[16117]367    private IEnumerable<TreeNode> GetCheckedNodes(TreeNodeCollection nodes) {
368      if (nodes != null) {
369        foreach (var node in nodes.OfType<TreeNode>()) {
370          if (node.Checked && node != ungroupedGroupNode) yield return node;
371          foreach (var child in GetCheckedNodes(node.Nodes))
372            yield return child;
[6976]373        }
374      }
375    }
376
[16117]377    private void treeSlaveGroup_DragEnterOver(object sender, DragEventArgs e) {
378      e.Effect = DragDropEffects.Move;
379      var resources = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IEnumerable<Resource>;
380      var targetNode = treeView.GetNodeAt(treeView.PointToClient(new Point(e.X, e.Y)));
381      var targetResource = (targetNode != null ? targetNode.Tag : null) as Resource;
[6976]382
[16117]383      if (!IsAdmin()
384        || resources == null
385        || !resources.Any()
386        || resources.Any(x => !HiveAdminClient.Instance.CheckParentChange(x, targetResource))
387        || (targetNode != null && (targetNode == ungroupedGroupNode || targetNode.Parent == ungroupedGroupNode))) {
388        e.Effect = DragDropEffects.None;
389      }
390    }
[6976]391
[16117]392    private void TabSlaveGroup_TabIndexChanged(object sender, EventArgs e) {
393      throw new NotImplementedException();
394    }
[6976]395
[16117]396    private async void TabSlaveGroup_Selected(object sender, System.Windows.Forms.TabControlEventArgs e) {
397      if (e.TabPage == tabSchedule) {
398        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
399          action: () => UpdateSchedule(),
400          finallyCallback: () => scheduleView.Content = HiveAdminClient.Instance.Downtimes);
401      }
402      SetEnabledStateOfControls();
403    }
404    #endregion
[6976]405
[16117]406    #region Helpers
407    private void BuildResourceTree(IEnumerable<Resource> resources) {
408      treeView.Nodes.Clear();
409      if (!resources.Any()) return;
[8051]410
[16117]411      var disabledParentResources = HiveAdminClient.Instance.DisabledParentResources;
412      var mainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
413        .Where(x => x.ParentResourceId == null));
414      //var parentedMainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
415      //  .Where(x => x.ParentResourceId.HasValue && !resources.Select(y => y.Id).Contains(x.ParentResourceId.Value)));
416      //mainResources.UnionWith(parentedMainResources);
417      var mainDisabledParentResources = new HashSet<Resource>(disabledParentResources.Where(x => x.ParentResourceId == null || x.ParentResourceId == Guid.Empty));
418      mainResources.UnionWith(mainDisabledParentResources);
419      var subResources = new HashSet<Resource>(resources.Union(disabledParentResources).Except(mainResources).OrderByDescending(x => x.Name));
[8051]420
[16117]421      var stack = new Stack<Resource>(mainResources.OrderByDescending(x => x.Name));
422      if (selectedResource != null) SelectedResource = resources.Where(x => x.Id == selectedResource.Id).FirstOrDefault();
423      bool nodeSelected = false;
[6976]424
[16117]425      TreeNode currentNode = null;
426      Resource currentResource = null;
427
428      while (stack.Any()) {
429        var newResource = stack.Pop();
430        var newNode = new TreeNode(newResource.Name) { Tag = newResource };
431        StyleTreeNode(newNode, newResource, resources);
432
433        if (selectedResource == null && !disabledParentResources.Contains(newResource)) {
434          SelectedResource = newResource;
435        }
436        if (!nodeSelected && selectedResource != null && newResource.Id == selectedResource.Id) {
437          newNode.BackColor = selectedBackColor;
438          newNode.ForeColor = selectedForeColor;
439          newNode.Text += SELECTED_TAG;
440          nodeSelected = true;
441        }
442
443        if (disabledParentResources.Contains(newResource)) {
444          newNode.Checked = false;
445          newNode.ForeColor = grayTextColor;
446        }
447
448        // search for parent node of newNode and save in currentNode
449        // necessary since newNodes (stack top items) might be siblings
450        // or grand..grandparents of previous node (currentNode)
451        while (currentNode != null && newResource.ParentResourceId != currentResource.Id) {
452          currentNode = currentNode.Parent;
453          currentResource = currentNode == null ? null : (Resource)currentNode.Tag;
454        }
455
456        if (currentNode == null) {
457          treeView.Nodes.Add(newNode);
458        } else {
459          currentNode.Nodes.Add(newNode);
460        }
461
462        if (newResource is SlaveGroup) {
463          var childResources = subResources.Where(x => x.ParentResourceId == newResource.Id);
464          if (childResources.Any()) {
465            foreach (var resource in childResources.OrderByDescending(x => x.Name)) {
466              subResources.Remove(resource);
467              stack.Push(resource);
[6976]468            }
[16117]469            currentNode = newNode;
470            currentResource = newResource;
[6976]471          }
472        }
[16117]473        newNode.SelectedImageIndex = newNode.ImageIndex;
[6976]474      }
475
[16117]476      // collapse slave-only nodes
477      foreach (TreeNode n in treeView.Nodes) {
478        CollapseSlaveOnlyNodes(n);
479      }
[6976]480
[16117]481      ungroupedGroupNode = new TreeNode(UNGROUPED_GROUP_NAME) {
482        ForeColor = SystemColors.GrayText,
[16122]483        ImageIndex = slaveGroupImageIndex,
[16117]484        Tag = new SlaveGroup() {
485          Name = UNGROUPED_GROUP_NAME,
486          Description = UNGROUPED_GROUP_DESCRIPTION
[6976]487        }
[16117]488      };
489
490      foreach (var slave in subResources.OfType<Slave>().OrderBy(x => x.Name)) {
491        var slaveNode = new TreeNode(slave.Name) { Tag = slave };
492        StyleTreeNode(slaveNode, slave, resources);
493        ungroupedGroupNode.Nodes.Add(slaveNode);
494        if (selectedResource == null) {
495          SelectedResource = slave;
496        }
497
498        if (slave.Id == selectedResource.Id && !nodeSelected) {
499          slaveNode.BackColor = selectedBackColor;
500          slaveNode.ForeColor = selectedForeColor;
501          slaveNode.Text += SELECTED_TAG;
502          nodeSelected = true;
503        }
[6976]504      }
505
[16117]506      if (ungroupedGroupNode.Nodes.Count > 0) {
507        ungroupedGroupNode.Text += " [" + ungroupedGroupNode.Nodes.Count.ToString() + "]";
508        ungroupedGroupNode.Expand();
[16122]509        treeView.Nodes.Add(ungroupedGroupNode);
[16117]510      }
[6976]511    }
512
[16117]513    private void CollapseSlaveOnlyNodes(TreeNode tn) {
514      Resource r = (Resource)tn.Tag;
515      var descendants = GetResourceDescendants();
516      if (descendants.ContainsKey(r.Id)) {
517        if (descendants[r.Id].OfType<SlaveGroup>().Any()) {
518          tn.Expand();
519          foreach (TreeNode n in tn.Nodes) CollapseSlaveOnlyNodes(n);
520        } else {
521          tn.Collapse();
522        }
523      }
[6976]524    }
525
[16117]526    private void ExpandResourceNodesOfInterest(TreeNodeCollection nodes) {
527      foreach (TreeNode n in nodes) {
528        Resource r = (Resource)n.Tag;
529        if (n.Nodes.Count > 0) {
530          if (HiveAdminClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()) {
531            n.Expand();
532            ExpandResourceNodesOfInterest(n.Nodes);
533          } else {
534            n.Collapse();
535          }
536        } else {
537          n.Collapse();
538        }
539      }
[6976]540    }
541
[16117]542    private void UpdateChildHbIntervall(Resource resource) {
543      foreach (Resource r in Content.Where(x => x.ParentResourceId == resource.Id)) {
544        r.HbInterval = resource.HbInterval;
545        if (r is SlaveGroup) {
546          UpdateChildHbIntervall(r);
[7256]547        }
[6976]548      }
549    }
550
551    private void UpdateResources() {
552      try {
553        HiveAdminClient.Instance.Refresh();
554        Content = HiveAdminClient.Instance.Resources;
[16117]555      } catch (AnonymousUserException) {
556        ShowHiveInformationDialog();
[6976]557      }
[16117]558    }
559
560    private void RemoveResource(Resource resource) {
561      if (resource == null) return;
562
563      try {
564        if (resource.Id != Guid.Empty) {
565          SelectedResource = HiveAdminClient.Instance.GetAvailableResourceAncestors(resource.Id).LastOrDefault();
[16185]566
567          // deal with all new, but not yet saved resources
568          var newResources = Content.Where(x => x.ParentResourceId == resource.Id).ToList();
569          if (newResources.Any(x => x.Id != Guid.Empty)) return;
570          foreach (var nr in newResources) Content.Remove(nr);
571
[16430]572          HiveAdminClient.Delete(resource);
[16117]573          UpdateResources();
574        } else {
[16185]575          SelectedResource = Content.FirstOrDefault(x => x.Id == resource.ParentResourceId);
[16122]576          Content.Remove(resource);
[16117]577        }
578      } catch (AnonymousUserException) {
579        ShowHiveInformationDialog();
[6976]580      }
[16117]581    }
582
[16185]583    private void RemoveResource(IEnumerable<Resource> resources) {
584      if (resources == null || !resources.Any()) return;
585
[16430]586      var ids = resources.Select(x => x.Id).ToList();
[16185]587      try {
588        bool update = false;
[16430]589        foreach (var r in resources) {
590          if (r.Id != Guid.Empty) {
591            if (r.Id == SelectedResource.Id)
[16185]592              SelectedResource = HiveAdminClient.Instance.GetAvailableResourceAncestors(r.Id).LastOrDefault();
593
594            // deal with all new, but not yet saved resources
595            var newResources = Content.Where(x => x.ParentResourceId == r.Id).ToList();
596            if (newResources.Any(x => x.Id != Guid.Empty)) return;
597            foreach (var nr in newResources) Content.Remove(nr);
598
599            HiveAdminClient.Delete(r);
600            update = true;
601          } else {
602            if (r.Id == SelectedResource.Id)
603              SelectedResource = Content.FirstOrDefault(x => x.Id == r.ParentResourceId);
604            Content.Remove(r);
605          }
606        }
607        if (update) UpdateResources();
608      } catch (AnonymousUserException) {
609        ShowHiveInformationDialog();
610      }
611    }
612
[16117]613    private void UpdateSchedule() {
614      try {
615        HiveAdminClient.Instance.RefreshCalendar();
616      } catch (AnonymousUserException) {
[7256]617        ShowHiveInformationDialog();
[7249]618      }
[6976]619    }
620
[16117]621    private bool IsAdmin() {
622      return HiveRoles.CheckAdminUserPermissions();
623    }
624
625    private void StyleTreeNode(TreeNode n, Resource r, IEnumerable<Resource> resources) {
626      n.Text = r.Name;
627      n.BackColor = Color.Transparent;
628      n.ForeColor = Color.Black;
629
630      if (HiveAdminClient.Instance.DisabledParentResources.Select(x => x.Id).Contains(r.Id)) {
631        n.ForeColor = grayTextColor;
632      } else if (r.Id == Guid.Empty && n != ungroupedGroupNode /*!r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
633        // not stored (i.e. new)
634        n.Text += NOT_STORED_TAG;
635      } else if (r.Modified && n != ungroupedGroupNode /*!r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
636        // changed
637        n.Text += CHANGES_NOT_STORED_TAG;
638      }
639
640      // slave count
641      int childSlavesCount = 0;
642      if (r.Id != Guid.Empty && r is SlaveGroup) {
643        var descendants = GetResourceDescendants();
644        if (descendants.ContainsKey(r.Id)) {
645          childSlavesCount = resources
646            .OfType<Slave>()
647            .Where(x => descendants[r.Id].Select(y => y.Id)
648              .Contains(x.Id))
649            .Count();
650        }
651      } else if (n == ungroupedGroupNode /*|| r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
652        childSlavesCount = resources
653          .OfType<Slave>()
654          .Where(x => x.ParentResourceId == null
655            || (x.ParentResourceId.HasValue && x.ParentResourceId.Value == Guid.Empty))
656          .Count();
657      }
658      if (childSlavesCount > 0)
659        n.Text += " [" + childSlavesCount.ToString() + "]";
660
661      // slave image index, state, utilization
662      if (r is Slave) {
663        n.ImageIndex = slaveImageIndex;
664        var s = r as Slave;
665        if (s.SlaveState == SlaveState.Calculating) {
666          n.ForeColor = calculatingColor;
667          n.Text += " [" + s.CpuUtilization.ToString("N2") + "%]";
668        } else if (s.SlaveState == SlaveState.Offline) {
669          n.ForeColor = offlineColor;
670          if (s.LastHeartbeat.HasValue)
671            n.Text += " [" + (s.LastHeartbeat != null ? s.LastHeartbeat.Value.ToString("g") : null) + "]";
672        }
[7256]673      } else {
[16117]674        n.ImageIndex = slaveGroupImageIndex;
[7256]675      }
[16117]676
677      // ungrouped
678      if (n == ungroupedGroupNode /*r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
679        n.ForeColor = SystemColors.GrayText;
680      }
[7256]681    }
682
[16117]683    private void ResetTreeNodes(TreeNodeCollection nodes, IEnumerable<Resource> resources) {
684      foreach (TreeNode n in nodes) {
685        StyleTreeNode(n, (Resource)n.Tag, resources);
686        if (n.Nodes.Count > 0) {
687          ResetTreeNodes(n.Nodes, resources);
[7256]688        }
689      }
690    }
691
[16117]692    private async void ChangeSelectedResource(Resource resource) {
693      selectedResource = resource;
694      viewHost.Content = selectedResource;
[6976]695
[16117]696      HiveAdminClient.Instance.DowntimeForResourceId = selectedResource != null ? selectedResource.Id : Guid.Empty;
697      if (tabSlaveGroup.SelectedTab == tabSchedule) {
698        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
699          action: () => UpdateSchedule(),
700          finallyCallback: () => scheduleView.Content = HiveAdminClient.Instance.Downtimes);
701      }
[6976]702
[16117]703      SetEnabledStateOfControls();
[6976]704    }
705
[16117]706    private void ChangeSelectedResourceNode(TreeNode resourceNode) {
707      if (resourceNode == null) return;
708      SelectedResource = (Resource)resourceNode.Tag;
709      ResetTreeNodes(treeView.Nodes, Content);
710      resourceNode.BackColor = selectedBackColor;
711      resourceNode.ForeColor = selectedForeColor;
712      resourceNode.Text += SELECTED_TAG;
[8051]713    }
714
[16117]715    private void ShowHiveInformationDialog() {
716      if (InvokeRequired) Invoke((Action)ShowHiveInformationDialog);
717      else {
718        using (HiveInformationDialog dialog = new HiveInformationDialog()) {
719          dialog.ShowDialog(this);
720        }
721      }
[8051]722    }
723
[16117]724    private void ResetView() {
725      if (InvokeRequired) Invoke((Action)ResetView);
726      else {
727        treeView.Nodes.Clear();
[8051]728
[16117]729        if (viewHost.Content != null && viewHost.Content is SlaveGroup) {
730          ((SlaveGroup)viewHost.Content).PropertyChanged -= SlaveViewContent_PropertyChanged;
731        }
[6976]732
[16117]733        viewHost.Content = null;
734        if (scheduleView.Content != null) {
735          scheduleView.Content.Clear();
736        }
737
738        HiveAdminClient.Instance.ResetDowntime();
[6976]739      }
740    }
741
[6994]742
[16117]743    private Dictionary<Guid, HashSet<Resource>> GetResourceDescendants() {
744      var resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
[16185]745      //var resources = Content.Where(x => x.Id != Guid.Empty).Union(HiveAdminClient.Instance.DisabledParentResources).ToList();     
[16117]746      var resources = Content.Union(HiveAdminClient.Instance.DisabledParentResources).ToList();
747
748      foreach (var r in resources) {
[16430]749        if (!resourceDescendants.ContainsKey(r.Id))
[16185]750          resourceDescendants.Add(r.Id, new HashSet<Resource>());
751      }
752      foreach (var r in resources) {
[16117]753        var parentResourceId = r.ParentResourceId;
754        while (parentResourceId != null) {
755          var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
756          if (parent != null) {
757            resourceDescendants[parent.Id].Add(r);
758            parentResourceId = parent.ParentResourceId;
759          } else {
760            parentResourceId = null;
761          }
762        }
763      }
764      return resourceDescendants;
[6994]765    }
[8051]766
[16117]767    #endregion
[6976]768  }
769}
Note: See TracBrowser for help on using the repository browser.