Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs @ 15813

Last change on this file since 15813 was 15813, checked in by jzenisek, 6 years ago

#2839: improved HiveAdmin interactions:

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