Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/30/18 11:32:56 (6 years ago)
Author:
jkarder
Message:

#2839: merged [15377-16116/branches/2839_HiveProjectManagement] into trunk

Location:
trunk
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/HeuristicLab.Clients.Hive.Administrator

  • trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectsView.cs

    r15760 r16117  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    4040    private const int greenFlagImageIndex = 0;
    4141    private const int redFlagImageIndex = 1;
    42 
    43     private readonly Color changedColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
    44     private readonly Color selectedColor = Color.FromArgb(255, 240, 194, 59); // #f0c23b
     42    private const string SELECTED_TAG = ""; // " [selected]";
     43    private const string NOT_STORED_TAG = "*"; // " [not stored]";
     44    private const string CHANGES_NOT_STORED_TAG = "*"; // " [changes not stored]";
     45
     46    private readonly Color selectedBackColor = Color.DodgerBlue;
     47    private readonly Color selectedForeColor = Color.White;
     48    private readonly Color grayTextColor = SystemColors.GrayText;
     49
    4550    private Project selectedProject = null;
     51    public Project SelectedProject {
     52      get { return selectedProject; }
     53      set { if (selectedProject != value) ChangeSelectedProject(value); }
     54    }
    4655
    4756    private readonly object locker = new object();
     
    92101        projectPermissionsView.Content = null;
    93102        projectResourcesView.Content = null;
     103        projectJobsView.Content = null;
     104        selectedProject = null;
    94105      } else {
    95         var top = BuildProjectTree(Content);
    96         projectView.Content = top;
    97         projectPermissionsView.Content = top;
    98         projectResourcesView.Content = top;
    99 
    100         if(top != null && top.Id == Guid.Empty) {
    101           projectPermissionsView.Locked = true;
    102           projectResourcesView.Locked = true;
    103         }
     106        BuildProjectTree(Content);
    104107      }
    105108    }
     
    107110    protected override void SetEnabledStateOfControls() {
    108111      base.SetEnabledStateOfControls();
    109       bool enabled = Content != null && !ReadOnly;
    110       refreshButton.Enabled = enabled;
    111       addButton.Enabled = enabled;
    112       removeButton.Enabled = enabled;
    113       saveProjectButton.Enabled = enabled;
    114       projectView.Enabled = enabled;
    115       projectPermissionsView.Enabled = enabled;
    116       projectResourcesView.Enabled = enabled;
     112      bool selectedProjectExists = selectedProject != null && selectedProject.Id != Guid.Empty && Content.Contains(selectedProject);
     113      bool projectIsNew = selectedProject != null && selectedProject.Id == Guid.Empty;
     114      bool locked = Content == null || selectedProject == null || Locked || ReadOnly;
     115      bool parentOwner = HiveAdminClient.Instance.CheckOwnershipOfParentProject(selectedProject, UserInformation.Instance.User.Id);
     116      bool saveLocked = locked || (!IsAdmin() && selectedProject.OwnerUserId != UserInformation.Instance.User.Id && !parentOwner);
     117      bool addLocked = saveLocked || projectIsNew || selectedProject.Id == Guid.Empty;
     118      bool deleteLocked = locked || (!IsAdmin() && !parentOwner) || Content.Where(x => x.ParentProjectId == selectedProject.Id).Any();
     119
     120      var now = DateTime.Now;
     121      if (!addLocked && (now < selectedProject.StartDate || now > selectedProject.EndDate)) addLocked = true;
     122
     123      addButton.Enabled = !addLocked;
     124      removeButton.Enabled = !deleteLocked;
     125      saveProjectButton.Enabled = !saveLocked;
     126      projectView.Enabled = !locked;
     127      projectPermissionsView.Enabled = !locked;
     128      projectResourcesView.Enabled = !locked;
     129      projectJobsView.Enabled = !locked;
     130
     131      projectView.Locked = locked;
     132      projectPermissionsView.Locked = locked;
     133      projectResourcesView.Locked = locked;
     134      projectJobsView.Locked = locked;
    117135    }
    118136    #endregion
     
    194212    }
    195213
    196     private void addButton_Click(object sender, EventArgs e) {
    197       Guid? parentProjectId = null;
    198 
     214    private void addButton_Click(object sender, EventArgs e) {     
     215
     216      if (selectedProject == null && !IsAdmin()) {
     217        MessageBox.Show(
     218          "You are not allowed to add a root project - please select a parent project.",
     219          "HeuristicLab Hive Administrator",
     220          MessageBoxButtons.OK,
     221          MessageBoxIcon.Information);
     222        return;
     223      }
     224     
    199225      if (selectedProject != null && selectedProject.Id == Guid.Empty) {
    200226        MessageBox.Show(
     
    206232      }
    207233
    208       if (selectedProject != null) parentProjectId = selectedProject.Id;
    209234      var project = new Project {
    210235        Name = "New Project",
    211         OwnerUserId = UserInformation.Instance.User.Id,
    212         ParentProjectId = parentProjectId
     236        OwnerUserId = UserInformation.Instance.User.Id,       
    213237      };
    214 
    215       selectedProject = project;
     238      if(selectedProject != null) {
     239        project.ParentProjectId = selectedProject.Id;
     240        project.EndDate = selectedProject.EndDate;
     241      }
     242
     243      SelectedProject = project;
    216244      Content.Add(project);
    217245    }
     
    221249
    222250      lock (locker) {
     251        // for details go to ChangeSelectedProject(..)
    223252        if (!removeButton.Enabled) return;
    224253        removeButton.Enabled = false;
    225254      }
    226255
    227       if(!IsAdmin()
    228         && HiveAdminClient.Instance.CheckOwnershipOfParentProject(selectedProject,
    229           UserInformation.Instance.User.Id)) {
     256      // double check of ChangeSelectedProject(..):
     257      // if the user is no admin nor owner of a parent project
     258      if (!IsAdmin() && !HiveAdminClient.Instance.CheckOwnershipOfParentProject(selectedProject, UserInformation.Instance.User.Id)) {
    230259        MessageBox.Show(
    231           "Only subprojects of owned projects can be deleted.",
     260          "Only admins and owners of parent projects are allowed to delete this project.",
    232261          "HeuristicLab Hive Administrator",
    233262          MessageBoxButtons.OK,
    234263          MessageBoxIcon.Error);
    235264        return;
    236       }
    237 
    238       if (!IsAdmin() && Content.Any(x => x.ParentProjectId == selectedProject.Id)) {
     265      }           
     266
     267
     268      if (Content.Any(x => x.ParentProjectId == selectedProject.Id)
     269          || HiveAdminClient.Instance.ProjectDescendants[selectedProject.Id].Any()) {
    239270        MessageBox.Show(
    240271          "Only empty projects can be deleted.",
     
    245276      }
    246277
     278      if (HiveAdminClient.Instance.Jobs.ContainsKey(selectedProject.Id)
     279        && HiveAdminClient.Instance.Jobs[selectedProject.Id] != null
     280        && HiveAdminClient.Instance.Jobs[selectedProject.Id].Any()) {
     281        MessageBox.Show(
     282          "There are " + HiveAdminClient.Instance.Jobs[selectedProject.Id].Count + " job(s) using this project and/or child-projects. It is necessary to delete them before the project.",
     283          "HeuristicLab Hive Administrator",
     284          MessageBoxButtons.OK,
     285          MessageBoxIcon.Error);
     286        return;
     287      }
     288
    247289      var result = MessageBox.Show(
    248290        "Do you really want to delete " + selectedProject.Name + "?",
     
    253295      if (result == DialogResult.Yes) {
    254296        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
    255           action: () => RemoveProject(selectedProject),
     297          action: () => {
     298            RemoveProject(selectedProject); 
     299          },
    256300          finallyCallback: () => {
    257301            removeButton.Enabled = true;
    258302          });
     303      } else {
     304        removeButton.Enabled = true;
    259305      }
    260306    }
     
    268314      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
    269315        action: () => {
     316          //if (selectedProject != null && selectedProject.Id == Guid.Empty)
     317          //  SelectedProject = HiveAdminClient.Instance.GetAvailableProjectAncestors(selectedProject.Id).LastOrDefault();
    270318          var projectsToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
    271319          foreach (var project in projectsToSave)
    272320            project.Store();
     321         
    273322          UpdateProjects();
    274323        },
     
    278327    }
    279328
    280     private void projectsTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
    281       ChangeSelectedProjectNode(e.Node);
    282 
    283       //if (projectView.Content != null)
    284       //  projectView.Content.PropertyChanged -= ProjectViewContent_PropertyChanged;
    285 
    286       projectView.Content = selectedProject;
    287       projectPermissionsView.Content = selectedProject;
    288       projectResourcesView.Content = selectedProject;
    289 
    290       //if (selectedProject != null)
    291       //  selectedProject.PropertyChanged += ProjectViewContent_PropertyChanged;
     329    private void projectsTreeView_MouseDown(object sender, MouseEventArgs e) {
     330      var node = projectsTreeView.GetNodeAt(e.Location);
     331      if (node == null) return;
     332      var p = (Project)node.Tag;
     333      if(!HiveAdminClient.Instance.DisabledParentProjects.Contains(p)) ChangeSelectedProjectNode(node);
     334    }
     335
     336    private void projectsTreeView_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
     337      e.Cancel = true;
    292338    }
    293339
    294340    private void projectsTreeView_DragDrop(object sender, DragEventArgs e) {
     341      if (e.Effect == DragDropEffects.None) return;
     342
    295343      var sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
    296344      if (sourceNode == null) return;
    297       var sourceResource = ((Project)sourceNode.Tag);
    298       if (sourceResource == null) return;
     345      var sourceProject = ((Project)sourceNode.Tag);
     346      if (sourceProject == null) return;
    299347
    300348      var treeView = (TreeView)sender;
     
    304352      var targetNode = treeView.GetNodeAt(targetPoint);
    305353
    306       if (sourceNode == targetNode) return;
    307354      var targetProject = (targetNode != null) ? (Project)targetNode.Tag : null;
    308355
    309       if(targetProject != null && targetProject.Id == Guid.Empty) {
     356      if (!HiveAdminClient.Instance.CheckParentChange(sourceProject, targetProject)) {
    310357        MessageBox.Show(
    311           "You cannot drag projects to a not yet stored project.",
     358          "You cannot drag projects to this project.",
    312359          "HeuristicLab Hive Administrator",
    313360          MessageBoxButtons.OK,
    314361          MessageBoxIcon.Information);
    315             return;
     362        return;
    316363      }
    317364
     
    320367      } else {
    321368        sourceNode.Parent.Nodes.Remove(sourceNode);
    322         sourceResource.ParentProjectId = null;
     369        sourceProject.ParentProjectId = null;
    323370      }
    324371
     
    327374      } else if(targetProject.Id != Guid.Empty) {
    328375        targetNode.Nodes.Add(sourceNode);
    329         sourceResource.ParentProjectId = targetProject.Id;
    330       }
    331 
    332       selectedProject = sourceResource;
     376        sourceProject.ParentProjectId = targetProject.Id;
     377      }
     378
     379      SelectedProject = sourceProject;
    333380      OnContentChanged();
    334381    }
     
    340387    }
    341388
    342     private void projectsTreeView_DragEnter(object sender, DragEventArgs e) {
     389    private void projectsTreeView_DragEnterOver(object sender, DragEventArgs e) {
    343390      e.Effect = DragDropEffects.Move;
    344     }
    345 
    346     private void projectsTreeView_DragOver(object sender, DragEventArgs e) {
    347       e.Effect = DragDropEffects.Move;
     391
     392      var sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
     393      var sourceProject = ((Project)sourceNode.Tag);
     394
     395      var targetPoint = projectsTreeView.PointToClient(new Point(e.X, e.Y));
     396      var targetNode = projectsTreeView.GetNodeAt(targetPoint);
     397      var targetProject = (targetNode != null) ? (Project)targetNode.Tag : null;
     398
     399      if ((!IsAdmin() && (targetNode == null || targetProject == null))
     400      || sourceNode == null
     401      || sourceProject == null
     402      || sourceNode == targetNode
     403      || !HiveAdminClient.Instance.CheckParentChange(sourceProject, targetProject)) {
     404        e.Effect = DragDropEffects.None;
     405      }
    348406    }
    349407
     
    354412
    355413    #region Helpers
    356     private void ResetTreeNodes(TreeNodeCollection nodes, Color c1, Color c2, bool resetText) {
    357       foreach (TreeNode n in nodes) {
    358         var pro = ((Project)n.Tag);
    359         if (n.BackColor.Equals(c1)) {
    360           n.BackColor = c2;
    361         }
    362         if (resetText) {
    363           n.Text = pro.Name;
    364 
    365           if (pro.Id == Guid.Empty) {
    366             n.Text += " [not stored]";
    367           } else if (pro.Modified) {
    368             n.Text += " [changes not stored]";
    369           }
    370         }
    371         if (n.Nodes.Count > 0) {
    372           ResetTreeNodes(n.Nodes, c1, c2, resetText);
    373         }
    374       }
    375     }
    376 
    377     private void ChangeSelectedProjectNode(TreeNode projectNode) {
    378       selectedProject = (Project)projectNode.Tag;
    379       ResetTreeNodes(projectsTreeView.Nodes, selectedColor, Color.Transparent, true);
    380       projectNode.BackColor = selectedColor;
    381       projectNode.Text += " [selected]";
    382     }
    383 
    384     private Project BuildProjectTree(IEnumerable<Project> projects) {
     414    private void BuildProjectTree(IEnumerable<Project> projects) {
    385415      projectsTreeView.Nodes.Clear();
    386       if (!projects.Any()) return null;
    387 
     416      if (!projects.Any()) return;
     417
     418      var disabledParentProjects = HiveAdminClient.Instance.DisabledParentProjects;
    388419      var mainProjects = new HashSet<Project>(projects.Where(x => x.ParentProjectId == null));
    389       var parentedMainProjects = new HashSet<Project>(projects
    390         .Where(x => x.ParentProjectId.HasValue
    391         && !projects.Select(y => y.Id).Contains(x.ParentProjectId.Value)));
    392             mainProjects.UnionWith(parentedMainProjects);
    393       var subProbjects = new HashSet<Project>(projects.Except(mainProjects));
     420      //var parentedMainProjects = new HashSet<Project>(projects
     421      //  .Where(x => x.ParentProjectId.HasValue
     422      //  && !projects.Select(y => y.Id).Contains(x.ParentProjectId.Value)));
     423      //mainProjects.UnionWith(parentedMainProjects);
     424      var mainDisabledParentProjects = new HashSet<Project>(disabledParentProjects.Where(x => x.ParentProjectId == null || x.ParentProjectId == Guid.Empty));
     425      mainProjects.UnionWith(mainDisabledParentProjects);
     426      var subProbjects = new HashSet<Project>(projects.Union(disabledParentProjects).Except(mainProjects));
    394427
    395428      var stack = new Stack<Project>(mainProjects.OrderByDescending(x => x.Name));
    396       if (selectedProject != null) selectedProject = projects.Where(x => x.Id == selectedProject.Id).FirstOrDefault();
     429      if (selectedProject != null) SelectedProject = projects.Where(x => x.Id == selectedProject.Id).FirstOrDefault();
    397430      bool nodeSelected = false;
    398431
    399432      TreeNode currentNode = null;
    400433      Project currentProject = null;
    401      
     434
    402435      while (stack.Any()) {
    403436        var newProject = stack.Pop();
    404437        var newNode = new TreeNode(newProject.Name) { Tag = newProject };
    405 
    406         if (newProject.Id == Guid.Empty) {
    407           newNode.Text += " [not stored]";
    408         } else if(newProject.Modified) {
    409           newNode.Text += " [changes not stored]";
    410         }
    411         if (selectedProject == null) {
    412           selectedProject = newProject;
    413         }
    414         if (newProject.Id == selectedProject.Id && !nodeSelected) {
    415           newNode.BackColor = selectedColor;
    416           newNode.Text += " [selected]";
     438        StyleTreeNode(newNode, newProject);
     439     
     440        if (selectedProject == null && !disabledParentProjects.Contains(newProject)) {
     441          SelectedProject = newProject;
     442        }
     443        if (!nodeSelected && selectedProject != null && selectedProject.Id == newProject.Id) {
     444          newNode.BackColor = selectedBackColor;
     445          newNode.ForeColor = selectedForeColor;
     446          newNode.Text += SELECTED_TAG;
    417447          nodeSelected = true;
    418448        }
     
    435465
    436466        newNode.SelectedImageIndex = newNode.ImageIndex;
     467
     468        if (disabledParentProjects.Contains(newProject)) {
     469          newNode.Checked = false;
     470          newNode.ForeColor = grayTextColor;
     471        }
    437472
    438473        var childProjects = subProbjects.Where(x => x.ParentProjectId == newProject.Id);
     
    448483
    449484      projectsTreeView.ExpandAll();
    450 
    451       return selectedProject;
     485    }
     486
     487    private void StyleTreeNode(TreeNode n, Project p) {
     488      n.Text = p.Name;
     489      n.BackColor = Color.Transparent;
     490      n.ForeColor = Color.Black;
     491
     492      if (HiveAdminClient.Instance.DisabledParentProjects.Select(x => x.Id).Contains(p.Id)) {
     493        n.ForeColor = grayTextColor;
     494      } else if (p.Id == Guid.Empty) {
     495        n.Text += NOT_STORED_TAG;
     496      } else if (p.Modified) {
     497        n.Text += CHANGES_NOT_STORED_TAG;
     498      }
     499    }
     500
     501    private void ResetTreeNodes(TreeNodeCollection nodes) {
     502      foreach (TreeNode n in nodes) {
     503        StyleTreeNode(n, (Project)n.Tag);
     504        if (n.Nodes.Count > 0) {
     505          ResetTreeNodes(n.Nodes);
     506        }
     507      }
     508    }
     509
     510    private void ChangeSelectedProject(Project project) {
     511      projectView.Content = project;
     512      projectPermissionsView.Content = project;
     513      projectResourcesView.Content = project;
     514      projectJobsView.Content = project;
     515      selectedProject = project;
     516      SetEnabledStateOfControls();
     517    }
     518
     519    private void ChangeSelectedProjectNode(TreeNode projectNode) {
     520      if (projectNode == null) return;
     521      SelectedProject = (Project)projectNode.Tag;
     522      ResetTreeNodes(projectsTreeView.Nodes);
     523      projectNode.BackColor = selectedBackColor;
     524      projectNode.ForeColor = selectedForeColor;
     525      projectNode.Text += SELECTED_TAG;
    452526    }
    453527
     
    462536
    463537    private void RemoveProject(Project project) {
    464       if (project == null || project.Id == Guid.Empty) return;
     538      if (project == null) return;
    465539
    466540      try {
    467         HiveAdminClient.Delete(project);
    468         Content.Remove(selectedProject);
     541        if (project.Id != Guid.Empty) {
     542          var projectsToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
     543          foreach (var p in projectsToSave)
     544            p.Store();
     545
     546          SelectedProject = HiveAdminClient.Instance.GetAvailableProjectAncestors(project.Id).LastOrDefault();
     547          HiveAdminClient.Delete(project);         
     548          UpdateProjects();
     549        } else {
     550          Content.Remove(project);
     551        }
    469552      } catch (AnonymousUserException) {
    470553        ShowHiveInformationDialog();
     
    474557    private bool IsAuthorized(Project project) {
    475558      return project != null && UserInformation.Instance.UserExists;
    476           //&& (project.OwnerUserId == UserInformation.Instance.User.Id || HiveRoles.CheckAdminUserPermissions());
    477559    }
    478560
Note: See TracChangeset for help on using the changeset viewer.