Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/04/19 14:28:13 (5 years ago)
Author:
mkommend
Message:

#2839: Merged 16117, 16122, 16173, 16184, 16185, 16186, 16187, 16202, 16203, 16204, 16205, 16208, 16211, 16209, 16211, 16219, 16257, 16247 into stable.

Location:
stable
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.Clients.Hive.JobManager

    • Property svn:mergeinfo set to (toggle deleted branches)
      /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.JobManagermergedeligible
      /trunk/HeuristicLab.Clients.Hive.JobManagermergedeligible
      /branches/1721-RandomForestPersistence/HeuristicLab.Clients.Hive.JobManager10321-10322
      /branches/2916_IndexedDataTableSerialization/HeuristicLab.Clients.Hive.JobManager15918
      /branches/2947_ConfigurableIndexedDataTable/HeuristicLab.Clients.Hive.JobManager16148-16526
      /branches/2972_PDPRowSelect/HeuristicLab.Clients.Hive.JobManager16444-16518
      /branches/Algorithms.GradientDescent/HeuristicLab.Clients.Hive.JobManager5516-5520
      /branches/Async/HeuristicLab.Clients.Hive.JobManager13329-15286
      /branches/Benchmarking/sources/HeuristicLab.Clients.Hive.JobManager6917-7005
      /branches/CloningRefactoring/HeuristicLab.Clients.Hive.JobManager4656-4721
      /branches/CodeEditor/HeuristicLab.Clients.Hive.JobManager11700-11806
      /branches/DataAnalysis Refactoring/HeuristicLab.Clients.Hive.JobManager5471-5808
      /branches/DataAnalysis SolutionEnsembles/HeuristicLab.Clients.Hive.JobManager5815-6180
      /branches/DataAnalysis/HeuristicLab.Clients.Hive.JobManager4458-4459,​4462,​4464
      /branches/DataPreprocessing/HeuristicLab.Clients.Hive.JobManager10085-11101
      /branches/GP.Grammar.Editor/HeuristicLab.Clients.Hive.JobManager6284-6795
      /branches/GP.Symbols (TimeLag, Diff, Integral)/HeuristicLab.Clients.Hive.JobManager5060
      /branches/HLScript/HeuristicLab.Clients.Hive.JobManager10331-10358
      /branches/HeuristicLab.DatasetRefactor/sources/HeuristicLab.Clients.Hive.JobManager11570-12508
      /branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Clients.Hive.JobManager6123-9799
      /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Clients.Hive.JobManager11130-12721
      /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.JobManager15377-15760
      /branches/HiveStatistics/sources/HeuristicLab.Clients.Hive.JobManager12440-12877
      /branches/LogResidualEvaluator/HeuristicLab.Clients.Hive.JobManager10202-10483
      /branches/NET40/sources/HeuristicLab.Clients.Hive.JobManager5138-5162
      /branches/NSGA-II Changes/HeuristicLab.Clients.Hive.JobManager12033-12122
      /branches/ParallelEngine/HeuristicLab.Clients.Hive.JobManager5175-5192
      /branches/ProblemInstancesRegressionAndClassification/HeuristicLab.Clients.Hive.JobManager7568-7810
      /branches/QAPAlgorithms/HeuristicLab.Clients.Hive.JobManager6350-6627
      /branches/Restructure trunk solution/HeuristicLab.Clients.Hive.JobManager6828
      /branches/RuntimeOptimizer/HeuristicLab.Clients.Hive.JobManager8943-9078
      /branches/ScatterSearch (trunk integration)/HeuristicLab.Clients.Hive.JobManager7787-8333
      /branches/SlaveShutdown/HeuristicLab.Clients.Hive.JobManager8944-8956
      /branches/SpectralKernelForGaussianProcesses/HeuristicLab.Clients.Hive.JobManager10204-10479
      /branches/SuccessProgressAnalysis/HeuristicLab.Clients.Hive.JobManager5370-5682
      /branches/Trunk/HeuristicLab.Clients.Hive.JobManager6829-6865
      /branches/UnloadJobs/HeuristicLab.Clients.Hive.JobManager9168-9215
      /branches/VNS/HeuristicLab.Clients.Hive.JobManager5594-5752
      /branches/crossvalidation-2434/HeuristicLab.Clients.Hive.JobManager12948-12950
      /branches/histogram/HeuristicLab.Clients.Hive.JobManager5959-6341
      /branches/symbreg-factors-2650/HeuristicLab.Clients.Hive.JobManager14232-14825
      /trunk/sources/HeuristicLab.Clients.Hive.JobManager9493,​9496,​9498,​9504-9506,​9515-9517,​9520-9521,​9523,​9530-9531,​9534-9537,​9540,​9542-9544,​9552-9555,​9568-9569,​9587,​9590-9592,​9600,​9607-9608,​9610-9611,​9613,​9618,​9623-9624,​9626,​9647-9649,​9652,​9657-9660,​9664-9666,​9675,​9692,​9695,​9699,​9702,​9710,​9714,​9718-9720,​9740-9741,​9751-9752,​9755,​9762,​9764-9775,​9777-9778,​9782-9786,​9792,​9794-9795,​9803-9812,​9816-9822,​9824-9825,​9828,​9830,​9833,​9837-9841,​9845,​9848-9851,​9855,​9859-9860,​9863,​9865-9868,​9871,​9893-9897,​9900-9902,​9905-9907,​9910,​9915-9916,​9919-9921,​9928,​9930,​9934-9935,​9938-9941,​9944,​9946,​9949,​9955-9956,​9958-9959,​9964-9965,​9973-9975,​9978,​9980-9982,​9988-9989,​9991-9992,​9994-9995,​9997,​10000-10005,​10009-10010,​10015,​10130,​10149-10150,​10154,​10170-10171,​10173-10176,​10195-10196,​10212-10213,​10231,​10261,​10273,​10291-10292,​10295,​10298,​10323-10324,​10346,​10348,​10355,​10359-10360,​10362-10363,​10365-10366,​10368,​10375,​10378,​10391,​10401,​10406-10407,​10414,​10417-10418,​10428,​10432-10433,​10435,​10440,​10448,​10453,​10460,​10465-10466,​10469-10470,​10472,​10474-10477,​10480,​10484,​10486,​10488-10500,​10503-10504,​10506,​10510-10512,​10519-10523,​10526,​10531,​10540-10541,​10543,​10545,​10561-10566,​10575-10578,​10596-10597,​10599,​10601-10607,​10639,​10642-10643,​10646,​10651-10653,​10727,​10731,​10745,​10747,​10761,​10767,​10774,​10787-10791,​10793-10794,​10796,​10799-10800,​10826,​10857-10862,​10865,​10885,​10889,​10894-10896,​10924,​10926-10927,​10937,​10941,​10953,​10955-10956,​10958-10961,​10963,​10975,​10983-10986,​10988-10989,​10996,​11007-11008,​11012-11014,​11019,​11024-11027,​11031,​11034-11035,​11048,​11050-11052,​11056-11058,​11060,​11065-11067,​11071,​11074-11082,​11086-11088,​11091-11093,​11095-11097,​11099-11100,​11102,​11108,​11111-11117,​11123-11128,​11131,​11135,​11153,​11156,​11161,​11214,​11241,​11243,​11248-11251,​11256,​11263,​11274,​11280,​11282-11283,​11285-11287,​11290,​11292,​11294-11296,​11298,​11300,​11302,​11306,​11308-11309,​11313,​11315,​11317,​11324,​11326,​11330-11332,​11337-11348,​11352-11353,​11361-11362,​11364-11367,​11380-11382,​11384,​11389,​11391-11392,​11394,​11403-11404,​11410-11411,​11417-11420,​11422,​11426-11430,​11432,​11434-11437,​11439-11448,​11450,​11453,​11455-11457,​11464,​11466-11467,​11469-11472,​11474,​11477-11480,​11483,​11494-11498,​11504,​11514-11515,​11523-11525,​11532-11533,​11536,​11540-11542,​11544-11545,​11547-11549,​11555,​11557,​11581,​11592,​11596-11597,​11599-11600,​11605,​11608,​11610,​11615-11616,​11618,​11623,​11631,​11634,​11650-11652,​11657,​11675,​11679-11680,​11703-11706,​11715,​11717,​11721,​11723-11725,​11734-11736,​11756-11758,​11762-11764,​11766,​11771-11772,​11781-11782,​11784,​11787-11790,​11794,​11807-11811,​11815-11816,​11818-11819,​11822,​11825-11831,​11833-11837,​11839-11840,​11853-11854,​11856,​11877-11879,​11882,​11890,​11909,​11912-11918,​11921,​11930,​11933-11934,​11936,​11938-11939,​11942,​11945,​11948,​11950-11951,​11955-11956,​11958-11961,​11963,​11967,​11970-11971,​11978,​11982-11984,​11987-11994,​11996,​11998-12004,​12015-12744,​12755,​12770,​12772,​12787,​12790-12798,​12801,​12807,​12810-12812,​12816-12819,​12835-12837,​12839,​12844-12846,​12851,​12855,​12868,​12873,​12875,​12878-12879,​12883,​12885-12886,​12889,​12894-12907,​12911-12918,​12920-12921,​12925-12927,​12932,​12934,​12936-12938,​12940,​12946-12948,​12953-12954,​12959-12961,​12971-12973,​12975-12978,​12981-12983,​12986-12987,​13000-13005,​13008,​13014,​13016,​13024-13027,​13030,​13033-13034,​13036,​13038-13040,​13051,​13054-13060,​13064-13066,​13078,​13080,​13087,​13093-13094,​13100-13104,​13109,​13116,​13118-13121,​13131,​13133,​13136-13143,​13154,​13157-13160,​13162-13165,​13167-13169,​13173,​13180-13181,​13183,​13186,​13198,​13200-13201,​13203-13205,​13209-13210,​13212,​13214,​13217-13219,​13222-13228,​13230-13239,​13241-13245,​13247-13257,​13260-13261,​13266-13271,​13288,​13300,​13307-13309,​13311,​13313-13315,​13318,​13392-13393,​13395,​13402,​13406,​13411,​13413-13415,​13419-13420,​13425,​13427-13430,​13433-13434,​13438-13442,​13445-13447,​13450,​13458,​13471,​13473-13474,​13484,​13491,​13494,​13498-13504,​13507-13514,​13516-13517,​13525-13526,​13529,​13534-13535,​13539-13540,​13549-13550,​13552,​13560,​13566-13567,​13570-13573,​13579-13582,​13584-13586,​13592-13593,​13597,​13614,​13616,​13621,​13626-13629,​13635,​13644-13646,​13648,​13650-13655,​13657-13662,​13666,​13669-13671,​13675-13684,​13690-13693,​13695,​13697-13705,​13707-13709,​13711,​13715,​13721,​13724,​13746,​13760-13761,​13764-13766,​13779,​13784-13786,​13796,​13800-13802,​13807,​13813,​13826,​13838,​13863,​13869,​13889-13891,​13895,​13898-13901,​13916-13917,​13921-13922,​13925,​13932-13935,​13938-13939,​13941-13942,​13958,​13963-13964,​13975,​13978,​13983-13987,​13992-13993,​13998,​14000-14001,​14007-14008,​14011,​14014-14017,​14024-14026,​14032,​14034,​14036-14037,​14056-14057,​14071,​14082-14083,​14095-14096,​14098-14100,​14102-14103,​14107,​14109-14110,​14118-14122,​14124-14127,​14130-14132,​14135-14136,​14140,​14142,​14144,​14150,​14152,​14155-14160,​14162-14164,​14167-14169,​14174-14175,​14177-14179,​14181,​14189,​14191,​14196,​14198,​14200,​14202-14207,​14209,​14221-14224,​14226-14230,​14234-14236,​14244-14247,​14250,​14255-14258,​14260,​14267-14268,​14270-14273,​14282,​14284-14300,​14307,​14314-14316,​14319,​14322,​14332,​14340-14350,​14352-14358,​14367-14369,​14371-14372,​14376,​14378,​14381-14382,​14384,​14388,​14390-14391,​14393-14394,​14396,​14400,​14405,​14407-14408,​14412,​14418,​14422-14423,​14425,​14432-14439,​14443,​14457-14458,​14463-14465,​14468-14469,​14475-14476,​14478-14479,​14481-14483,​14486,​14493-14494,​14504,​14506-14509,​14516-14517,​14519,​14522-14523,​14527-14529,​14531-14533,​14548,​14553,​14561,​14582,​14597,​14623,​14630,​14647,​14651-14652,​14654,​14656,​14659-14660,​14662-14663,​14672,​14685,​14687,​14692,​14697,​14706,​14708-14709,​14718,​14721-14722,​14726,​14732,​14734,​14737-14738,​14740,​14748-14750,​14769-14770,​14772-14775,​14779-14781,​14786,​14789-14791,​14793,​14805,​14809-14810,​14817,​14819-14820,​14826-14832,​14839-14843,​14845-14847,​14851-14854,​14857,​14860-14865,​14871,​14877,​14882,​14886,​14889-14890,​14899,​14901,​14904,​14911-14912,​14916,​14918,​14936-14938,​14940,​14943-14951,​14955,​14971,​14978-14979,​14982,​14984,​14987,​14992,​14995,​15002-15010,​15013,​15015-15016,​15023-15024,​15026,​15029,​15040,​15042,​15044,​15046-15054,​15058,​15067-15077,​15079-15080,​15083-15088,​15091-15096,​15098-15099,​15102-15107,​15110-15114,​15119-15126,​15129,​15135,​15139,​15156-15158,​15160,​15162-15169,​15172-15173,​15178-15181,​15184-15185,​15187,​15191-15192,​15194,​15198,​15201,​15203,​15205-15211,​15213-15214,​15221-15228,​15230,​15233-15236,​15240-15241,​15246-15248,​15264-15266,​15271,​15276,​15287-15288,​15300-15302,​15312,​15325-15327,​15329,​15335-15336,​15339,​15357-15358,​15361,​15367-15368,​15370-15372,​15376,​15383,​15388,​15390,​15393,​15395-15398,​15400,​15402,​15408-15409,​15419,​15427,​15447-15448,​15452,​15461,​15464,​15478,​15480-15481,​15483,​15486,​15498-15499,​15502,​15505,​15513,​15517-15518,​15532,​15534,​15545,​15548,​15551,​15556,​15560,​15570,​15591,​15594,​15596,​15598,​15607,​15610-15611,​15621-15623,​15626,​15637-15638,​15645,​15665,​15667,​15672-15674
      /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/HeuristicLab.Clients.Hive.JobManager14175
  • stable/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs

    r15584 r17059  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    2424using System.Drawing;
    2525using System.Linq;
    26 using System.Text;
    2726using System.Windows.Forms;
    28 using HeuristicLab.Clients.Hive.JobManager.ExtensionMethods;
     27using HeuristicLab.Collections;
     28using HeuristicLab.Common;
     29using HeuristicLab.Common.Resources;
    2930using HeuristicLab.Core;
    3031using HeuristicLab.Core.Views;
     
    3334
    3435namespace HeuristicLab.Clients.Hive.JobManager.Views {
    35   [View("Hive Resource Selector View")]
    36   [Content(typeof(IItemList<Resource>), true)]
    37   public partial class HiveResourceSelector : ItemView, IDisposable {
     36  [View("Hive Project Selector View")]
     37  [Content(typeof(IItemList<Project>), true)]
     38  public partial class HiveProjectSelector : ItemView, IDisposable {
     39    private const int greenFlagImageIndex = 0;
     40    private const int redFlagImageIndex = 1;
    3841    private const int slaveImageIndex = 0;
    3942    private const int slaveGroupImageIndex = 1;
     43    public const string additionalSlavesGroupName = "Additional Slaves";
     44    public const string additionalSlavesGroupDescription = "Contains additional slaves which are either ungrouped or the parenting slave group is not assigned to the selected project.";
     45
     46    private const string CURRENT_SELECTION_TAG = " [current assignment]";
     47    private const string NEW_SELECTION_TAG = " [new assignment]";
     48    private const string CHANGED_SELECTION_TAG = " [changed assignment]";
     49    private const string ADDED_SELECTION_TAG = " [added assignment]";
     50    private const string REMOVED_SELECTION_TAG = " [removed assignment]";
     51    private const string SELECTED_TAG = " [assigned]";
     52    private const string INCLUDED_TAG = " [included]";
     53    private const string ADDED_INCLUDE_TAG = " [added include]";
     54    private const string REMOVED_INCLUDE_TAG = " [removed include]";
     55
     56    private TreeNode additionalNode;
     57
     58    private readonly HashSet<TreeNode> mainTreeNodes = new HashSet<TreeNode>();
     59    private readonly HashSet<TreeNode> filteredTreeNodes = new HashSet<TreeNode>();
     60
     61    private readonly HashSet<Resource> availableResources = new HashSet<Resource>();
     62    private readonly HashSet<Resource> assignedResources = new HashSet<Resource>();
     63    private readonly HashSet<Resource> includedResources = new HashSet<Resource>();
     64    private readonly HashSet<Resource> newAssignedResources = new HashSet<Resource>();
     65    private readonly HashSet<Resource> newIncludedResources = new HashSet<Resource>();
     66
     67    private readonly Color addedAssignmentColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
     68    private readonly Color removedAssignmentColor = Color.FromArgb(255, 236, 159, 72); // #ec9f48
     69    private readonly Color addedIncludeColor = Color.FromArgb(25, 169, 221, 221); // #a9dddd
     70    private readonly Color removedIncludeColor = Color.FromArgb(25, 249, 210, 145); // #f9d291
     71    private readonly Color selectedBackColor = Color.DodgerBlue;
     72    private readonly Color selectedForeColor = Color.White;
     73    private readonly Color controlTextColor = SystemColors.ControlText;
     74    private readonly Color grayTextColor = SystemColors.GrayText;
     75
    4076    private string currentSearchString;
    41     private ISet<TreeNode> mainTreeNodes;
    42     private ISet<TreeNode> filteredTreeNodes;
    43     private ISet<TreeNode> nodeStore;
    44    
    45     private ISet<Resource> selectedResources;
    46     public ISet<Resource> SelectedResources {
    47       get { return selectedResources; }
    48       set { selectedResources = value; }
    49     }
    50 
    51     public new IItemList<Resource> Content {
    52       get { return (IItemList<Resource>)base.Content; }
     77
     78    private void resetHiveResourceSelector() {
     79      lastSelectedProject = null;
     80      selectedProject = null;
     81      projectId = null;
     82    }
     83
     84    private Guid jobId;
     85    public Guid JobId {
     86      get { return jobId; }
     87      set {
     88        if (jobId == value) return;
     89        jobId = value;
     90        resetHiveResourceSelector();
     91      }
     92    }
     93
     94    private Guid? projectId;
     95    public Guid? ProjectId {
     96      get { return projectId; }
     97      set {
     98        if (projectId == value) return;
     99        projectId = value;
     100      }
     101    }
     102
     103    private Guid? selectedProjectId;
     104    public Guid? SelectedProjectId {
     105      get { return selectedProjectId; }
     106      set {
     107        if (selectedProjectId == value) return;
     108        selectedProjectId = value;
     109      }
     110    }
     111
     112    private IEnumerable<Guid> selectedResourceIds;
     113    public IEnumerable<Guid> SelectedResourceIds {
     114      get { return selectedResourceIds; }
     115      set {
     116        if (selectedResourceIds == value) return;
     117        selectedResourceIds = value;
     118      }
     119    }
     120
     121    public bool ChangedProjectSelection {
     122      get {
     123        if ((lastSelectedProject == null && selectedProject != null)
     124          || (lastSelectedProject != null && selectedProject == null)
     125          || (lastSelectedProject != null && selectedProject != null && lastSelectedProject.Id != selectedProject.Id))
     126          return true;
     127        else return false;
     128      }
     129    }
     130
     131    public bool ChangedResources {
     132      get { return !assignedResources.SetEquals(newAssignedResources); }
     133    }
     134
     135    private Project lastSelectedProject;
     136    private Project selectedProject;
     137    public Project SelectedProject {
     138      get { return selectedProject; }
     139      set {
     140        if (selectedProject == value) return;
     141
     142        if ((JobId == Guid.Empty || JobId == null)
     143          && (value == null || SelectedProject == null || value.Id != SelectedProject.Id)) selectedResourceIds = null;
     144        lastSelectedProject = selectedProject;
     145        selectedProject = value;
     146
     147        UpdateResourceTree();
     148        ExtractStatistics();
     149        OnSelectedProjectChanged();
     150      }
     151    }
     152
     153    public int AssignedCores {
     154      get {
     155        HashSet<Slave> newAssignedSlaves = new HashSet<Slave>(newAssignedResources.OfType<Slave>());
     156        foreach(var slaveGroup in newAssignedResources.OfType<SlaveGroup>()) {
     157          foreach(var slave in HiveClient.Instance.GetAvailableResourceDescendants(slaveGroup.Id).OfType<Slave>()) {
     158            newAssignedSlaves.Add(slave);
     159          }
     160        }
     161        return newAssignedSlaves.Sum(x => x.Cores.GetValueOrDefault());
     162      }
     163    }
     164
     165    public IEnumerable<Resource> AssignedResources {
     166      get { return newAssignedResources; }
     167      set {
     168        if (newAssignedResources == value) return;
     169        newAssignedResources.Clear();
     170        foreach(var resource in value) {
     171          newAssignedResources.Add(resource);
     172        }
     173      }
     174    }
     175
     176
     177    public new IItemList<Project> Content {
     178      get { return (IItemList<Project>)base.Content; }
    53179      set { base.Content = value; }
    54180    }
    55181
    56     public HiveResourceSelector() {
     182    public HiveProjectSelector() {
    57183      InitializeComponent();
    58       mainTreeNodes = new HashSet<TreeNode>();
    59       filteredTreeNodes = new HashSet<TreeNode>();
    60       nodeStore = new HashSet<TreeNode>();
    61       selectedResources = new HashSet<Resource>();
    62       imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.MonitorLarge);
    63       imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NetworkCenterLarge);
    64     }
    65  
    66     public void StartProgressView() {
    67       if (InvokeRequired) {
    68         Invoke(new Action(StartProgressView));
    69       } else {
    70         var message = "Downloading resources. Please be patient.";
    71         MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().AddOperationProgressToView(this, message);
    72       }
    73     }
    74 
    75     public void FinishProgressView() {
    76       if (InvokeRequired) {
    77         Invoke(new Action(FinishProgressView));
    78       } else {
    79         MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().RemoveOperationProgressFromView(this);
    80       }
    81     }
    82 
     184
     185      projectsImageList.Images.Add(VSImageLibrary.FlagGreen);
     186      projectsImageList.Images.Add(VSImageLibrary.FlagRed);
     187      resourcesImageList.Images.Add(VSImageLibrary.MonitorLarge);
     188      resourcesImageList.Images.Add(VSImageLibrary.NetworkCenterLarge);
     189    }
     190
     191    #region Overrides
    83192    protected override void OnContentChanged() {
    84193      base.OnContentChanged();
    85194
    86       if (Content != null) {
    87         selectedResources = new HashSet<Resource>(Content.Where(x => selectedResources.Any(y => x.Id == y.Id)));
    88         UpdateMainTree();
     195      if (Content != null) {               
     196        if (SelectedProjectId.HasValue && SelectedProjectId.Value != Guid.Empty) {
     197          SelectedProject = GetSelectedProjectById(SelectedProjectId.Value);
     198        } else {
     199          SelectedProject = null;
     200        }
     201        //ExtractStatistics();
     202        UpdateProjectTree();
     203
     204      } else {
     205        lastSelectedProject = null;
     206        selectedProject = null;
     207        selectedProjectId = null;
     208        projectsTreeView.Nodes.Clear();
     209        resourcesTreeView.Nodes.Clear();
     210      }
     211    }
     212
     213    #endregion
     214
     215    #region Event Handlers
     216    private void HiveProjectSelector_Load(object sender, EventArgs e) {
     217      projectsTreeView.Nodes.Clear();
     218      resourcesTreeView.Nodes.Clear();
     219    }
     220
     221    private void searchTextBox_TextChanged(object sender, EventArgs e) {
     222      currentSearchString = searchTextBox.Text.ToLower();
     223      //UpdateFilteredTree();
     224      UpdateProjectTree();
     225    }
     226
     227    private void projectsTreeView_MouseDoubleClick(object sender, MouseEventArgs e) {
     228      OnProjectsTreeViewDoubleClicked();
     229    }
     230
     231    private void projectsTreeView_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
     232      var node = (Project)e.Node.Tag;
     233      if (HiveClient.Instance.DisabledParentProjects.Contains(node)) {
     234        e.Cancel = true;
     235      }
     236    }
     237
     238    private void projectsTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
     239      var node = (Project)e.Node.Tag;
     240
     241      if (node == null) {
     242        projectsTreeView.SelectedNode = null;
     243      } else if (HiveClient.Instance.DisabledParentProjects.Contains(node)) {
     244        return;
     245      } else {
     246        ResetTreeNodes(projectsTreeView.Nodes);
     247        e.Node.BackColor = selectedBackColor;
     248        e.Node.ForeColor = selectedForeColor;
     249
     250        if (node.Id == projectId) {
     251          e.Node.Text += CURRENT_SELECTION_TAG;
     252        } else if (projectId == null || projectId == Guid.Empty) {
     253          e.Node.Text += NEW_SELECTION_TAG;
     254        } else {
     255          e.Node.Text += CHANGED_SELECTION_TAG;
     256        }
     257
     258
     259      }
     260      SelectedProject = node;
     261    }
     262
     263    private void resourcesTreeView_MouseDown(object sender, MouseEventArgs e) {
     264      var node = resourcesTreeView.GetNodeAt(new Point(e.X, e.Y));
     265
     266      if (node == null && e.Button == MouseButtons.Left) {
     267        resourcesTreeView.SelectedNode = null;
    89268        ExtractStatistics();
     269      }
     270    }
     271
     272    private void resourcesTreeView_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
     273      if(e.Node == null) {
     274        e.Cancel = true;
     275        resourcesTreeView.SelectedNode = null;
     276        ExtractStatistics();
     277      } else if (e.Node == additionalNode) {
     278        e.Cancel = true;
    90279      } else {
    91         mainTreeNodes.Clear();
    92         UpdateFilteredTree();
    93       }
    94     }
    95 
    96     #region MainTree Methods
    97     private void UpdateMainTree() {
    98       mainTreeNodes.Clear();
    99 
    100       foreach (Resource g in Content) {
    101         if (g.GetType() == typeof(SlaveGroup)) {
    102           //root node
    103           if (g.ParentResourceId == null) {
    104             TreeNode tn = new TreeNode();
    105             tn.ImageIndex = slaveGroupImageIndex;
    106             tn.SelectedImageIndex = tn.ImageIndex;
    107 
    108             tn.Tag = g;
    109             tn.Text = g.Name;
    110             tn.Checked = selectedResources.Any(x => x.Id == g.Id);
    111 
    112             BuildMainTree(tn);
    113             mainTreeNodes.Add(tn);
    114           }
    115         }
    116       }
    117       UpdateFilteredTree();
    118     }
    119 
    120     private void BuildMainTree(TreeNode tn) {
    121       foreach (Resource r in Content.Where(s => s.ParentResourceId != null && s.ParentResourceId == ((Resource)tn.Tag).Id)) {
    122         TreeNode stn = new TreeNode(r.Name);
    123         if (r is Slave) stn.ImageIndex = slaveImageIndex;
    124         else if (r is SlaveGroup) stn.ImageIndex = slaveGroupImageIndex;
    125         stn.SelectedImageIndex = stn.ImageIndex;
    126         stn.Tag = r;
    127         stn.Checked = selectedResources.Any(x => x.Id == r.Id);
    128         tn.Nodes.Add(stn);
    129         mainTreeNodes.Add(stn);
    130 
    131         BuildMainTree(stn);
    132       }
     280        var r = (Resource)e.Node.Tag;
     281        if(r != null && !HiveClient.Instance.DisabledParentResources.Contains(r)) {
     282          ExtractStatistics(r);
     283        } else {
     284          e.Cancel = true;
     285        }
     286      }
     287    }
     288
     289    private void resourcesTreeView_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
     290      if(e.Node == null || e.Node == additionalNode) {
     291        e.Cancel = true;
     292      } else {
     293        var checkedResource = (Resource)e.Node.Tag;
     294        if (checkedResource == null
     295          || checkedResource.Id == Guid.Empty
     296          || HiveClient.Instance.DisabledParentResources.Contains(checkedResource)
     297          || newIncludedResources.Contains(checkedResource)) {
     298          e.Cancel = true;
     299        }
     300      }
     301    }
     302
     303    private void resourcesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
     304      var checkedResource = (Resource)e.Node.Tag;
     305      if (e.Node.Checked) {
     306        newAssignedResources.Add(checkedResource);
     307      } else {
     308        newAssignedResources.Remove(checkedResource);
     309      }
     310
     311      UpdateResourceTreeAfterCheck();
     312      if(resourcesTreeView.SelectedNode == null)
     313        ExtractStatistics();
     314      OnAssignedResourcesChanged();
     315    }
     316
     317    private void resourcesTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
     318      return;
    133319    }
    134320    #endregion
    135321
    136     #region FilteredTree Methods
    137     private void UpdateFilteredTree() {
    138       filteredTreeNodes.Clear();
    139       foreach (TreeNode n in mainTreeNodes) {
    140         n.BackColor = SystemColors.Window;
    141         if (currentSearchString == null || ((Resource)n.Tag).Name.ToLower().Contains(currentSearchString)) {
    142           n.BackColor = string.IsNullOrEmpty(currentSearchString) ? SystemColors.Window : Color.LightBlue;
    143           filteredTreeNodes.Add(n);
    144           TraverseParentNodes(n);
    145         }
    146       }
    147       UpdateResourceTree();
    148     }
    149 
    150     private void TraverseParentNodes(TreeNode node) {
    151       if (node != null) {
    152         for (TreeNode parent = node.Parent; parent != null; parent = parent.Parent)
    153           filteredTreeNodes.Add(parent);
    154       }
    155     }
     322    #region Helpers
     323
     324    private Project GetSelectedProjectById(Guid projectId) {
     325      return Content.Where(x => x.Id == projectId).SingleOrDefault();
     326    }
     327
     328    private void UpdateProjectTree() {
     329
     330      if (string.IsNullOrEmpty(currentSearchString)) {
     331        BuildProjectTree(Content);
     332      } else {
     333        HashSet<Project> filteredProjects = new HashSet<Project>();
     334        foreach(var project in Content) {
     335          if(project.Name.ToLower().Contains(currentSearchString.ToLower())) {
     336            filteredProjects.Add(project);
     337            filteredProjects.UnionWith(Content.Where(p => HiveClient.Instance.GetAvailableProjectAncestors(project.Id).Select(x => x.Id).Contains(p.Id)));
     338          }
     339        }
     340        BuildProjectTree(filteredProjects);
     341      }
     342    }
     343
     344    private void BuildProjectTree(IEnumerable<Project> projects) {
     345      projectsTreeView.Nodes.Clear();
     346      if (!projects.Any()) return;
     347
     348      var disabledParentProjects = HiveClient.Instance.DisabledParentProjects;
     349      // select all top level projects (withouth parent, or without any ancestor within current project collection)
     350      var mainProjects = new HashSet<Project>(projects.Where(x => x.ParentProjectId == null));
     351      //var parentedMainProjects = new HashSet<Project>(projects
     352      //  .Where(x => x.ParentProjectId.HasValue
     353      //  && !projects.Select(y => y.Id).Contains(x.ParentProjectId.Value)
     354      //  && !projects.SelectMany(y => HiveClient.Instance.ProjectAncestors[y.Id]).Contains(x.ParentProjectId.Value)));
     355      //mainProjects.UnionWith(parentedMainProjects);
     356      var mainDisabledParentProjects = new HashSet<Project>(disabledParentProjects.Where(x => x.ParentProjectId == null || x.ParentProjectId == Guid.Empty));
     357      mainProjects.UnionWith(mainDisabledParentProjects);
     358      var subProbjects = new HashSet<Project>(projects.Union(disabledParentProjects).Except(mainProjects));
     359      //foreach (var p in subProbjects) {
     360      //  p.ParentProjectId = HiveClient.Instance.ProjectAncestors[p.Id].Where(x => projects.Select(y => y.Id).Contains(x)).FirstOrDefault();
     361      //}
     362
     363      var stack = new Stack<Project>(mainProjects.OrderByDescending(x => x.Name));
     364
     365      TreeNode currentNode = null;
     366      Project currentProject = null;
     367
     368      while(stack.Any()) {
     369        var newProject = stack.Pop();
     370        var newNode = new TreeNode(newProject.Name) { Tag = newProject };
     371
     372        while (currentNode != null && newProject.ParentProjectId != currentProject.Id) {
     373          currentNode = currentNode.Parent;
     374          currentProject = currentNode == null ? null : (Project)currentNode.Tag;
     375        }
     376
     377        if (currentNode == null) {
     378          projectsTreeView.Nodes.Add(newNode);
     379          newNode.ImageIndex = greenFlagImageIndex;
     380        } else {
     381          currentNode.Nodes.Add(newNode);
     382          newNode.ImageIndex = redFlagImageIndex;
     383        }
     384
     385        newNode.SelectedImageIndex = newNode.ImageIndex;
     386
     387        if(disabledParentProjects.Contains(newProject)) {
     388          newNode.Checked = false;
     389          newNode.ForeColor = grayTextColor;
     390        }
     391        else if (SelectedProject != null && SelectedProject.Id.Equals(newProject.Id)) {
     392          newNode.BackColor = selectedBackColor;
     393          newNode.ForeColor = selectedForeColor;
     394          if(SelectedProject.Id == projectId) {
     395            newNode.Text += CURRENT_SELECTION_TAG;
     396          } else if (projectId == null || projectId == Guid.Empty) {
     397            newNode.Text += NEW_SELECTION_TAG;
     398          } else {
     399            newNode.Text += CHANGED_SELECTION_TAG;
     400          }
     401        }
     402
     403        if (!string.IsNullOrEmpty(currentSearchString) && newProject.Name.ToLower().Contains(currentSearchString.ToLower())) {
     404          newNode.BackColor = Color.LightBlue;
     405        }
     406
     407        var childProjects = subProbjects.Where(x => x.ParentProjectId == newProject.Id);
     408        if (childProjects.Any()) {
     409          foreach (var project in childProjects.OrderByDescending(x => x.Name)) {
     410            subProbjects.Remove(project);
     411            stack.Push(project);
     412          }
     413          currentNode = newNode;
     414          currentProject = newProject;
     415        }
     416      }
     417
     418      projectsTreeView.ExpandAll();
     419    }
     420
     421    private static IEnumerable<Resource> GetAssignedResourcesForProject(Guid projectId) {
     422      var assignedProjectResources = HiveServiceLocator.Instance.CallHiveService(s => s.GetAssignedResourcesForProject(projectId));
     423      return HiveClient.Instance.Resources.Where(x => assignedProjectResources.Select(y => y.ResourceId).Contains(x.Id));
     424    }
     425
     426    private static IEnumerable<Resource> GetAssignedResourcesForJob(Guid jobId) {
     427      var assignedJobResources = HiveServiceLocator.Instance.CallHiveService(s => s.GetAssignedResourcesForJob(jobId));
     428      return HiveClient.Instance.Resources.Where(x => assignedJobResources.Select(y => y.ResourceId).Contains(x.Id));
     429    }
     430
     431    private void UpdateResourceTree() {
     432      UpdateAvailableResources();
     433      UpdateAssignedResources();
     434      UpdateIncludedResources();
     435      BuildResourceTree(availableResources);
     436    }
     437
     438    private void UpdateResourceTreeAfterCheck() {
     439      resourcesTreeView.BeforeCheck -= resourcesTreeView_BeforeCheck;
     440      resourcesTreeView.AfterCheck -= resourcesTreeView_AfterCheck;
     441      UpdateNewAssignedResources();
     442      UpdateNewIncludedResources();
     443      SetTreeNodes(resourcesTreeView.Nodes);
     444      resourcesTreeView.BeforeCheck += resourcesTreeView_BeforeCheck;
     445      resourcesTreeView.AfterCheck += resourcesTreeView_AfterCheck;
     446    }
     447
     448    private void UpdateAvailableResources() {
     449      availableResources.Clear();
     450      if (selectedProject != null) {
     451        var assignedProjectResources = GetAssignedResourcesForProject(selectedProject.Id);
     452        foreach (var resource in assignedProjectResources) {
     453          availableResources.Add(resource);
     454          foreach(var descendant in HiveClient.Instance.Resources.Where(x => HiveClient.Instance.ResourceDescendants[resource.Id].Contains(x.Id))) {
     455            availableResources.Add(descendant);
     456          }
     457        }
     458      }
     459      //ExtractStatistics();
     460      //OnAssignedResourcesChanged();
     461    }
     462
     463    private void UpdateAssignedResources() {
     464      assignedResources.Clear();
     465      newAssignedResources.Clear();
     466
     467      if (JobId == Guid.Empty || JobId == null) { // new, unchanged jobs get all avaialable resources
     468        // update new assigned resources
     469        if(selectedResourceIds == null) {
     470          foreach (var resource in availableResources
     471            .Where(x => !x.ParentResourceId.HasValue
     472            || !availableResources.Select(y => y.Id).Contains(x.ParentResourceId.Value))) {
     473            newAssignedResources.Add(resource);
     474          }
     475        } else {
     476          foreach(var resource in availableResources.Where(x => selectedResourceIds.Contains(x.Id))) {
     477            newAssignedResources.Add(resource);
     478          }
     479        }
     480      } else if(selectedProject.Id == projectId) { // existent, unchanged jobs get all assigned resources
     481        // update assigned resources
     482        var assignedJobResources = GetAssignedResourcesForJob(JobId);
     483        foreach (var resource in assignedJobResources) {
     484          assignedResources.Add(resource);
     485          if (selectedResourceIds == null) {
     486            newAssignedResources.Add(resource);
     487          }
     488        }
     489
     490        if(selectedResourceIds != null) {
     491          foreach (var resource in availableResources.Where(x => selectedResourceIds.Contains(x.Id))) {
     492            newAssignedResources.Add(resource);
     493          }
     494        }
     495      }
     496
     497      //ExtractStatistics();
     498      OnAssignedResourcesChanged();
     499    }
     500
     501    private void UpdateNewAssignedResources() {
     502      for(int i = newAssignedResources.Count-1; i>=0; i--) {
     503        if(newAssignedResources.Intersect(HiveClient.Instance.GetAvailableResourceAncestors(newAssignedResources.ElementAt(i).Id)).Any()) {
     504          newAssignedResources.Remove(newAssignedResources.ElementAt(i));
     505        }
     506      }
     507    }
     508
     509    private void UpdateIncludedResources() {
     510      includedResources.Clear();
     511      newIncludedResources.Clear();
     512
     513      if (JobId != Guid.Empty) {
     514        foreach (var item in assignedResources) {
     515          foreach (var descendant in HiveClient.Instance.GetAvailableResourceDescendants(item.Id)) {
     516            includedResources.Add(descendant);
     517          }
     518        }
     519      }
     520
     521      foreach (var item in newAssignedResources) {
     522        foreach (var descendant in HiveClient.Instance.GetAvailableResourceDescendants(item.Id)) {
     523          newIncludedResources.Add(descendant);
     524        }
     525      }
     526    }
     527
     528    private void UpdateNewIncludedResources() {
     529      newIncludedResources.Clear();
     530      foreach (var item in newAssignedResources) {
     531        foreach (var descendant in HiveClient.Instance.GetAvailableResourceDescendants(item.Id)) {
     532          newIncludedResources.Add(descendant);
     533        }
     534      }
     535    }
     536
     537    private void BuildResourceTree(IEnumerable<Resource> resources) {
     538      resourcesTreeView.Nodes.Clear();
     539      if (!resources.Any()) return;
     540
     541      resourcesTreeView.BeforeCheck -= resourcesTreeView_BeforeCheck;
     542      resourcesTreeView.AfterCheck -= resourcesTreeView_AfterCheck;
     543
     544      //var disabledParentResources = HiveClient.Instance.DisabledParentResources;
     545      var disabledParentResources = HiveClient.Instance.GetDisabledResourceAncestors(resources);
     546      var mainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>().Where(x => x.ParentResourceId == null));
     547      //var parentedMainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
     548      //  .Where(x => x.ParentResourceId.HasValue && !resources.Select(y => y.Id).Contains(x.ParentResourceId.Value)));
     549      //mainResources.UnionWith(parentedMainResources);
     550      //var subResources = new HashSet<Resource>(resources.Except(mainResources));
     551      var mainDisabledParentResources = new HashSet<Resource>(disabledParentResources.Where(x => x.ParentResourceId == null || x.ParentResourceId == Guid.Empty));
     552      mainResources.UnionWith(mainDisabledParentResources);
     553      var subResources = new HashSet<Resource>(resources.Union(disabledParentResources).Except(mainResources).OrderByDescending(x => x.Name));
     554
     555      var addedAssignments = newAssignedResources.Except(assignedResources);
     556      var removedAssignments = assignedResources.Except(newAssignedResources);
     557      var addedIncludes = newIncludedResources.Except(includedResources);
     558      var removedIncludes = includedResources.Except(newIncludedResources);
     559
     560      TreeNode currentNode = null;
     561      Resource currentResource = null;
     562
     563      var stack = new Stack<Resource>(mainResources.OrderByDescending(x => x.Name));
     564
     565      while (stack.Any()) {
     566        var newResource = stack.Pop();
     567        var newNode = new TreeNode(newResource.Name) { Tag = newResource };
     568
     569        // search for parent node of newNode and save in currentNode
     570        // necessary since newNodes (stack top items) might be siblings
     571        // or grand..grandparents of previous node (currentNode)
     572        while (currentNode != null && newResource.ParentResourceId != currentResource.Id) {
     573          currentNode = currentNode.Parent;
     574          currentResource = currentNode == null ? null : (Resource)currentNode.Tag;
     575        }
     576
     577        if (currentNode == null) {
     578          resourcesTreeView.Nodes.Add(newNode);
     579        } else {
     580          currentNode.Nodes.Add(newNode);
     581        }
     582
     583        if (disabledParentResources.Contains(newResource)) {
     584          newNode.Checked = false;
     585          newNode.ForeColor = grayTextColor;
     586        } else if (newAssignedResources.Select(x => x.Id).Contains(newResource.Id)) {
     587          newNode.Checked = true;
     588          if(!addedAssignments.Select(x => x.Id).Contains(newResource.Id) && !removedAssignments.Select(x => x.Id).Contains(newResource.Id)) {
     589            newNode.Text += SELECTED_TAG;
     590          }
     591        } else if (newIncludedResources.Select(x => x.Id).Contains(newResource.Id)) {
     592          newNode.Checked = true;
     593          newNode.ForeColor = grayTextColor;
     594        }
     595
     596        if (includedResources.Select(x => x.Id).Contains(newResource.Id) && newIncludedResources.Select(x => x.Id).Contains(newResource.Id)) {
     597          newNode.Text += INCLUDED_TAG;
     598        } else if (addedIncludes.Select(x => x.Id).Contains(newResource.Id)) {
     599          newNode.BackColor = addedIncludeColor;
     600          newNode.ForeColor = grayTextColor;
     601          newNode.Text += ADDED_INCLUDE_TAG;
     602        } else if (removedIncludes.Select(x => x.Id).Contains(newResource.Id)) {
     603          newNode.BackColor = removedIncludeColor;
     604          newNode.Text += REMOVED_INCLUDE_TAG;
     605        }
     606
     607        if (addedAssignments.Select(x => x.Id).Contains(newResource.Id)) {
     608          newNode.BackColor = addedAssignmentColor;
     609          newNode.ForeColor = controlTextColor;
     610          newNode.Text += ADDED_SELECTION_TAG;
     611        } else if (removedAssignments.Select(x => x.Id).Contains(newResource.Id)) {
     612          newNode.BackColor = removedAssignmentColor;
     613          newNode.ForeColor = controlTextColor;
     614          newNode.Text += REMOVED_SELECTION_TAG;
     615        }
     616
     617        if (newResource is Slave) {
     618          newNode.ImageIndex = slaveImageIndex;
     619        } else {
     620          newNode.ImageIndex = slaveGroupImageIndex;
     621
     622          var childResources = subResources.Where(x => x.ParentResourceId == newResource.Id);
     623          if (childResources.Any()) {
     624            foreach (var resource in childResources.OrderByDescending(x => x.Name)) {
     625              subResources.Remove(resource);
     626              stack.Push(resource);
     627            }
     628            currentNode = newNode;
     629            currentResource = newResource;
     630          }
     631        }
     632        newNode.SelectedImageIndex = newNode.ImageIndex;
     633      }
     634
     635      var singleSlaves = subResources.OfType<Slave>();
     636      if (singleSlaves.Any()) {
     637
     638        additionalNode = new TreeNode(additionalSlavesGroupName) {
     639          ForeColor = SystemColors.GrayText,
     640          ImageIndex = slaveGroupImageIndex,
     641          Tag = new SlaveGroup() {
     642            Name = additionalSlavesGroupName,
     643            Description = additionalSlavesGroupDescription
     644          }
     645        };
     646
     647        foreach (var slave in singleSlaves.OrderBy(x => x.Name)) {
     648          var slaveNode = new TreeNode(slave.Name) { Tag = slave };
     649
     650          if (newAssignedResources.Select(x => x.Id).Contains(slave.Id)) {
     651            slaveNode.Checked = true;
     652            if (!addedAssignments.Select(x => x.Id).Contains(slave.Id) &&
     653                !removedAssignments.Select(x => x.Id).Contains(slave.Id)) {
     654              slaveNode.Text += SELECTED_TAG;
     655            }
     656          }
     657
     658          if (addedAssignments.Select(x => x.Id).Contains(slave.Id)) {
     659            slaveNode.BackColor = addedAssignmentColor;
     660            slaveNode.ForeColor = controlTextColor;
     661            slaveNode.Text += ADDED_SELECTION_TAG;
     662          } else if (removedAssignments.Select(x => x.Id).Contains(slave.Id)) {
     663            slaveNode.BackColor = removedAssignmentColor;
     664            slaveNode.ForeColor = controlTextColor;
     665            slaveNode.Text += REMOVED_SELECTION_TAG;
     666          }
     667
     668          additionalNode.Nodes.Add(slaveNode);
     669        }
     670
     671        resourcesTreeView.Nodes.Add(additionalNode);
     672      }
     673
     674      ExpandResourceNodesOfInterest(resourcesTreeView.Nodes);
     675
     676      resourcesTreeView.BeforeCheck += resourcesTreeView_BeforeCheck;
     677      resourcesTreeView.AfterCheck += resourcesTreeView_AfterCheck;
     678    }
     679
     680    private void ExpandResourceNodesOfInterest(TreeNodeCollection nodes) {
     681      foreach(TreeNode n in nodes) {
     682        Resource r = (Resource)n.Tag;
     683        if(n.Nodes.Count > 0) {
     684          if(HiveClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()           
     685            || HiveClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<Slave>().Intersect(assignedResources.Union(newAssignedResources)).Any()
     686            || (n == additionalNode && additionalNode.Nodes.Count > 0 && additionalNode.Nodes.Cast<TreeNode>().Any(x => x.Checked))) {
     687            n.Expand();
     688            ExpandResourceNodesOfInterest(n.Nodes);
     689          } else {
     690            n.Collapse();
     691          }   
     692        } else {
     693          n.Collapse();
     694        }
     695      }
     696    }
     697
     698    private void CollapseSlaveOnlyNodes(TreeNode tn) {
     699      if (!(tn.Tag is Resource)) return;
     700
     701      Resource r = (Resource)tn.Tag;
     702      if (HiveClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()) {
     703        tn.Expand();
     704        foreach (TreeNode n in tn.Nodes) CollapseSlaveOnlyNodes(n);
     705      } else {
     706        tn.Collapse();
     707      }
     708    }
     709
     710    private void ExtractStatistics(Resource resource = null) {
     711      HashSet<Slave> newAssignedSlaves = new HashSet<Slave>(newAssignedResources.OfType<Slave>());
     712      foreach (var slaveGroup in newAssignedResources.OfType<SlaveGroup>()) {
     713        foreach (var slave in HiveClient.Instance.GetAvailableResourceDescendants(slaveGroup.Id).OfType<Slave>()) {
     714          newAssignedSlaves.Add(slave);
     715        }
     716      }
     717
     718      HashSet<Slave> selectedSlaves = null;
     719
     720      if (resource != null) {
     721        var slaveGroup = resource as SlaveGroup;
     722        if (slaveGroup != null) {
     723          selectedSlaves = new HashSet<Slave>(HiveClient.Instance.GetAvailableResourceDescendants(slaveGroup.Id).OfType<Slave>());
     724        } else {
     725          selectedSlaves = new HashSet<Slave>(new[] { resource as Slave });
     726        }
     727      } else {
     728        selectedSlaves = newAssignedSlaves;
     729      }
     730
     731      int sumCores = selectedSlaves.Sum(x => x.Cores.GetValueOrDefault());
     732      int sumFreeCores = selectedSlaves.Sum(x => x.FreeCores.GetValueOrDefault());
     733      double sumMemory = selectedSlaves.Sum(x => x.Memory.GetValueOrDefault()) / 1024.0;
     734      double sumFreeMemory = selectedSlaves.Sum(x => x.FreeMemory.GetValueOrDefault()) / 1024.0;
     735
     736      coresSummaryLabel.Text = string.Format("{0} Total ({1} Free / {2} Used)", sumCores, sumFreeCores, sumCores - sumFreeCores);
     737      memorySummaryLabel.Text = string.Format("{0:0.00} GB Total ({1:0.00} GB Free / {2:0.00} GB Used)", sumMemory, sumFreeMemory, sumMemory - sumFreeMemory);
     738    }
     739
     740    private void StyleTreeNode(TreeNode n, string name) {
     741      n.Text = name;
     742      n.BackColor = Color.Transparent;
     743      n.ForeColor = Color.Black;
     744
     745      if(n.Tag is Project) {
     746        var p = (Project)n.Tag;
     747        if(HiveClient.Instance.DisabledParentProjects.Select(x => x.Id).Contains(p.Id)) {
     748          n.Checked = false;
     749          n.ForeColor = grayTextColor;
     750        }
     751      } else if(n.Tag is Resource) {
     752        var r = (Resource)n.Tag;
     753        if(HiveClient.Instance.DisabledParentResources.Select(x => x.Id).Contains(r.Id) || n == additionalNode) {
     754          n.Checked = false;
     755          n.ForeColor = grayTextColor;
     756        }
     757      }
     758    }
     759
     760    private void ResetTreeNodes(TreeNodeCollection nodes) {
     761      foreach (TreeNode n in nodes) {
     762        string name = "";
     763        if (n.Tag is Project) name = ((Project)n.Tag).Name;
     764        else if (n.Tag is Resource) name = ((Resource)n.Tag).Name;
     765        StyleTreeNode(n, name);
     766        if (n.Nodes.Count > 0) {
     767          ResetTreeNodes(n.Nodes);
     768        }
     769      }
     770    }
     771
     772    private void SetTreeNodes(TreeNodeCollection nodes) {
     773      var addedAssignments = newAssignedResources.Except(assignedResources);
     774      var removedAssignments = assignedResources.Except(newAssignedResources);
     775      var addedIncludes = newIncludedResources.Except(includedResources);
     776      var removedIncludes = includedResources.Except(newIncludedResources);
     777
     778      foreach (TreeNode n in nodes) {
     779
     780        if(n.Tag is Resource) {
     781          // reset
     782          var resource = (Resource)n.Tag;
     783          n.Text = resource.Name;
     784          n.BackColor = Color.Transparent;
     785          n.ForeColor = Color.Black;
     786          n.Checked = false;
     787
     788          if (HiveClient.Instance.DisabledParentResources.Select(x => x.Id).Contains(resource.Id) || n == additionalNode) {
     789            n.ForeColor = grayTextColor;
     790          }
     791
     792          // add additional info
     793          if (newAssignedResources.Select(x => x.Id).Contains(resource.Id)) {
     794            n.Checked = true;
     795            if (!addedAssignments.Select(x => x.Id).Contains(resource.Id) && !removedAssignments.Select(x => x.Id).Contains(resource.Id)) {
     796              n.Text += SELECTED_TAG;
     797            }
     798          } else if (newIncludedResources.Select(x => x.Id).Contains(resource.Id)) {
     799            n.Checked = true;
     800            n.ForeColor = grayTextColor;
     801          }
     802
     803          if (includedResources.Select(x => x.Id).Contains(resource.Id) && newIncludedResources.Select(x => x.Id).Contains(resource.Id)) {
     804            n.Text += INCLUDED_TAG;
     805          } else if (addedIncludes.Select(x => x.Id).Contains(resource.Id)) {
     806            n.BackColor = addedIncludeColor;
     807            n.ForeColor = grayTextColor;
     808            n.Text += ADDED_INCLUDE_TAG;
     809          } else if (removedIncludes.Select(x => x.Id).Contains(resource.Id)) {
     810            n.BackColor = removedIncludeColor;
     811            n.Text += REMOVED_INCLUDE_TAG;
     812          }
     813
     814          if (addedAssignments.Select(x => x.Id).Contains(resource.Id)) {
     815            n.BackColor = addedAssignmentColor;
     816            n.ForeColor = controlTextColor;
     817            n.Text += ADDED_SELECTION_TAG;
     818          } else if (removedAssignments.Select(x => x.Id).Contains(resource.Id)) {
     819            n.BackColor = removedAssignmentColor;
     820            n.ForeColor = controlTextColor;
     821            n.Text += REMOVED_SELECTION_TAG;
     822          }
     823        }
     824
     825        if(n.Nodes.Count > 0) {
     826          SetTreeNodes(n.Nodes);
     827        }
     828      }
     829    }
     830
    156831    #endregion
    157832
    158     #region ResourceTree Methods
    159     private void UpdateResourceTree() {
    160       resourcesTreeView.Nodes.Clear();
    161       nodeStore.Clear();
    162 
    163       foreach (TreeNode node in filteredTreeNodes) {
    164         var clone = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
    165         if (clone == null) {
    166           clone = (TreeNode)node.Clone();
    167           nodeStore.Add(clone);
    168           clone.Nodes.Clear();
    169         }
    170         foreach (TreeNode child in node.Nodes)
    171           if (filteredTreeNodes.Any(x => ((Resource)x.Tag).Id == ((Resource)child.Tag).Id)) {
    172             var childClone = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)child.Tag).Id);
    173             if (childClone == null) {
    174               childClone = (TreeNode)child.Clone();
    175               nodeStore.Add(childClone);
    176               childClone.Nodes.Clear();
    177             }
    178             clone.Nodes.Add(childClone);
    179           }
    180       }
    181       resourcesTreeView.Nodes.AddRange(nodeStore.Where(x => ((Resource)x.Tag).ParentResourceId == null).ToArray());
    182       if (string.IsNullOrEmpty(currentSearchString)) ExpandSlaveGroupNodes();
    183       else resourcesTreeView.ExpandAll();
    184     }
    185     #endregion
    186 
    187833    #region Events
    188     private void resourcesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
    189       if (e.Action != TreeViewAction.Unknown) {
    190         if (e.Node.Checked) {
    191           IncludeChildNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
    192           IncludeParentNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
    193         } else {
    194           ExcludeChildNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
    195           ExcludeParentNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
    196         }
    197         ExtractStatistics();
    198       }
    199     }
    200 
    201     private void resourcesTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
    202       if (e.Action != TreeViewAction.Unknown) {
    203         ExtractStatistics(e.Node);
    204       }
    205     }
    206 
    207     private void searchTextBox_TextChanged(object sender, System.EventArgs e) {
    208       currentSearchString = searchTextBox.Text.ToLower();
    209       UpdateFilteredTree();
    210     }
    211     #endregion
    212 
    213     #region Helpers
    214     private void IncludeChildNodes(TreeNode node) {
    215       if (node != null) {
    216         node.Checked = true;
    217         selectedResources.Add((Resource)node.Tag);
    218         AdjustNodeCheckedState(node);
    219         foreach (TreeNode n in node.Nodes) IncludeChildNodes(n);
    220       }
    221     }
    222 
    223     private void IncludeParentNodes(TreeNode node) {
    224       if (node != null && node.Parent != null) {
    225         TreeNode parent = node.Parent;
    226         if (parent.Nodes.OfType<TreeNode>().All(x => x.Checked)) {
    227           parent.Checked = true;
    228           selectedResources.Add((Resource)parent.Tag);
    229           AdjustNodeCheckedState(parent);
    230           IncludeParentNodes(parent);
    231         }
    232       }
    233     }
    234 
    235     private void ExcludeChildNodes(TreeNode node) {
    236       if (node != null) {
    237         node.Checked = false;
    238         selectedResources.Remove((Resource)node.Tag);
    239         AdjustNodeCheckedState(node);
    240         foreach (TreeNode n in node.Nodes) ExcludeChildNodes(n);
    241       }
    242     }
    243 
    244     private void ExcludeParentNodes(TreeNode node) {
    245       if (node != null) {
    246         node.Checked = false;
    247         selectedResources.Remove((Resource)node.Tag);
    248         AdjustNodeCheckedState(node);
    249         ExcludeParentNodes(node.Parent);
    250       }
    251     }
    252 
    253     private void AdjustNodeCheckedState(TreeNode node) {
    254       var filterdNode = filteredTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
    255       var storedNode = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
    256       if (filterdNode != null) filterdNode.Checked = node.Checked;
    257       if (storedNode != null) storedNode.Checked = node.Checked;
    258     }
    259 
    260     private void ExpandSlaveGroupNodes() {
    261       foreach (TreeNode n in nodeStore.Where(x => x.Tag is SlaveGroup)) {
    262         TreeNode[] children = new TreeNode[n.Nodes.Count];
    263         n.Nodes.CopyTo(children, 0);
    264         if (children.Any(x => x.Tag is SlaveGroup)) n.Expand();
    265       }
    266     }
    267 
    268     private void ExtractStatistics(TreeNode treeNode = null) {
    269       StringBuilder sb = new StringBuilder();
    270       Resource resource = treeNode == null ? null : treeNode.Tag as Resource;
    271       ISet<Resource> resources = treeNode == null ? selectedResources : new HashSet<Resource>(treeNode.DescendantNodes().Select(x => x.Tag as Resource)); ;
    272       IEnumerable<SlaveGroup> slaveGroups = resources.OfType<SlaveGroup>();
    273       IEnumerable<Slave> slaves = resources.OfType<Slave>();
    274       int cpuSpeed = 0, cores = 0, freeCores = 0, memory = 0, freeMemory = 0;
    275       string contextString = treeNode == null ? "Selected" : "Included";
    276 
    277       if (resources.Any() || resource != null) {
    278         foreach (Slave s in slaves) {
    279           cpuSpeed += s.CpuSpeed.GetValueOrDefault();
    280           cores += s.Cores.GetValueOrDefault();
    281           freeCores += s.FreeCores.GetValueOrDefault();
    282           memory += s.Memory.GetValueOrDefault();
    283           freeMemory += s.FreeMemory.GetValueOrDefault();
    284         }
    285         if (resource != null) {
    286           if (resource is SlaveGroup) sb.Append("Slave group: ");
    287           else if (resource is Slave) {
    288             sb.Append("Slave: ");
    289             if (!resources.Any()) {
    290               Slave s = resource as Slave;
    291               cpuSpeed = s.CpuSpeed.GetValueOrDefault();
    292               cores = s.Cores.GetValueOrDefault();
    293               freeCores = s.FreeCores.GetValueOrDefault();
    294               memory = s.Memory.GetValueOrDefault();
    295               freeMemory = s.FreeMemory.GetValueOrDefault();
    296             }
    297           }
    298           sb.AppendLine(string.Format("{0}", resource.Name));
    299         }
    300         if (resource == null || resource is SlaveGroup) {
    301           if (resources.Any()) {
    302             sb.AppendFormat("{0} slave groups ({1}): ", contextString, slaveGroups.Count());
    303             foreach (SlaveGroup sg in slaveGroups) sb.AppendFormat("{0}; ", sg.Name);
    304             sb.AppendLine();
    305             sb.AppendFormat("{0} slaves ({1}): ", contextString, slaves.Count());
    306             foreach (Slave s in slaves) sb.AppendFormat("{0}; ", s.Name);
    307             sb.AppendLine();
    308           } else {
    309             sb.Append("The selection does not inlcude any further resources.");
    310           }
    311         }
    312         sb.AppendLine();
    313         sb.AppendLine(string.Format("CPU speed: {0} MHz", cpuSpeed));
    314         if (resources.Any()) sb.AppendLine(string.Format("Avg. CPU speed: {0:0.00} MHz", (double)cpuSpeed / resources.Count()));
    315         sb.AppendLine(string.Format("Cores: {0}", cores));
    316         sb.AppendLine(string.Format("Free cores: {0}", freeCores));
    317         if (resources.Any()) sb.AppendLine(string.Format("Avg. free cores: {0:0.00}", (double)freeCores / resources.Count()));
    318         sb.AppendLine(string.Format("Memory: {0} MB", memory));
    319         sb.AppendFormat("Free memory: {0} MB", freeMemory);
    320         if (resources.Any()) sb.Append(string.Format("{0}Avg. free memory: {1:0.00} MB", Environment.NewLine, (double)freeMemory / resources.Count()));
    321       } else {
    322         sb.Append("No resources selected.");
    323       }
    324 
    325       descriptionTextBox.Text = sb.ToString();
     834    public event EventHandler SelectedProjectChanged;
     835    private void OnSelectedProjectChanged() {
     836      var handler = SelectedProjectChanged;
     837      if (handler != null) handler(this, EventArgs.Empty);
     838    }
     839
     840    public event EventHandler AssignedResourcesChanged;
     841    private void OnAssignedResourcesChanged() {
     842      var handler = AssignedResourcesChanged;
     843      if (handler != null) handler(this, EventArgs.Empty);
     844    }
     845
     846    public event EventHandler ProjectsTreeViewDoubleClicked;
     847    private void OnProjectsTreeViewDoubleClicked() {
     848      var handler = ProjectsTreeViewDoubleClicked;
     849      if (handler != null) handler(this, EventArgs.Empty);
    326850    }
    327851    #endregion
Note: See TracChangeset for help on using the changeset viewer.