#region License Information
/* HeuristicLab
* Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using HeuristicLab.Clients.Hive.Views;
using HeuristicLab.Core;
using HeuristicLab.Core.Views;
using HeuristicLab.MainForm;
namespace HeuristicLab.Clients.Hive.Administrator.Views {
[View("ResourcesView")]
[Content(typeof(IItemList), IsDefaultView = true)]
public partial class ResourcesView : ItemView {
public new IItemList Content {
get { return (IItemList)base.Content; }
set { base.Content = value; }
}
private const string ungroupedGroupName = "UNGROUPED";
private const int slaveImageIndex = 0;
private const int slaveGroupImageIndex = 1;
public ResourcesView() {
InitializeComponent();
treeSlaveGroup.ImageList.Images.Add(HiveImageLibrary.Slave);
treeSlaveGroup.ImageList.Images.Add(HiveImageLibrary.SlaveGroup);
updateScheduleControl.UpdateAction = new Action(UpdateSchedule);
updateSlaveGroup.UpdateAction = new Action(UpdateSlaveGroups);
}
#region Register Content Events
protected override void DeregisterContentEvents() {
Content.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler>(Content_ItemsAdded);
Content.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler>(Content_ItemsRemoved);
base.DeregisterContentEvents();
}
protected override void RegisterContentEvents() {
base.RegisterContentEvents();
Content.ItemsAdded += new Collections.CollectionItemsChangedEventHandler>(Content_ItemsAdded);
Content.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler>(Content_ItemsRemoved);
}
#endregion
protected override void OnContentChanged() {
base.OnContentChanged();
if (Content == null) {
slaveView.Content = null;
treeSlaveGroup.Nodes.Clear();
} else {
treeSlaveGroup.Nodes.Clear();
//rebuild
TreeNode ungrp = new TreeNode(ungroupedGroupName);
ungrp.ImageIndex = slaveGroupImageIndex;
ungrp.SelectedImageIndex = ungrp.ImageIndex;
var newGroup = new SlaveGroup();
newGroup.Name = ungroupedGroupName;
newGroup.Id = Guid.NewGuid();
newGroup.Description = "Contains slaves which are in no group";
ungrp.Tag = newGroup;
foreach (Resource g in Content) {
if (g.GetType() == typeof(SlaveGroup)) {
//root node
if (g.ParentResourceId == null) {
TreeNode tn = new TreeNode();
tn.ImageIndex = slaveGroupImageIndex;
tn.SelectedImageIndex = tn.ImageIndex;
tn.Tag = g;
tn.Text = g.Name;
BuildSlaveGroupTree(g, tn);
tn.ExpandAll();
treeSlaveGroup.Nodes.Add(tn);
}
} else if (g.GetType() == typeof(Slave)) {
if (g.ParentResourceId == null) {
var stn = new TreeNode(g.Name);
stn.ImageIndex = slaveImageIndex;
stn.SelectedImageIndex = stn.ImageIndex;
stn.Tag = g;
ungrp.Nodes.Add(stn);
}
}
}
ungrp.ExpandAll();
treeSlaveGroup.Nodes.Add(ungrp);
}
}
private void BuildSlaveGroupTree(Resource g, TreeNode tn) {
foreach (Resource r in Content.Where(s => s.ParentResourceId != null && s.ParentResourceId == g.Id)) {
TreeNode stn = new TreeNode(r.Name);
if (r is Slave) {
stn.ImageIndex = slaveImageIndex;
} else if (r is SlaveGroup) {
stn.ImageIndex = slaveGroupImageIndex;
}
stn.SelectedImageIndex = stn.ImageIndex;
stn.Tag = r;
tn.Nodes.Add(stn);
BuildSlaveGroupTree(r, stn);
tn.ExpandAll();
}
}
protected override void SetEnabledStateOfControls() {
base.SetEnabledStateOfControls();
// TODO: Put code here to enable or disable controls based on whether the Content is/not null or the view is ReadOnly
}
private void treeSlaveGroup_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
if (slaveView.Content != null && slaveView.Content is SlaveGroup) {
slaveView.Content.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(SlaveViewContent_PropertyChanged);
}
slaveView.Content = (Resource)e.Node.Tag;
scheduleView.ResourceId = ((Resource)e.Node.Tag).Id;
if (e.Node.Tag is SlaveGroup) {
slaveView.Content.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(SlaveViewContent_PropertyChanged);
}
if (tabSlaveGroup.SelectedIndex == 1) {
UpdateSchedule();
}
}
void SlaveViewContent_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) {
OnContentChanged();
}
private void btnAddGroup_Click(object sender, EventArgs e) {
SlaveGroup newGroup = new SlaveGroup();
newGroup.Name = "New Group";
Content.Add(newGroup);
}
void Content_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs> e) {
OnContentChanged();
}
void Content_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs> e) {
OnContentChanged();
}
private void btnRemoveGroup_Click(object sender, EventArgs e) {
if (treeSlaveGroup.SelectedNode != null && treeSlaveGroup.SelectedNode.Tag != null) {
Resource res = (Resource)treeSlaveGroup.SelectedNode.Tag;
DialogResult diagRes = MessageBox.Show("Do you really want to delete " + res.Name + "?", "HeuristicLab Hive Administration", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (diagRes == DialogResult.Yes) {
if (res is Slave) {
Content.Remove(res);
ServiceLocator.Instance.CallHiveService(service => service.DeleteSlave(res.Id));
} else if (res is SlaveGroup) {
//only delete empty groups
if (Content.Where(s => s.ParentResourceId == res.Id).Count() < 1) {
Content.Remove(res);
ServiceLocator.Instance.CallHiveService(service => service.DeleteSlaveGroup(res.Id));
} else {
MessageBox.Show("Only empty groups can be deleted.", "HeuristicLab Hive Administration", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}
private void btnSave_Click(object sender, EventArgs e) {
foreach (Resource res in Content) {
if (res is SlaveGroup && res.Id == Guid.Empty) {
SlaveGroup slaveGroup = (SlaveGroup)res;
ServiceLocator.Instance.CallHiveService(service => slaveGroup.Id = service.AddSlaveGroup(slaveGroup));
}
if (res.Id != Guid.Empty && res.Modified) {
if (res is SlaveGroup) {
ServiceLocator.Instance.CallHiveService(service => service.UpdateSlaveGroup((SlaveGroup)res));
} else if (res is Slave) {
ServiceLocator.Instance.CallHiveService(service => service.UpdateSlave((Slave)res));
}
}
}
}
private void treeSlaveGroup_DragDrop(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false)) {
Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
TreeNode destNode = ((TreeView)sender).GetNodeAt(pt);
TreeNode newNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
if (destNode.TreeView == newNode.TreeView) {
if (destNode.Text == ungroupedGroupName || (destNode.Parent != null && destNode.Parent.Text == ungroupedGroupName)) {
MessageBox.Show(String.Format("You can't drag items to the {0} group.{1}This group only contains slaves which haven't yet been assigned to a real group.",
ungroupedGroupName, Environment.NewLine), "HeuristicLab Hive Administration", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
SlaveGroup sgrp = null;
TreeNode parentNode = null;
if (destNode.Tag != null && destNode.Tag is SlaveGroup) {
sgrp = (SlaveGroup)destNode.Tag;
parentNode = destNode;
} else if (destNode.Parent != null && destNode.Parent.Tag is SlaveGroup) {
sgrp = (SlaveGroup)destNode.Parent.Tag;
parentNode = destNode.Parent;
}
if (newNode.Tag is SlaveGroup && CheckParentsEqualsMovedNode(parentNode, newNode)) {
return;
}
if (sgrp != null && newNode.Tag != null) {
//save parent group to get an id
if (sgrp.Id == Guid.Empty) {
ServiceLocator.Instance.CallHiveService(service => sgrp.Id = service.AddSlaveGroup(sgrp));
}
if (newNode.Tag is Slave) {
Slave slave = (Slave)newNode.Tag;
if (slave.ParentResourceId == null || (slave.ParentResourceId != null && slave.ParentResourceId != sgrp.Id)) {
slave.ParentResourceId = sgrp.Id;
newNode.Remove();
parentNode.Nodes.Clear();
BuildSlaveGroupTree(sgrp, parentNode);
}
} else if (newNode.Tag is SlaveGroup) {
SlaveGroup slaveGroup = (SlaveGroup)newNode.Tag;
if (slaveGroup.ParentResourceId == null || (slaveGroup.ParentResourceId != null && slaveGroup.ParentResourceId != sgrp.Id)) {
slaveGroup.ParentResourceId = sgrp.Id;
newNode.Remove();
parentNode.Nodes.Clear();
BuildSlaveGroupTree(sgrp, parentNode);
}
}
}
}
}
}
private bool CheckParentsEqualsMovedNode(TreeNode dest, TreeNode movedNode) {
TreeNode tmp = dest;
while (tmp != null) {
if (tmp == movedNode) {
return true;
}
tmp = tmp.Parent;
}
return false;
}
private void treeSlaveGroup_ItemDrag(object sender, ItemDragEventArgs e) {
TreeNode sourceNode = (TreeNode)e.Item;
DoDragDrop(sourceNode, DragDropEffects.All);
}
private void treeSlaveGroup_DragEnter(object sender, DragEventArgs e) {
e.Effect = DragDropEffects.Move;
}
private void treeSlaveGroup_DragOver(object sender, DragEventArgs e) {
e.Effect = DragDropEffects.Move;
}
private void treeSlaveGroup_QueryContinueDrag(object sender, QueryContinueDragEventArgs e) {
e.Action = DragAction.Continue;
}
void ResetView() {
treeSlaveGroup.Nodes.Clear();
if (slaveView.Content != null && slaveView.Content is SlaveGroup) {
slaveView.Content.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(SlaveViewContent_PropertyChanged);
}
slaveView.Content = null;
scheduleView.ResourceId = Guid.Empty;
}
private void UpdateSlaveGroups() {
this.Invoke(new Action(ResetView));
Content.Clear();
IItemList resources = new ItemList();
ServiceLocator.Instance.CallHiveService(service => {
service.GetSlaveGroups().ForEach(g => resources.Add(g));
service.GetSlaves().ForEach(s => resources.Add(s));
});
Content = resources;
}
private void UpdateSchedule() {
Guid resourceId = scheduleView.ResourceId;
if (resourceId != null) {
ServiceLocator.Instance.CallHiveService(service => {
var appointments = service.GetDowntimesForResource(resourceId);
ItemList ias = new ItemList();
appointments.ForEach(a => ias.Add(a));
scheduleView.Invoke(new Action(() => scheduleView.Content = ias));
});
}
}
private void tabSlaveGroup_SelectedIndexChanged(object sender, EventArgs e) {
if (tabSlaveGroup.SelectedIndex == 1) {
UpdateSchedule();
}
}
}
}