tbf/TBF/UI/Calendar/CalendarTabPageCtrl.cs

426 lines
18 KiB
C#
Raw Normal View History

///
/// Copyright (c) 2020-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using log4net;
using NHibernate;
using Common;
using Config.Entities;
using Config.CalendarEvent;
using TBF.Resources;
namespace TBF.UI.Calendar
{
public partial class CalendarTabPageCtrl : UserControl
{
static readonly ILog log = LogManager.GetLogger(typeof(CalendarTabPageCtrl));
2023-04-18 12:01:23 +00:00
public IList<ICalendarEvent> EventsFromComponents;
Timer timer;
2023-04-18 12:01:23 +00:00
DateTime LastTimeCalendarEventsServed;
public CalendarTabPageCtrl()
{
InitializeComponent();
2023-04-18 12:01:23 +00:00
EventsFromComponents = new List<ICalendarEvent>();
Localize();
}
void Localize()
{
newEventButton.Text = Strings.New_event;
calendarEventsListViewEx.Columns.Add(Strings.Date_and_time, 100);
calendarEventsListViewEx.Columns.Add(Strings.Frequency, 70);
calendarEventsListViewEx.Columns.Add(Strings.Source, 50);
calendarEventsListViewEx.Columns.Add(Strings.Title, 200);
calendarEventsListViewEx.Columns.Add(Strings.Action);
calendarEventsListViewEx.Columns.Add(Strings.Parameters);
calendarEventsListViewEx.Columns.Add(Strings.On_exact_day);
calendarEventsListViewEx.Columns.Add(Strings.Read_only);
}
void AddOne(ICalendarEvent evnt)
{
ListViewItem lvi = new ListViewItem(evnt.Date.ToString(evnt.AllDay ? Constants.DateFormat : Constants.DateTimeFormat));
lvi.SubItems.Add(Config.CalendarEvent.Utils.Freq2String(evnt.Frequency));
lvi.SubItems.Add(evnt.Source);
lvi.SubItems.Add(evnt.Title);
lvi.SubItems.Add(Config.CalendarEvent.Utils.Action2String(evnt.AutoAction));
lvi.SubItems.Add(evnt.Parameters);
lvi.SubItems.Add(evnt.TriggerOnExactDayOnly ? Strings.yes : Strings.no);
lvi.SubItems.Add(evnt.ReadOnly ? Strings.yes : Strings.no);
lvi.Tag = evnt;
calendarEventsListViewEx.Items.Add(lvi);
}
2023-04-18 12:01:23 +00:00
/// <summary>
/// Initializes 'public IList<...> EventsFromComponents.
///
/// </summary>
/// <param name="eventsFromComponents"></param>
/// <param name="session"></param>
public void StartCalendar(IList<ICalendarEvent> eventsFromComponents, ISession session = null)
{
2023-04-18 12:01:23 +00:00
this.EventsFromComponents = eventsFromComponents;
bool openAndCloseSession = (session == null);
try
{
/// Read custom events from the database
if (openAndCloseSession) session = TBF.DB.ConfigDBSessionFactory.OpenSession();
2023-04-18 12:01:23 +00:00
var customEvents = session.QueryOver<CustomEvent>().List();
TripplicateShiftCustomEvents(customEvents);
/// Calendar
foreach (var evnt in eventsFromComponents) calendarCtrl1.AddEvent(evnt);
foreach (var evnt in customEvents) calendarCtrl1.AddEvent(evnt);
/// List view in the right pane
calendarEventsListViewEx.Items.Clear();
foreach (var e in customEvents) AddOne(e);
foreach (var e in eventsFromComponents) if (!e.Hidden) AddOne(e);
/// Serve events (determine if any event was triggered)
2023-04-18 12:01:23 +00:00
ServeCalendarEventsNotifWarnErrorFatal(DateTime.Now, session, customEvents);
}
catch (Exception)
{
log.ErrorFormat("Failed to load custom events from the LOCAL config database");
}
2023-04-18 12:01:23 +00:00
finally
{
if (openAndCloseSession && session != null && session.IsOpen) session.Close();
}
calendarCtrl1.CalendarView = CalendarViews.Month;
timer = new System.Windows.Forms.Timer();
timer.Interval = 300000; /// 300000 ms = 300 s = 5 min
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
/// <summary>
/// After StartCalendar() was called this function is invoked every 5 minutes
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
void timer_Tick(object sender, EventArgs args)
{
2023-04-18 12:01:23 +00:00
DateTime dateTimeNow = DateTime.Now;
2023-04-18 12:01:23 +00:00
if ((dateTimeNow.Hour != LastTimeCalendarEventsServed.Hour) ||
(dateTimeNow.Minute % 30) != (LastTimeCalendarEventsServed.Minute % 30))
{
/// Serve events at the beginning of each half hour
2023-04-18 12:01:23 +00:00
ServeCalendarEventsNotifWarnErrorFatal(dateTimeNow);
}
}
/// <summary>
/// Triggers events corresponding to triggered motification.warning/error calendar events.
/// </summary>
2023-04-18 12:01:23 +00:00
/// <param name="dateTimeNow">Current time</param>
void ServeCalendarEventsNotifWarnErrorFatal(DateTime dateTimeNow, ISession session = null, IList<CustomEvent> customEventsFromDB = null)
{
2023-04-18 12:01:23 +00:00
LastTimeCalendarEventsServed = dateTimeNow;
2023-04-18 12:01:23 +00:00
var eventsToTrigger = new List<Events.Entities.Event>();
2023-04-18 12:01:23 +00:00
for (int i = EventsFromComponents.Count - 1; i >= 0; i--)
{
2023-04-18 12:01:23 +00:00
ICalendarEvent calEvent = EventsFromComponents[i];
AutoAction a = calEvent.AutoAction;
if (a == AutoAction.Notification || a == AutoAction.Warning || a == AutoAction.Error || a == AutoAction.FatalErr)
{
2023-04-18 12:01:23 +00:00
if (Config.CalendarEvent.Utils.IsCalendarEventTrigerred(calEvent, dateTimeNow))
{
eventsToTrigger.Add(new Events.Entities.Event(null,
calEvent.Source,
EventClass.Metrology,
ToSeverity(calEvent.AutoAction),
calEvent.Title,
calEvent.Parameters,
null,
SubscriberGroup.Metrology | SubscriberGroup.Maintenance |
SubscriberGroup.Production | SubscriberGroup.Management));
if (calEvent.Frequency == Frequency.Once)
{
2023-04-18 12:01:23 +00:00
EventsFromComponents.Remove(calEvent);
}
else
{
2023-04-18 12:01:23 +00:00
Config.CalendarEvent.Utils.UpdateRecurringDate(calEvent, dateTimeNow);
}
}
}
}
2023-04-18 12:01:23 +00:00
bool openAndCloseSession = (session == null);
///
try
{
if (openAndCloseSession) session = TBF.DB.ConfigDBSessionFactory.OpenSession();
2023-04-18 12:01:23 +00:00
var customEvents = (customEventsFromDB != null) ? customEventsFromDB : session.QueryOver<CustomEvent>().List();
for (int i = customEvents.Count - 1; i >= 0; i--)
{
CustomEvent calEvent = customEvents[i];
AutoAction a = calEvent.AutoAction;
if (a == AutoAction.Notification || a == AutoAction.Warning || a == AutoAction.Error || a == AutoAction.FatalErr)
{
2023-04-18 12:01:23 +00:00
if (Config.CalendarEvent.Utils.IsCalendarEventTrigerred(calEvent, dateTimeNow))
{
eventsToTrigger.Add(new Events.Entities.Event(null,
calEvent.Source,
EventClass.Undefined,
ToSeverity(calEvent.AutoAction),
calEvent.Title,
calEvent.Parameters,
null,
SubscriberGroup.Metrology | SubscriberGroup.Maintenance |
SubscriberGroup.Production | SubscriberGroup.Management));
if (calEvent.Frequency == Frequency.Once)
{
session.Delete(calEvent);
}
2023-04-18 12:01:23 +00:00
else if (calEvent.UpdateRecurringDate(dateTimeNow))
{
session.SaveOrUpdate(calEvent);
}
}
}
}
session.Flush();
}
catch (Exception exc)
{
log.ErrorFormat("Failed to load or update CustomEvent-s in ServeTriggerEvtCalendarEvents(): {0}", exc.Message);
}
2023-04-18 12:01:23 +00:00
finally
{
if (openAndCloseSession && session != null && session.IsOpen) session.Close();
}
if (eventsToTrigger.Count > 0 && TBF.DB.EventsDBSessionFactory != null)
{
using (ISession evtDBSession = TBF.DB.EventsDBSessionFactory.OpenSession())
{
global::Events.DB.LoadSubscribers(evtDBSession);
foreach (var e in eventsToTrigger)
{
TBF.UiBridge.Bridge.TriggerEvent(evtDBSession, e);
}
2023-04-18 12:01:23 +00:00
evtDBSession.Flush();
evtDBSession.Close();
}
}
}
/// <summary>
/// Returns an array of parameters of selected actions.
/// This function is not invoked from UI thread.
/// </summary>
/// <param name="selectedAction">Selected AutoAction</param>
/// <param name="maxCount">Max. number of calendar events served</param>
/// <returns>List of strings of triggered actions</returns>
public static IList<string> ServeCalendarEventsInvokeXY(AutoAction selectedAction, int maxCount = 1)
{
DateTime currentTime = DateTime.Now;
IList<string> parametersList = new List<string>();
if (maxCount <= 0) return parametersList;
ISession session = null;
try
{
session = TBF.DB.ConfigDBSessionFactory.OpenSession();
var customEventsFromDB = session.QueryOver<CustomEvent>().List();
for (int i = customEventsFromDB.Count - 1; i >= 0; i--)
{
CustomEvent calEvent = customEventsFromDB[i];
if (calEvent.AutoAction == selectedAction && Config.CalendarEvent.Utils.IsCalendarEventTrigerred(calEvent, currentTime))
{
parametersList.Add(calEvent.Parameters);
if (calEvent.Frequency == Frequency.Once)
{
session.Delete(calEvent);
}
else if (calEvent.UpdateRecurringDate(currentTime))
{
session.SaveOrUpdate(calEvent);
}
if (parametersList.Count >= maxCount) break;
}
}
2023-04-18 12:01:23 +00:00
session.Flush();
}
catch (Exception exc)
{
log.ErrorFormat("Failed to load or update CustomEvent-s in ServeSelectedCalendarEvents(): {0}", exc.Message);
}
finally
{
if (session != null && session.IsOpen) session.Close();
}
if (parametersList.Count > 0)
{
/// TODO: Invoke calendar redraw in UI thread
}
return parametersList;
}
/// <summary>
/// Convert calendar event AutoAction to event Severity
/// </summary>
/// <param name="action">AutoAction enum value</param>
/// <returns>Severity enum value</returns>
Severity ToSeverity(AutoAction action)
{
switch (action)
{
default:
case AutoAction.Notification: return Severity.Notification;
case AutoAction.Warning: return Severity.Warning;
case AutoAction.Error: return Severity.Error;
case AutoAction.FatalErr: return Severity.FatalError;
}
}
void TripplicateShiftCustomEvents(IList<CustomEvent> customEvents)
{
/// Tripplicate each custom event with frequency 'EveryShift'
for (int i = customEvents.Count - 1; i >= 0; i--)
{
if (customEvents[i].Frequency == Frequency.EveryShift)
{
DateTime dt = customEvents[i].Date;
var ev2 = (CustomEvent)customEvents[i].Clone();
ev2.Date = new DateTime(dt.Year, dt.Month, dt.Day, (dt.Hour + 8) % 24, dt.Minute, 0);
ev2.ReadOnly = true;
customEvents.Insert(i + 1, ev2);
var ev3 = (CustomEvent)customEvents[i].Clone();
ev3.Date = new DateTime(dt.Year, dt.Month, dt.Day, (dt.Hour + 16) % 24, dt.Minute, 0);
ev3.ReadOnly = true;
customEvents.Insert(i + 2, ev3);
}
}
}
private void newEventButton_Click(object sender, EventArgs ea)
{
EventDetailsForm dlg = new EventDetailsForm();
if (dlg.ShowDialog() == DialogResult.OK && dlg.NewEvent is CustomEvent)
{
ISession session = null;
try
{
session = TBF.DB.ConfigDBSessionFactory.OpenSession();
session.SaveOrUpdate(dlg.NewEvent as CustomEvent);
session.Flush();
2023-04-18 12:01:23 +00:00
var customEvents = session.QueryOver<CustomEvent>().List();
TripplicateShiftCustomEvents(customEvents);
/// Calendar
calendarCtrl1.ClearEvents();
2023-04-18 12:01:23 +00:00
foreach (var e in EventsFromComponents) calendarCtrl1.AddEvent(e);
foreach (var e in customEvents) calendarCtrl1.AddEvent(e);
/// List view in the right pane
calendarEventsListViewEx.Items.Clear();
foreach (var e in customEvents) AddOne(e);
2023-04-18 12:01:23 +00:00
foreach (var e in EventsFromComponents) if (!e.Hidden) AddOne(e);
}
catch (Exception)
{
MessageBox.Show("Cannot save the change to the database", Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
finally
{
if (session != null && session.IsOpen) session.Close();
}
}
}
private void calendarEventsListViewEx_MouseDoubleClick(object sender, MouseEventArgs mea)
{
if (calendarEventsListViewEx.SelectedIndices.Count != 1) return;
CustomEvent evnt = calendarEventsListViewEx.SelectedItems[0].Tag as CustomEvent;
if (evnt == null || evnt.ReadOnly) return;
EventDetailsForm dlg = new EventDetailsForm { Event = evnt };
if (dlg.ShowDialog() != DialogResult.OK) return;
ISession session = null;
try
{
/// Re-read selected custom event from the database
session = TBF.DB.ConfigDBSessionFactory.OpenSession();
var cEvents = session.QueryOver<CustomEvent>()
.Where(x => (x.Id == evnt.Id))
.List();
if (cEvents.Count == 1)
{
cEvents[0].Date = dlg.NewEvent.Date;
cEvents[0].Frequency = dlg.NewEvent.Frequency;
cEvents[0].AllDay = dlg.NewEvent.AllDay;
cEvents[0].TriggerOnExactDayOnly = dlg.NewEvent.TriggerOnExactDayOnly;
cEvents[0].Source = dlg.NewEvent.Source;
cEvents[0].Title = dlg.NewEvent.Title;
cEvents[0].AutoAction = dlg.NewEvent.AutoAction;
cEvents[0].Parameters = dlg.NewEvent.Parameters;
cEvents[0].Rank = dlg.NewEvent.Rank;
cEvents[0].Hidden = dlg.NewEvent.Hidden;
cEvents[0].ReadOnly = dlg.NewEvent.ReadOnly;
cEvents[0].BackColor = dlg.NewEvent.BackColor;
cEvents[0].TextColor = dlg.NewEvent.TextColor;
cEvents[0].TooltipEnabled = dlg.NewEvent.TooltipEnabled;
cEvents[0].CustomRecurringFunction = null;
session.SaveOrUpdate(cEvents[0]);
session.Flush();
2023-04-18 12:01:23 +00:00
var customEvents = session.QueryOver<CustomEvent>().List();
TripplicateShiftCustomEvents(customEvents);
/// Calendar
calendarCtrl1.ClearEvents();
2023-04-18 12:01:23 +00:00
foreach (var e in EventsFromComponents) calendarCtrl1.AddEvent(e);
foreach (var e in customEvents) calendarCtrl1.AddEvent(e);
/// List view in the right pane
calendarEventsListViewEx.Items.Clear();
foreach (var e in customEvents) AddOne(e);
2023-04-18 12:01:23 +00:00
foreach (var e in EventsFromComponents) if (!e.Hidden) AddOne(e);
}
}
catch (Exception)
{
MessageBox.Show("Cannot save the change to the database", Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
finally
{
if (session != null && session.IsOpen) session.Close();
}
}
}
}