Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 16043 was 15978, checked in by jzenisek, 6 years ago

#2839: applied several fixes:

  • show full project-path in project/resource selector
  • handle lost of project-ownership by not withdrawing permissions
  • update automatically after hand-down save
  • lock jobs for which statistics/deletion is pending
  • lock the disabled checkbox in ProjectResourcesView...
File size: 14.6 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 (DateTime.TryParse(dtpFrom.Text, out from) && DateTime.TryParse(dtpTo.Text, out to) && from <= to) {
95          //whole day appointment, only dates are visible
96          if (chbade.Checked) {
97            offlineTimes.Add(CreateDowntime(new DateTime(from.Year, from.Month, from.Day), (new DateTime(to.Year, to.Month, to.Day)).AddDays(1), true, dtType));
98          } else {
99            //Timeframe appointment
100            if (from.Date == to.Date)
101              offlineTimes.Add(CreateDowntime(from, to, false, dtType));
102            else {
103              //more than 1 day selected
104              while (from.Date != to.Date) {
105                offlineTimes.Add(CreateDowntime(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false, dtType));
106                from = from.AddDays(1);
107              }
108              offlineTimes.Add(CreateDowntime(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false, dtType));
109            }
110          }
111
112        } else {
113          MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
114        }
115
116
117        dvOnline.Invalidate();
118        return true;
119      } else {
120        MessageBox.Show("Error creating downtime, please fill out all textboxes!", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
121        return false;
122      }
123    }
124
125    private HiveDowntime CreateDowntime(DateTime startDate, DateTime endDate, bool allDay, DowntimeType downtimeType) {
126      HiveDowntime downtime = new HiveDowntime();
127      downtime.StartDate = startDate;
128      downtime.EndDate = endDate;
129      downtime.AllDayEvent = allDay;
130      downtime.BorderColor = Color.Red;
131      downtime.Locked = true;
132      downtime.Subject = downtimeType.ToString();
133      downtime.Recurring = false;
134      return downtime;
135    }
136
137    private HiveDowntime CreateDowntime(DateTime startDate, DateTime endDate, bool allDay, bool recurring, Guid recurringId, DowntimeType downtimeType) {
138      HiveDowntime downtime = new HiveDowntime();
139      downtime.StartDate = startDate;
140      downtime.EndDate = endDate;
141      downtime.AllDayEvent = allDay;
142      downtime.BorderColor = Color.Red;
143      downtime.Locked = true;
144      downtime.Subject = downtimeType.ToString();
145      downtime.Recurring = recurring;
146      downtime.RecurringId = recurringId;
147      return downtime;
148    }
149
150    private void DeleteRecurringDowntime(Guid recurringId) {
151      foreach (HiveDowntime downtime in offlineTimes) {
152        if (downtime.RecurringId == recurringId) {
153          downtime.Deleted = true;
154        }
155      }
156    }
157
158    private void ChangeRecurrenceDowntime(Guid recurringId) {
159      DateTime from, to;
160      if (DateTime.TryParse(dtpFrom.Text, out from) && DateTime.TryParse(dtpTo.Text, out to) && from <= to) {
161        List<HiveDowntime> recurringDowntimes = offlineTimes.Where(appointment => ((HiveDowntime)appointment).RecurringId == recurringId).ToList();
162        recurringDowntimes.ForEach(appointment => appointment.StartDate = new DateTime(appointment.StartDate.Year, appointment.StartDate.Month, appointment.StartDate.Day, from.Hour, 0, 0));
163        recurringDowntimes.ForEach(appointment => appointment.EndDate = new DateTime(appointment.EndDate.Year, appointment.EndDate.Month, appointment.EndDate.Day, to.Hour, 0, 0));
164      } else {
165        MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
166      }
167    }
168
169    public void DialogClosed(RecurrentEvent e) {
170      CreateDailyRecurrenceDowntimes(e.DateFrom, e.DateTo, e.AllDay, e.WeekDays, e.DowntimeType);
171    }
172
173    private void CreateDailyRecurrenceDowntimes(DateTime dateFrom, DateTime dateTo, bool allDay, HashSet<DayOfWeek> daysOfWeek, DowntimeType appointmentType) {
174      DateTime incDate = dateFrom;
175      Guid guid = Guid.NewGuid();
176
177      while (incDate.Date <= dateTo.Date) {
178        if (daysOfWeek.Contains(incDate.Date.DayOfWeek))
179          offlineTimes.Add(CreateDowntime(incDate, new DateTime(incDate.Year, incDate.Month, incDate.Day, dateTo.Hour, dateTo.Minute, 0), allDay, true, guid, appointmentType));
180        incDate = incDate.AddDays(1);
181      }
182
183      dvOnline.Invalidate();
184    }
185
186    private void btbDelete_Click(object sender, EventArgs e) {
187      HiveDowntime selectedDowntime = (HiveDowntime)dvOnline.SelectedAppointment;
188      if (dvOnline.SelectedAppointment != null) {
189        if (!selectedDowntime.Recurring)
190          DeleteDowntime();
191        else {
192          DialogResult res = MessageBox.Show("Delete all events in this series?", "Delete recurrences", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
193          if (res != DialogResult.Yes)
194            DeleteDowntime();
195          else
196            DeleteRecurringDowntime(selectedDowntime.RecurringId);
197        }
198      }
199      dvOnline.Invalidate();
200    }
201
202    private void DeleteDowntime() {
203      try {
204        HiveDowntime downtime = offlineTimes.First(s => s.Equals((HiveDowntime)dvOnline.SelectedAppointment));
205        downtime.Deleted = true;
206      }
207      catch (InvalidOperationException) {
208        // this is a ui bug where a selected all day appointment is not properly selected :-/
209      }
210    }
211
212    #region Register Content Events
213    protected override void DeregisterContentEvents() {
214      base.DeregisterContentEvents();
215    }
216    protected override void RegisterContentEvents() {
217      base.RegisterContentEvents();
218    }
219    #endregion
220
221    protected override void OnContentChanged() {
222      base.OnContentChanged();
223      UpdateCalendarFromContent();
224    }
225
226    protected override void SetEnabledStateOfControls() {
227      base.SetEnabledStateOfControls();
228      bool enabled = Content != null && !Locked;
229      btCreate.Enabled = enabled;
230      btbDelete.Enabled = enabled;
231      btnClearCal.Enabled = enabled;
232      btnRecurrence.Enabled = enabled;
233      btnSaveCal.Enabled = enabled;
234    }
235
236    //public virtual void SetEnabledStateOfSchedule(bool state) {
237    //  if (InvokeRequired) {
238    //    Invoke(new Action(() => SetEnabledStateOfSchedule(state)));
239    //  } else {
240    //    if (Content == null || Locked || ReadOnly) state = false;
241    //    //groupBox1.Enabled = state;
242    //    btnClearCal.Enabled = state;
243    //    btnSaveCal.Enabled = state;
244    //  }
245    //}
246
247    private void btnClearCal_Click(object sender, System.EventArgs e) {
248      foreach (HiveDowntime app in offlineTimes) {
249        app.Deleted = true;
250      }
251      dvOnline.Invalidate();
252    }
253
254    private void chbade_CheckedChanged(object sender, EventArgs e) {
255      if(chbade.Checked) {
256        dtpFrom.Value = new DateTime(dtpFrom.Value.Year, dtpFrom.Value.Month, dtpFrom.Value.Day);
257        dtpTo.Value = new DateTime(dtpTo.Value.Year, dtpTo.Value.Month, dtpTo.Value.Day);
258      }
259    }
260
261    private void dvOnline_OnSelectionChanged(object sender, EventArgs e) {
262      if (dvOnline.Selection == SelectionType.DateRange) {
263        dtpFrom.Value = dvOnline.SelectionStart;
264        dtpTo.Value = dvOnline.SelectionEnd.Date;
265        btCreate.Text = "Create Downtime";
266      }
267
268      if (dvOnline.Selection == SelectionType.Appointment) {
269        dtpFrom.Value = dvOnline.SelectedAppointment.StartDate;
270        dtpTo.Value = dvOnline.SelectedAppointment.EndDate;
271
272        if (dvOnline.SelectedAppointment.Recurring)
273          //also change the caption of the save button
274          btCreate.Text = "Save changes";
275      }
276      if (dvOnline.Selection == SelectionType.None) {
277        //also change the caption of the save button
278        btCreate.Text = "Create Downtime";
279      }
280    }
281
282    private void mcOnline_DateChanged(object sender, DateRangeEventArgs e) {
283      dvOnline.StartDate = mcOnline.SelectionStart;
284    }
285
286    private void btCreate_Click(object sender, EventArgs e) {
287      if (dvOnline.Selection != SelectionType.Appointment) {
288        DowntimeType dtType;
289        DialogResult result;
290        DowntimeTypeDialog dialog = new DowntimeTypeDialog();
291        result = dialog.ShowDialog(this);
292        dtType = dialog.AppointmentType;
293        dialog.Dispose();
294        if (result == DialogResult.Cancel) return;
295        CreateDowntime(dtType);
296      } else {
297        //now we want to change an existing appointment
298        if (!dvOnline.SelectedAppointment.Recurring) {
299          if (CreateDowntime(GetDowntimeTypeOfSelectedDowntime()))
300            DeleteDowntime();
301        } else {
302          //change recurring appointment
303          //check, if only selected appointment has to change or whole recurrence
304          DialogResult res = MessageBox.Show("Change all events in this series?", "Change recurrences", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
305          if (res != DialogResult.Yes) {
306            if (CreateDowntime(GetDowntimeTypeOfSelectedDowntime()))
307              DeleteDowntime();
308          } else
309            ChangeRecurrenceDowntime(((HiveDowntime)dvOnline.SelectedAppointment).RecurringId);
310        }
311      }
312      dvOnline.Invalidate();
313    }
314
315    private void btnRecurrence_Click(object sender, EventArgs e) {
316      Recurrence recurrence = new Recurrence();
317      recurrence.dialogClosedDelegate = new OnDialogClosedDelegate(this.DialogClosed);
318      recurrence.Show();
319    }
320
321    private void btnSaveCal_Click(object sender, EventArgs e) {
322      if (HiveAdminClient.Instance.DowntimeForResourceId == null || HiveAdminClient.Instance.DowntimeForResourceId == Guid.Empty) {
323        MessageBox.Show("You have to save the group before you can save the schedule. ", "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Stop);
324      } else {
325        List<Downtime> downtimes = new List<Downtime>();
326        foreach (HiveDowntime downtime in offlineTimes) {
327          if (downtime.Deleted && downtime.Id != Guid.Empty) {
328            HiveAdminClient.Delete(ToDowntime(downtime));
329          } else if (downtime.Changed || downtime.Id == null || downtime.Id == Guid.Empty) {
330            Downtime dt = ToDowntime(downtime);
331            downtimes.Add(dt);
332          }
333        }
334        foreach (Downtime dt in downtimes) {
335          dt.Store();
336        }
337      }
338    }
339
340    private HiveDowntime ToHiveDowntime(Downtime downtime) {
341      HiveDowntime hiveDowntime = new HiveDowntime {
342        AllDayEvent = downtime.AllDayEvent,
343        EndDate = downtime.EndDate,
344        StartDate = downtime.StartDate,
345        Recurring = downtime.Recurring,
346        RecurringId = downtime.RecurringId,
347        Deleted = false,
348        BorderColor = Color.Red,
349        Locked = true,
350        Subject = downtime.DowntimeType.ToString(),
351        Changed = downtime.Modified,
352        Id = downtime.Id
353      };
354      return hiveDowntime;
355    }
356
357    private Downtime ToDowntime(HiveDowntime hiveDowntime) {
358      Downtime downtime = new Downtime {
359        AllDayEvent = hiveDowntime.AllDayEvent,
360        EndDate = hiveDowntime.EndDate,
361        StartDate = hiveDowntime.StartDate,
362        Recurring = hiveDowntime.Recurring,
363        RecurringId = hiveDowntime.RecurringId,
364        ResourceId = HiveAdminClient.Instance.DowntimeForResourceId,
365        Id = hiveDowntime.Id,
366        DowntimeType = (DowntimeType)Enum.Parse(typeof(DowntimeType), hiveDowntime.Subject)
367      };
368      return downtime;
369    }
370
371    private DowntimeType GetDowntimeTypeOfSelectedDowntime() {
372      return (DowntimeType)Enum.Parse(typeof(DowntimeType), ((HiveDowntime)dvOnline.SelectedAppointment).Subject);
373    }
374  }
375}
Note: See TracBrowser for help on using the repository browser.