Ignore:
Timestamp:
09/25/19 16:41:04 (3 years ago)
Author:
jkarder
Message:

#3024: refactored ProjectView and added button to refresh users

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectView.cs

    r17223 r17268  
    2828using HeuristicLab.Core.Views;
    2929using HeuristicLab.MainForm;
     30using Tpl = System.Threading.Tasks;
    3031
    3132namespace HeuristicLab.Clients.Hive.Administrator.Views {
     
    3334  [Content(typeof(Project), IsDefaultView = true)]
    3435  public partial class ProjectView : ItemView {
    35     private readonly object locker = new object();
    36 
    3736    public new Project Content {
    3837      get { return (Project)base.Content; }
     
    4544      AccessClient.Instance.Refreshing += AccessClient_Instance_Refreshing;
    4645      AccessClient.Instance.Refreshed += AccessClient_Instance_Refreshed;
     46
     47      UpdateUsers();
    4748    }
    4849
     
    5859    }
    5960
    60     protected void RegisterControlEvents() {
    61       nameTextBox.TextChanged += nameTextBox_TextChanged;
    62       nameTextBox.Validating += nameTextBox_Validating;
    63       descriptionTextBox.TextChanged += descriptionTextBox_TextChanged;
    64       ownerComboBox.SelectedIndexChanged += ownerComboBox_SelectedIndexChanged;
    65       startDateTimePicker.ValueChanged += startDateTimePicker_ValueChanged;
    66       endDateTimePicker.ValueChanged += endDateTimePicker_ValueChanged;
    67       indefiniteCheckBox.CheckedChanged += indefiniteCheckBox_CheckedChanged;
    68     }
    69 
    70     protected void DeregisterControlEvents() {
    71       nameTextBox.TextChanged -= nameTextBox_TextChanged;
    72       nameTextBox.Validating -= nameTextBox_Validating;
    73       descriptionTextBox.TextChanged -= descriptionTextBox_TextChanged;
    74       ownerComboBox.SelectedIndexChanged -= ownerComboBox_SelectedIndexChanged;
    75       startDateTimePicker.ValueChanged -= startDateTimePicker_ValueChanged;
    76       endDateTimePicker.ValueChanged -= endDateTimePicker_ValueChanged;
    77       indefiniteCheckBox.CheckedChanged -= indefiniteCheckBox_CheckedChanged;
    78     }
    79 
    8061    protected override void OnContentChanged() {
    8162      base.OnContentChanged();
    82       DeregisterControlEvents();
     63      UpdateView();
     64    }
     65
     66    private void UpdateView() {
    8367      if (Content == null) {
    8468        idTextBox.Clear();
     
    9478        nameTextBox.Text = Content.Name;
    9579        descriptionTextBox.Text = Content.Description;
    96 
    97         if (AccessClient.Instance.UsersAndGroups != null) {
    98           var users = AccessClient.Instance.UsersAndGroups.OfType<LightweightUser>();
    99           if (!Content.ParentProjectId.HasValue) users = users.Where(x => x.Roles.Select(y => y.Name).Contains(HiveRoles.Administrator));
    100           var projectOwnerId = Content.OwnerUserId;
    101           ownerComboBox.DataSource = users.OrderBy(x => x.UserName).ToList();
    102           ownerComboBox.SelectedItem = users.FirstOrDefault(x => x.Id == projectOwnerId);
    103         }
    104 
     80        ownerComboBox.SelectedItem = AccessClient.Instance.UsersAndGroups.OfType<LightweightUser>().SingleOrDefault(x => x.Id == Content.OwnerUserId);
    10581        createdTextBox.Text = Content.DateCreated.ToString("ddd, dd.MM.yyyy, HH:mm:ss");
    10682        startDateTimePicker.Value = Content.StartDate;
    107 
     83        endDateTimePicker.Value = Content.EndDate.GetValueOrDefault(Content.StartDate);
    10884        indefiniteCheckBox.Checked = !Content.EndDate.HasValue;
    109         if (!indefiniteCheckBox.Checked) endDateTimePicker.Value = Content.EndDate.Value;
    110         else endDateTimePicker.Value = Content.StartDate;
    111         endDateTimePicker.Enabled = !indefiniteCheckBox.Checked;
    112       }
    113       SetEnabledStateOfControls();
    114       RegisterControlEvents();
    115     }
    116 
    117     protected override void SetEnabledStateOfControls() {
    118       base.SetEnabledStateOfControls();
    119       bool enabled = Content != null && !Locked && !ReadOnly;
    120       nameTextBox.Enabled = enabled;
    121       descriptionTextBox.Enabled = enabled;
    122       ownerComboBox.Enabled = enabled;
    123       createdTextBox.Enabled = enabled;
    124       startDateTimePicker.Enabled = enabled;
    125       endDateTimePicker.Enabled = enabled && Content.EndDate.HasValue;
    126       indefiniteCheckBox.Enabled = enabled;
    127 
    128       if (Content != null) {
    129         //var parentProject = HiveAdminClient.Instance.GetAvailableProjectAncestors(Content.Id).LastOrDefault();
    130         var parentProject = HiveAdminClient.Instance.Projects.FirstOrDefault(x => x.Id == Content.ParentProjectId);
    131         if ((!IsAdmin() && (parentProject == null || parentProject.EndDate.HasValue))
    132            || (IsAdmin() && parentProject != null && parentProject.EndDate.HasValue)) {
    133           indefiniteCheckBox.Enabled = false;
    134         }
    135 
    136         if (Content.Id != Guid.Empty && !IsAdmin() && !HiveAdminClient.Instance.CheckOwnershipOfParentProject(Content, UserInformation.Instance.User.Id)) {
    137           ownerComboBox.Enabled = false;
    138           startDateTimePicker.Enabled = false;
    139           endDateTimePicker.Enabled = false;
    140           indefiniteCheckBox.Enabled = false;
    141         }
    142       }
    143     }
    144     #endregion
    145 
    146     #region Event Handlers
    147     private void Content_PropertyChanged(object sender, PropertyChangedEventArgs e) {
    148       if (InvokeRequired) Invoke((Action<object, PropertyChangedEventArgs>)Content_PropertyChanged, sender, e);
    149       else OnContentChanged();
    150     }
    151 
    152     private void AccessClient_Instance_Refreshing(object sender, EventArgs e) {
    153       if (InvokeRequired) Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshing, sender, e);
    154       else {
    155         Progress.Show(this, "Refreshing ...", ProgressMode.Indeterminate);
    156         SetEnabledStateOfControls();
    157       }
    158     }
    159 
    160     private void AccessClient_Instance_Refreshed(object sender, EventArgs e) {
    161       if (InvokeRequired) Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshed, sender, e);
    162       else {
    163         Progress.Hide(this);
    164         SetEnabledStateOfControls();
    165       }
    166     }
    167 
    168     private async void ProjectView_Load(object sender, EventArgs e) {
    169       await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
    170         action: () => UpdateUsers(),
    171         finallyCallback: () => {
    172           ownerComboBox.SelectedIndexChanged -= ownerComboBox_SelectedIndexChanged;
    173           var users = AccessClient.Instance.UsersAndGroups.OfType<LightweightUser>();
    174           if (Content != null && !Content.ParentProjectId.HasValue) users = users.Where(x => x.Roles.Select(y => y.Name).Contains(HiveRoles.Administrator));
    175           var projectOwnerId = Content != null ? Content.OwnerUserId : (Guid?)null;
    176           ownerComboBox.DataSource = users.OrderBy(x => x.UserName).ToList();
    177           ownerComboBox.SelectedItem = projectOwnerId.HasValue ? users.FirstOrDefault(x => x.Id == projectOwnerId) : null;
    178           ownerComboBox.SelectedIndexChanged += ownerComboBox_SelectedIndexChanged;
    179         });
    180     }
    181 
    182     private void ProjectView_Disposed(object sender, EventArgs e) {
    183       AccessClient.Instance.Refreshed -= AccessClient_Instance_Refreshed;
    184       AccessClient.Instance.Refreshing -= AccessClient_Instance_Refreshing;
    185     }
    186 
    187     private void nameTextBox_Validating(object sender, CancelEventArgs e) {
    188       if (string.IsNullOrEmpty(nameTextBox.Text)) {
    189         MessageBox.Show(
    190           "Project must have a name.",
    191           "HeuristicLab Hive Administrator",
    192           MessageBoxButtons.OK,
    193           MessageBoxIcon.Error);
    194         e.Cancel = true;
    195       }
    196     }
    197 
    198     private void nameTextBox_TextChanged(object sender, EventArgs e) {
    199       if (Content != null && Content.Name != nameTextBox.Text) {
    200         DeregisterContentEvents();
    201         Content.Name = nameTextBox.Text;
    202         RegisterContentEvents();
    203       }
    204     }
    205 
    206     private void descriptionTextBox_TextChanged(object sender, EventArgs e) {
    207       if (Content != null && Content.Description != descriptionTextBox.Text) {
    208         DeregisterContentEvents();
    209         Content.Description = descriptionTextBox.Text;
    210         RegisterContentEvents();
    211       }
    212     }
    213 
    214     private void ownerComboBox_SelectedIndexChanged(object sender, EventArgs e) {
    215       var selectedItem = (LightweightUser)ownerComboBox.SelectedItem;
    216       var selectedOwnerUserId = selectedItem != null ? selectedItem.Id : Guid.Empty;
    217       if (Content != null && Content.OwnerUserId != selectedOwnerUserId) {
    218         DeregisterContentEvents();
    219         Content.OwnerUserId = selectedOwnerUserId;
    220         RegisterContentEvents();
    221       }
    222     }
    223 
    224     private void startDateTimePicker_ValueChanged(object sender, EventArgs e) {
    225       if (Content == null) return;
    226       startDateTimePicker.ValueChanged -= startDateTimePicker_ValueChanged;
    227 
    228       if (!IsAdmin()) {
    229         var parentProject = HiveAdminClient.Instance.GetAvailableProjectAncestors(Content.Id).LastOrDefault();
    230         if (parentProject != null) {
    231           if (startDateTimePicker.Value < parentProject.StartDate)
    232             startDateTimePicker.Value = parentProject.StartDate;
    233         } else {
    234           startDateTimePicker.Value = Content.StartDate;
    235         }
    236       }
    237 
    238       if (!Content.EndDate.HasValue || startDateTimePicker.Value > Content.EndDate)
    239         endDateTimePicker.Value = startDateTimePicker.Value;
    240       if (Content.StartDate != startDateTimePicker.Value) {
    241         DeregisterContentEvents();
    242         Content.StartDate = startDateTimePicker.Value;
    243         RegisterContentEvents();
    244       }
    245 
    246       startDateTimePicker.ValueChanged += startDateTimePicker_ValueChanged;
    247     }
    248 
    249     private void endDateTimePicker_ValueChanged(object sender, EventArgs e) {
    250       if (Content == null) return;
    251       endDateTimePicker.ValueChanged -= endDateTimePicker_ValueChanged;
    252 
    253       if (!IsAdmin()) {
    254         var parentProject = HiveAdminClient.Instance.GetAvailableProjectAncestors(Content.Id).LastOrDefault();
    255         if (parentProject != null) {
    256           if (parentProject.EndDate.HasValue && endDateTimePicker.Value > parentProject.EndDate.Value) {
    257             endDateTimePicker.Value = parentProject.EndDate.Value;
    258           }
    259         } else if (Content.EndDate.HasValue) {
    260           endDateTimePicker.Value = Content.EndDate.Value;
    261         }
    262       }
    263 
    264       if (endDateTimePicker.Value < startDateTimePicker.Value)
    265         endDateTimePicker.Value = startDateTimePicker.Value;
    266       if (Content.EndDate != endDateTimePicker.Value) {
    267         DeregisterContentEvents();
    268         Content.EndDate = endDateTimePicker.Value;
    269         RegisterContentEvents();
    270       }
    271 
    272       endDateTimePicker.ValueChanged += endDateTimePicker_ValueChanged;
    273     }
    274 
    275     private void indefiniteCheckBox_CheckedChanged(object sender, EventArgs e) {
    276       if (Content == null) return;
    277 
    278       var newEndDate = indefiniteCheckBox.Checked ? (DateTime?)null : endDateTimePicker.Value;
    279       endDateTimePicker.Enabled = !indefiniteCheckBox.Checked;
    280       if (Content.EndDate != newEndDate) {
    281         DeregisterContentEvents();
    282         Content.EndDate = newEndDate;
    283         RegisterContentEvents();
    284       }
    285     }
    286     #endregion
    287 
    288     #region Helpers
     85      }
     86    }
     87
     88    private async Tpl.Task UpdateUsersAsync() {
     89      await Tpl.Task.Run(UpdateUsers);
     90    }
     91
    28992    private void UpdateUsers() {
     93      // deregister handler to avoid change of content's owner when data source is updated
     94      ownerComboBox.SelectedIndexChanged -= ownerComboBox_SelectedIndexChanged;
    29095      try {
    291         AccessClient.Instance.Refresh();
     96        ownerComboBox.DataSource = null;
     97        SecurityExceptionUtil.TryAndReportSecurityExceptions(AccessClient.Instance.Refresh);
     98        ownerComboBox.DataSource = AccessClient.Instance.UsersAndGroups.OfType<LightweightUser>().OrderBy(x => x.UserName).ToList();
    29299      } catch (AnonymousUserException) {
    293100        ShowHiveInformationDialog();
    294       }
    295     }
    296 
    297     private bool IsAdmin() {
    298       return HiveRoles.CheckAdminUserPermissions();
     101      } finally {
     102        ownerComboBox.SelectedIndexChanged += ownerComboBox_SelectedIndexChanged;
     103      }
    299104    }
    300105
     
    307112      }
    308113    }
     114
     115    protected override void SetEnabledStateOfControls() {
     116      base.SetEnabledStateOfControls();
     117
     118      bool enabled = Content != null && !Locked && !ReadOnly;
     119
     120      nameTextBox.Enabled = enabled;
     121      descriptionTextBox.Enabled = enabled;
     122      ownerComboBox.Enabled = enabled;
     123      refreshButton.Enabled = enabled;
     124      createdTextBox.Enabled = enabled;
     125      startDateTimePicker.Enabled = enabled;
     126      endDateTimePicker.Enabled = enabled && Content.EndDate.HasValue && Content.EndDate > Content.StartDate;
     127      indefiniteCheckBox.Enabled = enabled;
     128
     129      if (Content == null) return;
     130
     131      var parentProject = HiveAdminClient.Instance.Projects.SingleOrDefault(x => x.Id == Content.ParentProjectId);
     132      if (parentProject != null && parentProject.EndDate.HasValue)
     133        indefiniteCheckBox.Enabled = false;
     134
     135      if (Content.Id == Guid.Empty) return; // newly created project
     136      if (HiveRoles.CheckAdminUserPermissions()) return; // admins can edit any project
     137      if (HiveAdminClient.Instance.CheckOwnershipOfParentProject(Content, UserInformation.Instance.User.Id)) return; // owner can edit project
     138
     139      // project was already created and user is neither admin nor owner
     140      ownerComboBox.Enabled = false;
     141      startDateTimePicker.Enabled = false;
     142      endDateTimePicker.Enabled = false;
     143      indefiniteCheckBox.Enabled = false;
     144    }
    309145    #endregion
     146
     147    #region Event Handlers
     148    private void Content_PropertyChanged(object sender, PropertyChangedEventArgs e) {
     149      UpdateView();
     150    }
     151
     152    private void nameTextBox_TextChanged(object sender, EventArgs e) {
     153      if (Content == null || Content.Name == nameTextBox.Text) return;
     154      Content.Name = nameTextBox.Text;
     155    }
     156
     157    private void nameTextBox_Validating(object sender, CancelEventArgs e) {
     158      if (!string.IsNullOrEmpty(nameTextBox.Text)) return;
     159
     160      MessageBox.Show("Project must have a name.", "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Error);
     161      e.Cancel = true;
     162    }
     163
     164    private void descriptionTextBox_TextChanged(object sender, EventArgs e) {
     165      if (Content == null || Content.Description == descriptionTextBox.Text) return;
     166      Content.Description = descriptionTextBox.Text;
     167    }
     168
     169    private void ownerComboBox_SelectedIndexChanged(object sender, EventArgs e) {
     170      if (Content == null) return;
     171
     172      var selectedItem = (LightweightUser)ownerComboBox.SelectedItem;
     173      var selectedOwnerUserId = selectedItem != null ? selectedItem.Id : Guid.Empty;
     174      if (Content.OwnerUserId == selectedOwnerUserId) return;
     175
     176      Content.OwnerUserId = selectedOwnerUserId;
     177    }
     178
     179    private void startDateTimePicker_ValueChanged(object sender, EventArgs e) {
     180      if (Content == null || Content.StartDate == startDateTimePicker.Value) return;
     181
     182      string errorMessage = string.Empty;
     183
     184      var parentProject = HiveAdminClient.Instance.Projects.SingleOrDefault(x => x.Id == Content.ParentProjectId);
     185      if (parentProject != null) {
     186        if (startDateTimePicker.Value < parentProject.StartDate) {
     187          errorMessage = "Project cannot start before its parent project has started.";
     188        } else if (startDateTimePicker.Value > parentProject.EndDate) {
     189          errorMessage = "Project cannot start after its parent project has ended.";
     190        }
     191      }
     192
     193      if (startDateTimePicker.Value > endDateTimePicker.Value) {
     194        errorMessage = "Project cannot start after it ends.";
     195      }
     196
     197      if (!string.IsNullOrEmpty(errorMessage)) {
     198        MessageBox.Show(errorMessage, "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Error);
     199        startDateTimePicker.Value = Content.StartDate;
     200      }
     201
     202      Content.StartDate = startDateTimePicker.Value;
     203    }
     204
     205    private void endDateTimePicker_ValueChanged(object sender, EventArgs e) {
     206      if (Content == null || Content.EndDate == endDateTimePicker.Value || Content.StartDate == endDateTimePicker.Value) return;
     207
     208      string errorMessage = string.Empty;
     209
     210      var parentProject = HiveAdminClient.Instance.Projects.SingleOrDefault(x => x.Id == Content.ParentProjectId);
     211      if (parentProject != null) {
     212        if (endDateTimePicker.Value > parentProject.EndDate) {
     213          errorMessage = "Project cannot end after its parent project has ended.";
     214        } else if (endDateTimePicker.Value < parentProject.StartDate) {
     215          errorMessage = "Project cannot end before its parent project has started.";
     216        }
     217      }
     218
     219      if (endDateTimePicker.Value < startDateTimePicker.Value) {
     220        errorMessage = "Project cannot end after it starts.";
     221      }
     222
     223      if (!string.IsNullOrEmpty(errorMessage)) {
     224        MessageBox.Show(errorMessage, "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Error);
     225        endDateTimePicker.Value = Content.EndDate.GetValueOrDefault(Content.StartDate);
     226      }
     227
     228      Content.EndDate = endDateTimePicker.Value;
     229    }
     230
     231    private void indefiniteCheckBox_CheckedChanged(object sender, EventArgs e) {
     232      if (Content == null) return;
     233
     234      var newEndDate = indefiniteCheckBox.Checked ? (DateTime?)null : endDateTimePicker.Value;
     235
     236      if (Content.EndDate == newEndDate) return;
     237      Content.EndDate = newEndDate;
     238
     239      endDateTimePicker.Enabled = !indefiniteCheckBox.Checked;
     240    }
     241
     242    private void AccessClient_Instance_Refreshing(object sender, EventArgs e) {
     243      if (InvokeRequired) {
     244        Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshing, sender, e);
     245        return;
     246      }
     247
     248      Progress.Show(this, "Refreshing ...", ProgressMode.Indeterminate);
     249      SetEnabledStateOfControls();
     250    }
     251
     252    private void AccessClient_Instance_Refreshed(object sender, EventArgs e) {
     253      if (InvokeRequired) {
     254        Invoke((Action<object, EventArgs>)AccessClient_Instance_Refreshed, sender, e);
     255        return;
     256      }
     257
     258      Progress.Hide(this);
     259      SetEnabledStateOfControls();
     260    }
     261    #endregion
     262
     263    private async void refreshButton_Click(object sender, EventArgs e) {
     264      Locked = true;
     265      try {
     266        await UpdateUsersAsync();
     267        UpdateView();
     268      } finally {
     269        Locked = false;
     270      }
     271    }
    310272  }
    311273}
Note: See TracChangeset for help on using the changeset viewer.