Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 16147 was 16095, checked in by jkarder, 6 years ago

#2839: worked on hive project management

  • removed usage of null-conditional operator
File size: 27.4 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]";
[15953]45    private const string NOT_STORED_TAG = "*"; // " [not stored]";
[15813]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
[15995]53    private readonly Color grayTextColor = SystemColors.GrayText;
[15777]54
[15813]55
56
57    private TreeNode ungroupedGroupNode;
58
[15742]59    private Resource selectedResource = null;
[15777]60    public Resource SelectedResource {
61      get { return selectedResource; }
62      set { if (selectedResource != value) ChangeSelectedResource(value); }
63    }
[15742]64
[15401]65    private readonly object locker = new object();
66
[6976]67    public new IItemList<Resource> Content {
68      get { return (IItemList<Resource>)base.Content; }
69      set { base.Content = value; }
70    }
71
72    public ResourcesView() {
73      InitializeComponent();
74
[15422]75      treeView.ImageList.Images.Add(VSImageLibrary.MonitorLarge);
76      treeView.ImageList.Images.Add(VSImageLibrary.NetworkCenterLarge);
[8051]77
[15401]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
[15401]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);
[6976]91    }
92
[15401]93    protected override void RegisterContentEvents() {
94      base.RegisterContentEvents();
95      Content.ItemsAdded += Content_ItemsAdded;
96      Content.ItemsRemoved += Content_ItemsRemoved;
[6976]97    }
98
99    protected override void DeregisterContentEvents() {
[15401]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) {
[15422]108        treeView.Nodes.Clear();
109        viewHost.Content = null;
[8051]110        scheduleView.Content = null;
[6976]111      } else {
[15777]112        BuildResourceTree(Content);
[6976]113      }
114    }
115
116    protected override void SetEnabledStateOfControls() {
117      base.SetEnabledStateOfControls();
[15813]118
[16072]119      bool locked = Content == null || selectedResource == null || Locked || ReadOnly;
120      bool adminLocked = locked || !IsAdmin();
121      bool addLocked = adminLocked || selectedResource.Id == Guid.Empty || selectedResource is Slave;
122      bool deleteLocked = adminLocked || HiveAdminClient.Instance.ResourceDescendants[selectedResource.Id].Any();
[15813]123
124      btnAddGroup.Enabled = !addLocked;
[16072]125      btnRemoveGroup.Enabled = !deleteLocked;
[15813]126      btnSave.Enabled = !locked;
[16072]127      scheduleView.Locked = adminLocked;
[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;
[16064]210      if (!IsAdmin()) {
[15742]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;
[16064]217      } else if (selectedResource != null && selectedResource.Id == Guid.Empty) {
[15742]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      }
[16064]225
[16072]226      if (selectedResource != null && selectedResource is SlaveGroup) {
227        parentResourceId = selectedResource.Id;
228      } else {
229        MessageBox.Show(
230          "You cannot add a resource group to a slave.",
231          "HeuristicLab Hive Administrator",
232          MessageBoxButtons.OK,
233          MessageBoxIcon.Information);
234        return;
235      }
236
[15401]237      var group = new SlaveGroup {
238        Name = "New Group",
[15742]239        OwnerUserId = UserInformation.Instance.User.Id,
240        ParentResourceId = parentResourceId
[15401]241      };
[15742]242
[15922]243      //HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
[15777]244      SelectedResource = group;
[15401]245      Content.Add(group);
246    }
247
248    private async void btnRemoveGroup_Click(object sender, EventArgs e) {
[15742]249      if (selectedResource == null) return;
250
[15401]251      lock (locker) {
[15422]252        if (!btnRemoveGroup.Enabled) return;
253        btnRemoveGroup.Enabled = false;
[6976]254      }
[15401]255
[15742]256      if (!IsAdmin()) {
257        MessageBox.Show(
[16072]258          "You have no permission to delete resource groups.",
[15742]259          "HeuristicLab Hive Administrator",
260          MessageBoxButtons.OK,
261          MessageBoxIcon.Information);
262        return;
263      }
264
265      if (Content.Any(x => x.ParentResourceId == selectedResource.Id)) {
266        MessageBox.Show(
[16072]267          "Only empty resource groups can be deleted.",
[15742]268          "HeuristicLab Hive Administrator",
269          MessageBoxButtons.OK,
270          MessageBoxIcon.Error);
271        return;
272      }
273
274      var result = MessageBox.Show(
275        "Do you really want to delete " + selectedResource.Name + "?",
276        "HeuristicLab Hive Administrator",
277        MessageBoxButtons.YesNo,
278        MessageBoxIcon.Question);
279      if (result == DialogResult.Yes) {
280        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
[15792]281          action: () => {
282            RemoveResource(selectedResource);
283          },
[16064]284          finallyCallback: () => {
[15742]285            btnRemoveGroup.Enabled = true;
286          });
[16072]287      } else {
288        btnRemoveGroup.Enabled = true;
[16064]289      }
[6976]290    }
291
[15401]292    private async void btnSave_Click(object sender, EventArgs e) {
293      lock (locker) {
[15422]294        if (!btnSave.Enabled) return;
295        btnSave.Enabled = false;
[15401]296      }
297
298      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
299        action: () => {
300          var resourcesToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
301          foreach (var resource in resourcesToSave)
302            resource.Store();
[15742]303          UpdateResources();
[15401]304        },
[15422]305        finallyCallback: () => btnSave.Enabled = true);
[15742]306
307      OnContentChanged();
[15401]308    }
309
[15777]310    private void treeSlaveGroup_MouseDown(object sender, MouseEventArgs e) {
311      var node = treeView.GetNodeAt(e.Location);
[15995]312      if (node == null || node == ungroupedGroupNode) return;
313      var r = (Resource)node.Tag;
[16064]314      if (!HiveAdminClient.Instance.DisabledParentResources.Contains(r)) ChangeSelectedResourceNode(node);
[15742]315    }
316
[15777]317    private void treeSlaveGroup_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
318      e.Cancel = true;
[15401]319    }
320
[15813]321    private void treeSlaveGroup_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
[16064]322      if (e.Node == ungroupedGroupNode) {
[15813]323        e.Cancel = true;
[15995]324      } else {
325        var r = (Resource)e.Node.Tag;
[16064]326        if (HiveAdminClient.Instance.DisabledParentResources.Contains(r)) {
[15995]327          e.Cancel = true;
328        }
[15813]329      }
330    }
331
[6976]332    private void treeSlaveGroup_DragDrop(object sender, DragEventArgs e) {
[15767]333      if (e.Effect == DragDropEffects.None) return;
334
[15813]335      var targetNode = treeView.GetNodeAt(treeView.PointToClient(new Point(e.X, e.Y)));
[15742]336      var targetResource = (targetNode != null) ? (Resource)targetNode.Tag : null;
[15813]337      var resources = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IEnumerable<Resource>;
[6976]338
[16064]339      foreach (var r in resources) {
[16095]340        r.ParentResourceId = targetResource != null ? targetResource.Id : (Guid?)null;
[15422]341      }
[8051]342
[15922]343      // TODO
344      //HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
[15742]345      OnContentChanged();
[6976]346    }
347
348    private void treeSlaveGroup_ItemDrag(object sender, ItemDragEventArgs e) {
[15813]349      if (!IsAdmin()) return;
350
351      var nodes = GetCheckedNodes(treeView.Nodes).ToList();
[6976]352      TreeNode sourceNode = (TreeNode)e.Item;
[16064]353      if (!sourceNode.Checked) nodes.Add(sourceNode);
[15813]354      nodes.Remove(ungroupedGroupNode);
355      ungroupedGroupNode.Checked = false;
356      var resources = nodes.Select(x => x.Tag).OfType<Resource>().ToList();
357
[16064]358      if (resources.Count > 0) {
[15813]359        DataObject data = new DataObject();
360        data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, resources);
361        var action = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
[16064]362        if (action.HasFlag(DragDropEffects.Move)) {
[15813]363          foreach (var node in nodes) node.Remove();
364          StyleTreeNode(ungroupedGroupNode, (Resource)ungroupedGroupNode.Tag, resources);
365        }
366      }
[6976]367    }
368
[15813]369    private IEnumerable<TreeNode> GetCheckedNodes(TreeNodeCollection nodes) {
370      if (nodes != null) {
371        foreach (var node in nodes.OfType<TreeNode>()) {
372          if (node.Checked && node != ungroupedGroupNode) yield return node;
[16064]373          foreach (var child in GetCheckedNodes(node.Nodes))
374            yield return child;
375        }
[15813]376      }
377    }
378
[15767]379    private void treeSlaveGroup_DragEnterOver(object sender, DragEventArgs e) {
[6976]380      e.Effect = DragDropEffects.Move;
[15813]381      var resources = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IEnumerable<Resource>;
382      var targetNode = treeView.GetNodeAt(treeView.PointToClient(new Point(e.X, e.Y)));
[16095]383      var targetResource = (targetNode != null ? targetNode.Tag : null) as Resource;
[6976]384
[16064]385      if (!IsAdmin()
[15813]386        || resources == null
387        || !resources.Any()
388        || resources.Any(x => !HiveAdminClient.Instance.CheckParentChange(x, targetResource))
389        || (targetNode != null && (targetNode == ungroupedGroupNode || targetNode.Parent == ungroupedGroupNode))) {
[15767]390        e.Effect = DragDropEffects.None;
391      }
[6976]392    }
393
[15813]394    private void TabSlaveGroup_TabIndexChanged(object sender, EventArgs e) {
395      throw new NotImplementedException();
[6976]396    }
[15813]397
398    private async void TabSlaveGroup_Selected(object sender, System.Windows.Forms.TabControlEventArgs e) {
[16064]399      if (e.TabPage == tabSchedule) {
[15813]400        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
401          action: () => UpdateSchedule(),
402          finallyCallback: () => scheduleView.Content = HiveAdminClient.Instance.Downtimes);
403      }
404      SetEnabledStateOfControls();
405    }
[15401]406    #endregion
407
408    #region Helpers
[15777]409    private void BuildResourceTree(IEnumerable<Resource> resources) {
[15422]410      treeView.Nodes.Clear();
[15777]411      if (!resources.Any()) return;
[15422]412
[15995]413      var disabledParentResources = HiveAdminClient.Instance.DisabledParentResources;
[15742]414      var mainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
415        .Where(x => x.ParentResourceId == null));
[15995]416      //var parentedMainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
417      //  .Where(x => x.ParentResourceId.HasValue && !resources.Select(y => y.Id).Contains(x.ParentResourceId.Value)));
418      //mainResources.UnionWith(parentedMainResources);
419      var mainDisabledParentResources = new HashSet<Resource>(disabledParentResources.Where(x => x.ParentResourceId == null || x.ParentResourceId == Guid.Empty));
420      mainResources.UnionWith(mainDisabledParentResources);
421      var subResources = new HashSet<Resource>(resources.Union(disabledParentResources).Except(mainResources).OrderByDescending(x => x.Name));
[15422]422
[15557]423      var stack = new Stack<Resource>(mainResources.OrderByDescending(x => x.Name));
[15777]424      if (selectedResource != null) SelectedResource = resources.Where(x => x.Id == selectedResource.Id).FirstOrDefault();
[15760]425      bool nodeSelected = false;
[15422]426
427      TreeNode currentNode = null;
428      Resource currentResource = null;
429
[15792]430      while (stack.Any()) {
[15422]431        var newResource = stack.Pop();
432        var newNode = new TreeNode(newResource.Name) { Tag = newResource };
[15792]433        StyleTreeNode(newNode, newResource, resources);
[15422]434
[15995]435        if (selectedResource == null && !disabledParentResources.Contains(newResource)) {
[15777]436          SelectedResource = newResource;
[15742]437        }
[15995]438        if (!nodeSelected && selectedResource != null && newResource.Id == selectedResource.Id) {
[15813]439          newNode.BackColor = selectedBackColor;
440          newNode.ForeColor = selectedForeColor;
441          newNode.Text += SELECTED_TAG;
[15760]442          nodeSelected = true;
[15742]443        }
444
[16064]445        if (disabledParentResources.Contains(newResource)) {
[15995]446          newNode.Checked = false;
447          newNode.ForeColor = grayTextColor;
448        }
449
[15557]450        // search for parent node of newNode and save in currentNode
451        // necessary since newNodes (stack top items) might be siblings
452        // or grand..grandparents of previous node (currentNode)
[15742]453        while (currentNode != null && newResource.ParentResourceId != currentResource.Id) {
[15422]454          currentNode = currentNode.Parent;
455          currentResource = currentNode == null ? null : (Resource)currentNode.Tag;
[15401]456        }
457
[15792]458        if (currentNode == null) {
[15422]459          treeView.Nodes.Add(newNode);
460        } else {
461          currentNode.Nodes.Add(newNode);
462        }
463
[15792]464        if (newResource is SlaveGroup) {
[15557]465          var childResources = subResources.Where(x => x.ParentResourceId == newResource.Id);
[15792]466          if (childResources.Any()) {
467            foreach (var resource in childResources.OrderByDescending(x => x.Name)) {
[15557]468              subResources.Remove(resource);
469              stack.Push(resource);
[15422]470            }
471            currentNode = newNode;
472            currentResource = newResource;
473          }
474        }
475        newNode.SelectedImageIndex = newNode.ImageIndex;
[15401]476      }
[15422]477
[15813]478      // collapse slave-only nodes
[16064]479      foreach (TreeNode n in treeView.Nodes) {
[15813]480        CollapseSlaveOnlyNodes(n);
481      }
[16064]482
[15813]483      ungroupedGroupNode = new TreeNode(UNGROUPED_GROUP_NAME) {
[15422]484        ForeColor = SystemColors.GrayText,
485        Tag = new SlaveGroup() {
[15813]486          Name = UNGROUPED_GROUP_NAME,
487          Description = UNGROUPED_GROUP_DESCRIPTION
[15422]488        }
489      };
490
[15557]491      foreach (var slave in subResources.OfType<Slave>().OrderBy(x => x.Name)) {
[15422]492        var slaveNode = new TreeNode(slave.Name) { Tag = slave };
[15792]493        StyleTreeNode(slaveNode, slave, resources);
[15813]494        ungroupedGroupNode.Nodes.Add(slaveNode);
[15792]495        if (selectedResource == null) {
[15777]496          SelectedResource = slave;
[15742]497        }
[15792]498
[15760]499        if (slave.Id == selectedResource.Id && !nodeSelected) {
[15813]500          slaveNode.BackColor = selectedBackColor;
501          slaveNode.ForeColor = selectedForeColor;
502          slaveNode.Text += SELECTED_TAG;
[15760]503          nodeSelected = true;
[15742]504        }
[15422]505      }
506
[15813]507      if (ungroupedGroupNode.Nodes.Count > 0) {
508        ungroupedGroupNode.Text += " [" + ungroupedGroupNode.Nodes.Count.ToString() + "]";
509        ungroupedGroupNode.Expand();
510      }
[16064]511      treeView.Nodes.Add(ungroupedGroupNode);
[15401]512    }
513
[15813]514    private void CollapseSlaveOnlyNodes(TreeNode tn) {
515      Resource r = (Resource)tn.Tag;
[15922]516      var descendants = GetResourceDescendants();
[16064]517      if (descendants.ContainsKey(r.Id)) {
518        if (descendants[r.Id].OfType<SlaveGroup>().Any()) {
[15813]519          tn.Expand();
520          foreach (TreeNode n in tn.Nodes) CollapseSlaveOnlyNodes(n);
521        } else {
522          tn.Collapse();
523        }
524      }
525    }
526
[15922]527    private void ExpandResourceNodesOfInterest(TreeNodeCollection nodes) {
528      foreach (TreeNode n in nodes) {
529        Resource r = (Resource)n.Tag;
530        if (n.Nodes.Count > 0) {
[15995]531          if (HiveAdminClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()) {
[15922]532            n.Expand();
533            ExpandResourceNodesOfInterest(n.Nodes);
534          } else {
535            n.Collapse();
536          }
537        } else {
538          n.Collapse();
539        }
540      }
541    }
542
[15401]543    private void UpdateChildHbIntervall(Resource resource) {
544      foreach (Resource r in Content.Where(x => x.ParentResourceId == resource.Id)) {
545        r.HbInterval = resource.HbInterval;
546        if (r is SlaveGroup) {
547          UpdateChildHbIntervall(r);
548        }
549      }
550    }
551
[6976]552    private void UpdateResources() {
[15742]553      try {
554        HiveAdminClient.Instance.Refresh();
555        Content = HiveAdminClient.Instance.Resources;
[16064]556      } catch (AnonymousUserException) {
[15742]557        ShowHiveInformationDialog();
558      }
[6976]559    }
560
[15742]561    private void RemoveResource(Resource resource) {
[15777]562      if (resource == null) return;
[7256]563
[15742]564      try {
[15792]565        if (resource.Id != Guid.Empty) {
566          var resourcesToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
567          foreach (var r in resourcesToSave)
568            r.Store();
[16072]569
570          SelectedResource = HiveAdminClient.Instance.GetAvailableResourceAncestors(resource.Id).LastOrDefault();
[15792]571          HiveAdminClient.Delete(resource);
572          UpdateResources();
573        } else {
574          Content.Remove(selectedResource);
575        }
[16064]576      } catch (AnonymousUserException) {
[15742]577        ShowHiveInformationDialog();
[7256]578      }
579    }
580
[6976]581    private void UpdateSchedule() {
[15412]582      try {
583        HiveAdminClient.Instance.RefreshCalendar();
584      } catch (AnonymousUserException) {
585        ShowHiveInformationDialog();
[15401]586      }
[8051]587    }
588
[15742]589    private bool IsAdmin() {
590      return HiveRoles.CheckAdminUserPermissions();
591    }
592
[15792]593    private void StyleTreeNode(TreeNode n, Resource r, IEnumerable<Resource> resources) {
594      n.Text = r.Name;
595      n.BackColor = Color.Transparent;
596      n.ForeColor = Color.Black;
597
[16064]598      if (HiveAdminClient.Instance.DisabledParentResources.Select(x => x.Id).Contains(r.Id)) {
[15995]599        n.ForeColor = grayTextColor;
600      } else if (r.Id == Guid.Empty && n != ungroupedGroupNode /*!r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
601        // not stored (i.e. new)
[15813]602        n.Text += NOT_STORED_TAG;
603      } else if (r.Modified && n != ungroupedGroupNode /*!r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
[15995]604        // changed
[15813]605        n.Text += CHANGES_NOT_STORED_TAG;
606      }
607
[15792]608      // slave count
609      int childSlavesCount = 0;
610      if (r.Id != Guid.Empty && r is SlaveGroup) {
[15922]611        var descendants = GetResourceDescendants();
[15792]612        if (descendants.ContainsKey(r.Id)) {
613          childSlavesCount = resources
614            .OfType<Slave>()
615            .Where(x => descendants[r.Id].Select(y => y.Id)
[15922]616              .Contains(x.Id))
[15792]617            .Count();
618        }
[16064]619      } else if (n == ungroupedGroupNode /*|| r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
[15792]620        childSlavesCount = resources
621          .OfType<Slave>()
[16064]622          .Where(x => x.ParentResourceId == null
[15792]623            || (x.ParentResourceId.HasValue && x.ParentResourceId.Value == Guid.Empty))
624          .Count();
625      }
626      if (childSlavesCount > 0)
627        n.Text += " [" + childSlavesCount.ToString() + "]";
628
629      // slave image index, state, utilization
630      if (r is Slave) {
631        n.ImageIndex = slaveImageIndex;
632        var s = r as Slave;
633        if (s.SlaveState == SlaveState.Calculating) {
634          n.ForeColor = calculatingColor;
635          n.Text += " [" + s.CpuUtilization.ToString("N2") + "%]";
636        } else if (s.SlaveState == SlaveState.Offline) {
637          n.ForeColor = offlineColor;
638          if (s.LastHeartbeat.HasValue)
[16095]639            n.Text += " [" + (s.LastHeartbeat != null ? s.LastHeartbeat.Value.ToString("g") : null) + "]";
[15792]640        }
641      } else {
642        n.ImageIndex = slaveGroupImageIndex;
643      }
644
645      // ungrouped
[16064]646      if (n == ungroupedGroupNode /*r.Name.StartsWith(UNGROUPED_GROUP_NAME)*/) {
647        n.ForeColor = SystemColors.GrayText;
[15792]648      }
649    }
650
651    private void ResetTreeNodes(TreeNodeCollection nodes, IEnumerable<Resource> resources) {
652      foreach (TreeNode n in nodes) {
653        StyleTreeNode(n, (Resource)n.Tag, resources);
654        if (n.Nodes.Count > 0) {
655          ResetTreeNodes(n.Nodes, resources);
656        }
657      }
658    }
659
[15777]660    private async void ChangeSelectedResource(Resource resource) {
661      selectedResource = resource;
662      viewHost.Content = selectedResource;
[15813]663
[15777]664      HiveAdminClient.Instance.DowntimeForResourceId = selectedResource != null ? selectedResource.Id : Guid.Empty;
[15813]665      if (tabSlaveGroup.SelectedTab == tabSchedule) {
666        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
667          action: () => UpdateSchedule(),
668          finallyCallback: () => scheduleView.Content = HiveAdminClient.Instance.Downtimes);
669      }
[15777]670
[15813]671      SetEnabledStateOfControls();
[15777]672    }
673
[15742]674    private void ChangeSelectedResourceNode(TreeNode resourceNode) {
[15777]675      if (resourceNode == null) return;
676      SelectedResource = (Resource)resourceNode.Tag;
[15792]677      ResetTreeNodes(treeView.Nodes, Content);
[15813]678      resourceNode.BackColor = selectedBackColor;
679      resourceNode.ForeColor = selectedForeColor;
680      resourceNode.Text += SELECTED_TAG;
[15742]681    }
682
[15401]683    private void ShowHiveInformationDialog() {
684      if (InvokeRequired) Invoke((Action)ShowHiveInformationDialog);
685      else {
686        using (HiveInformationDialog dialog = new HiveInformationDialog()) {
687          dialog.ShowDialog(this);
688        }
[6976]689      }
690    }
[15792]691
692    private void ResetView() {
693      if (InvokeRequired) Invoke((Action)ResetView);
694      else {
695        treeView.Nodes.Clear();
696
697        if (viewHost.Content != null && viewHost.Content is SlaveGroup) {
698          ((SlaveGroup)viewHost.Content).PropertyChanged -= SlaveViewContent_PropertyChanged;
699        }
700
701        viewHost.Content = null;
702        if (scheduleView.Content != null) {
703          scheduleView.Content.Clear();
704        }
705
706        HiveAdminClient.Instance.ResetDowntime();
707      }
708    }
709
[15922]710
711    private Dictionary<Guid, HashSet<Resource>> GetResourceDescendants() {
712      var resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
[15995]713      var resources = Content.Union(HiveAdminClient.Instance.DisabledParentResources).ToList();
[15922]714
[15995]715      foreach (var r in resources) resourceDescendants.Add(r.Id, new HashSet<Resource>());
[16064]716      foreach (var r in resources) {
[15922]717        var parentResourceId = r.ParentResourceId;
[16064]718        while (parentResourceId != null) {
[15995]719          var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
[16064]720          if (parent != null) {
[15922]721            resourceDescendants[parent.Id].Add(r);
722            parentResourceId = parent.ParentResourceId;
723          } else {
724            parentResourceId = null;
725          }
726        }
727      }
728      return resourceDescendants;
729    }
[16064]730
[15401]731    #endregion
[6976]732  }
733}
Note: See TracBrowser for help on using the repository browser.