Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ScheduleView.cs @ 15933

Last change on this file since 15933 was 15813, checked in by jzenisek, 7 years ago

#2839: improved HiveAdmin interactions:

  • collaps groups with slaves only
  • update scheduleView only if currently visible
  • made schedule scrollable for non-admins
  • changed selection backcolor
  • fixed add/delete project permission bug for non-admins
File size: 15.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using Calendar;
28using HeuristicLab.Core;
29using HeuristicLab.Core.Views;
30using HeuristicLab.MainForm;
31
32namespace HeuristicLab.Clients.Hive.Administrator.Views {
33  [View("Schedule View")]
34  [Content(typeof(IItemList<Downtime>), IsDefaultView = true)]
35  public partial class ScheduleView : ItemView {
36    public new IItemList<Downtime> Content {
37      get { return (IItemList<Downtime>)base.Content; }
38      set { base.Content = value; }
39    }
40
41    public List<HiveDowntime> offlineTimes = new List<HiveDowntime>();
42
43    //delegate fired, if a dialog is being closed
44    public delegate void OnDialogClosedDelegate(RecurrentEvent e);
45
46    public ScheduleView() {
47      InitializeComponent();
48      InitCalender();
49    }
50
51    private void InitCalender() {
52      dvOnline.StartDate = DateTime.Now;
53      dvOnline.OnNewAppointment += new EventHandler<NewAppointmentEventArgs>(dvOnline_OnNewAppointment);
54      dvOnline.OnResolveAppointments += new EventHandler<ResolveAppointmentsEventArgs>(dvOnline_OnResolveAppointments);
55    }
56
57    private void dvOnline_OnResolveAppointments(object sender, ResolveAppointmentsEventArgs e) {
58      List<HiveDowntime> apps = new List<HiveDowntime>();
59
60      foreach (HiveDowntime app in offlineTimes) {
61        if (app.StartDate >= e.StartDate && app.StartDate <= e.EndDate && !app.Deleted) {
62          apps.Add(app);
63        }
64      }
65
66      e.Appointments.Clear();
67      foreach (HiveDowntime app in apps) {
68        e.Appointments.Add(app);
69      }
70    }
71
72    private void dvOnline_OnNewAppointment(object sender, NewAppointmentEventArgs e) {
73      HiveDowntime downtime = new HiveDowntime();
74
75      downtime.StartDate = e.StartDate;
76      downtime.EndDate = e.EndDate;
77      offlineTimes.Add(downtime);
78    }
79
80    private void UpdateCalendarFromContent() {
81      offlineTimes.Clear();
82      if (Content != null) {
83        foreach (Downtime downtime in Content) {
84          offlineTimes.Add(ToHiveDowntime(downtime));
85        }
86      }
87      dvOnline.Invalidate();
88    }
89
90    private bool CreateDowntime(DowntimeType dtType) {
91      DateTime from, to;
92
93      if (!string.IsNullOrEmpty(dtpFrom.Text) && !string.IsNullOrEmpty(dtpTo.Text)) {
94        if (chbade.Checked) {
95          //whole day appointment, only dates are visible
96          if (DateTime.TryParse(dtpFrom.Text, out from) && DateTime.TryParse(dtpTo.Text, out to) && from <= to)
97            offlineTimes.Add(CreateDowntime(from, to.AddDays(1), true, dtType));
98          else
99            MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
100        } else if (!string.IsNullOrEmpty(txttimeFrom.Text) && !string.IsNullOrEmpty(txttimeTo.Text)) {
101          //Timeframe appointment
102          if (DateTime.TryParse(dtpFrom.Text + " " + txttimeFrom.Text, out from) && DateTime.TryParse(dtpTo.Text + " " + txttimeTo.Text, out to) && from < to) {
103            if (from.Date == to.Date)
104              offlineTimes.Add(CreateDowntime(from, to, false, dtType));
105            else {
106              //more than 1 day selected
107              while (from.Date != to.Date) {
108                offlineTimes.Add(CreateDowntime(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false, dtType));
109                from = from.AddDays(1);
110              }
111              offlineTimes.Add(CreateDowntime(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false, dtType));
112            }
113          } else
114            MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
115        }
116        dvOnline.Invalidate();
117        return true;
118      } else {
119        MessageBox.Show("Error creating downtime, please fill out all textboxes!", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
120        return false;
121      }
122    }
123
124    private HiveDowntime CreateDowntime(DateTime startDate, DateTime endDate, bool allDay, DowntimeType downtimeType) {
125      HiveDowntime downtime = new HiveDowntime();
126      downtime.StartDate = startDate;
127      downtime.EndDate = endDate;
128      downtime.AllDayEvent = allDay;
129      downtime.BorderColor = Color.Red;
130      downtime.Locked = true;
131      downtime.Subject = downtimeType.ToString();
132      downtime.Recurring = false;
133      return downtime;
134    }
135
136    private HiveDowntime CreateDowntime(DateTime startDate, DateTime endDate, bool allDay, bool recurring, Guid recurringId, DowntimeType downtimeType) {
137      HiveDowntime downtime = new HiveDowntime();
138      downtime.StartDate = startDate;
139      downtime.EndDate = endDate;
140      downtime.AllDayEvent = allDay;
141      downtime.BorderColor = Color.Red;
142      downtime.Locked = true;
143      downtime.Subject = downtimeType.ToString();
144      downtime.Recurring = recurring;
145      downtime.RecurringId = recurringId;
146      return downtime;
147    }
148
149    private void DeleteRecurringDowntime(Guid recurringId) {
150      foreach (HiveDowntime downtime in offlineTimes) {
151        if (downtime.RecurringId == recurringId) {
152          downtime.Deleted = true;
153        }
154      }
155    }
156
157    private void ChangeRecurrenceDowntime(Guid recurringId) {
158      int hourfrom = int.Parse(txttimeFrom.Text.Substring(0, txttimeFrom.Text.IndexOf(':')));
159      int hourTo = int.Parse(txttimeTo.Text.Substring(0, txttimeTo.Text.IndexOf(':')));
160      List<HiveDowntime> recurringDowntimes = offlineTimes.Where(appointment => ((HiveDowntime)appointment).RecurringId == recurringId).ToList();
161      recurringDowntimes.ForEach(appointment => appointment.StartDate = new DateTime(appointment.StartDate.Year, appointment.StartDate.Month, appointment.StartDate.Day, hourfrom, 0, 0));
162      recurringDowntimes.ForEach(appointment => appointment.EndDate = new DateTime(appointment.EndDate.Year, appointment.EndDate.Month, appointment.EndDate.Day, hourTo, 0, 0));
163    }
164
165    public void DialogClosed(RecurrentEvent e) {
166      CreateDailyRecurrenceDowntimes(e.DateFrom, e.DateTo, e.AllDay, e.WeekDays, e.DowntimeType);
167    }
168
169    private void CreateDailyRecurrenceDowntimes(DateTime dateFrom, DateTime dateTo, bool allDay, HashSet<DayOfWeek> daysOfWeek, DowntimeType appointmentType) {
170      DateTime incDate = dateFrom;
171      Guid guid = Guid.NewGuid();
172
173      while (incDate.Date <= dateTo.Date) {
174        if (daysOfWeek.Contains(incDate.Date.DayOfWeek))
175          offlineTimes.Add(CreateDowntime(incDate, new DateTime(incDate.Year, incDate.Month, incDate.Day, dateTo.Hour, dateTo.Minute, 0), allDay, true, guid, appointmentType));
176        incDate = incDate.AddDays(1);
177      }
178
179      dvOnline.Invalidate();
180    }
181
182    private void btbDelete_Click(object sender, EventArgs e) {
183      HiveDowntime selectedDowntime = (HiveDowntime)dvOnline.SelectedAppointment;
184      if (dvOnline.SelectedAppointment != null) {
185        if (!selectedDowntime.Recurring)
186          DeleteDowntime();
187        else {
188          DialogResult res = MessageBox.Show("Delete all events in this series?", "Delete recurrences", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
189          if (res != DialogResult.Yes)
190            DeleteDowntime();
191          else
192            DeleteRecurringDowntime(selectedDowntime.RecurringId);
193        }
194      }
195      dvOnline.Invalidate();
196    }
197
198    private void DeleteDowntime() {
199      try {
200        HiveDowntime downtime = offlineTimes.First(s => s.Equals((HiveDowntime)dvOnline.SelectedAppointment));
201        downtime.Deleted = true;
202      }
203      catch (InvalidOperationException) {
204        // this is a ui bug where a selected all day appointment is not properly selected :-/
205      }
206    }
207
208    #region Register Content Events
209    protected override void DeregisterContentEvents() {
210      base.DeregisterContentEvents();
211    }
212    protected override void RegisterContentEvents() {
213      base.RegisterContentEvents();
214    }
215    #endregion
216
217    protected override void OnContentChanged() {
218      base.OnContentChanged();
219      UpdateCalendarFromContent();
220    }
221
222    protected override void SetEnabledStateOfControls() {
223      base.SetEnabledStateOfControls();
224      bool enabled = Content != null && !Locked;
225      btCreate.Enabled = enabled;
226      btbDelete.Enabled = enabled;
227      btnClearCal.Enabled = enabled;
228      btnRecurrence.Enabled = enabled;
229      btnSaveCal.Enabled = enabled;
230    }
231
232    public virtual void SetEnabledStateOfSchedule(bool state) {
233      if (InvokeRequired) {
234        Invoke(new Action(() => SetEnabledStateOfSchedule(state)));
235      } else {
236        if (Content == null || Locked || ReadOnly) state = false;
237        //groupBox1.Enabled = state;
238        btnClearCal.Enabled = state;
239        btnSaveCal.Enabled = state;
240      }
241    }
242
243    private void btnClearCal_Click(object sender, System.EventArgs e) {
244      foreach (HiveDowntime app in offlineTimes) {
245        app.Deleted = true;
246      }
247      dvOnline.Invalidate();
248    }
249
250    private void chbade_CheckedChanged(object sender, EventArgs e) {
251      txttimeFrom.Visible = !chbade.Checked;
252      txttimeTo.Visible = !chbade.Checked;
253    }
254
255    private void dvOnline_OnSelectionChanged(object sender, EventArgs e) {
256      if (dvOnline.Selection == SelectionType.DateRange) {
257        dtpFrom.Text = dvOnline.SelectionStart.ToShortDateString();
258        dtpTo.Text = dvOnline.SelectionEnd.Date.ToShortDateString();
259        txttimeFrom.Text = dvOnline.SelectionStart.ToShortTimeString();
260        txttimeTo.Text = dvOnline.SelectionEnd.ToShortTimeString();
261        btCreate.Text = "Create Downtime";
262      }
263
264      if (dvOnline.Selection == SelectionType.Appointment) {
265        dtpFrom.Text = dvOnline.SelectedAppointment.StartDate.ToShortDateString();
266        dtpTo.Text = dvOnline.SelectedAppointment.EndDate.ToShortDateString();
267        txttimeFrom.Text = dvOnline.SelectedAppointment.StartDate.ToShortTimeString();
268        txttimeTo.Text = dvOnline.SelectedAppointment.EndDate.ToShortTimeString();
269
270        if (dvOnline.SelectedAppointment.Recurring)
271          //also change the caption of the save button
272          btCreate.Text = "Save changes";
273      }
274      if (dvOnline.Selection == SelectionType.None) {
275        //also change the caption of the save button
276        btCreate.Text = "Create Downtime";
277      }
278    }
279
280    private void mcOnline_DateChanged(object sender, DateRangeEventArgs e) {
281      dvOnline.StartDate = mcOnline.SelectionStart;
282    }
283
284    private void btCreate_Click(object sender, EventArgs e) {
285      if (dvOnline.Selection != SelectionType.Appointment) {
286        DowntimeType dtType;
287        DialogResult result;
288        DowntimeTypeDialog dialog = new DowntimeTypeDialog();
289        result = dialog.ShowDialog(this);
290        dtType = dialog.AppointmentType;
291        dialog.Dispose();
292        if (result == DialogResult.Cancel) return;
293        CreateDowntime(dtType);
294      } else {
295        //now we want to change an existing appointment
296        if (!dvOnline.SelectedAppointment.Recurring) {
297          if (CreateDowntime(GetDowntimeTypeOfSelectedDowntime()))
298            DeleteDowntime();
299        } else {
300          //change recurring appointment
301          //check, if only selected appointment has to change or whole recurrence
302          DialogResult res = MessageBox.Show("Change all events in this series?", "Change recurrences", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
303          if (res != DialogResult.Yes) {
304            if (CreateDowntime(GetDowntimeTypeOfSelectedDowntime()))
305              DeleteDowntime();
306          } else
307            ChangeRecurrenceDowntime(((HiveDowntime)dvOnline.SelectedAppointment).RecurringId);
308        }
309      }
310      dvOnline.Invalidate();
311    }
312
313    private void btnRecurrence_Click(object sender, EventArgs e) {
314      Recurrence recurrence = new Recurrence();
315      recurrence.dialogClosedDelegate = new OnDialogClosedDelegate(this.DialogClosed);
316      recurrence.Show();
317    }
318
319    private void btnSaveCal_Click(object sender, EventArgs e) {
320      if (HiveAdminClient.Instance.DowntimeForResourceId == null || HiveAdminClient.Instance.DowntimeForResourceId == Guid.Empty) {
321        MessageBox.Show("You have to save the group before you can save the schedule. ", "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Stop);
322      } else {
323        List<Downtime> downtimes = new List<Downtime>();
324        foreach (HiveDowntime downtime in offlineTimes) {
325          if (downtime.Deleted && downtime.Id != Guid.Empty) {
326            HiveAdminClient.Delete(ToDowntime(downtime));
327          } else if (downtime.Changed || downtime.Id == null || downtime.Id == Guid.Empty) {
328            Downtime dt = ToDowntime(downtime);
329            downtimes.Add(dt);
330          }
331        }
332        foreach (Downtime dt in downtimes) {
333          dt.Store();
334        }
335      }
336    }
337
338    private HiveDowntime ToHiveDowntime(Downtime downtime) {
339      HiveDowntime hiveDowntime = new HiveDowntime {
340        AllDayEvent = downtime.AllDayEvent,
341        EndDate = downtime.EndDate,
342        StartDate = downtime.StartDate,
343        Recurring = downtime.Recurring,
344        RecurringId = downtime.RecurringId,
345        Deleted = false,
346        BorderColor = Color.Red,
347        Locked = true,
348        Subject = downtime.DowntimeType.ToString(),
349        Changed = downtime.Modified,
350        Id = downtime.Id
351      };
352      return hiveDowntime;
353    }
354
355    private Downtime ToDowntime(HiveDowntime hiveDowntime) {
356      Downtime downtime = new Downtime {
357        AllDayEvent = hiveDowntime.AllDayEvent,
358        EndDate = hiveDowntime.EndDate,
359        StartDate = hiveDowntime.StartDate,
360        Recurring = hiveDowntime.Recurring,
361        RecurringId = hiveDowntime.RecurringId,
362        ResourceId = HiveAdminClient.Instance.DowntimeForResourceId,
363        Id = hiveDowntime.Id,
364        DowntimeType = (DowntimeType)Enum.Parse(typeof(DowntimeType), hiveDowntime.Subject)
365      };
366      return downtime;
367    }
368
369    private DowntimeType GetDowntimeTypeOfSelectedDowntime() {
370      return (DowntimeType)Enum.Parse(typeof(DowntimeType), ((HiveDowntime)dvOnline.SelectedAppointment).Subject);
371    }
372  }
373}
Note: See TracBrowser for help on using the repository browser.