522 lines
23 KiB
C#
522 lines
23 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Net.Http;
|
|
using System.Windows.Forms;
|
|
using Outlook = Microsoft.Office.Interop.Outlook;
|
|
|
|
namespace MeetingClock
|
|
{
|
|
public partial class MainWindow : Form
|
|
{
|
|
private readonly string LINK_URL = "https://zechert.net/meeting-clock";
|
|
|
|
private BluetoothManager bluetoothManager;
|
|
private MeetingClockManager meetingClockManager;
|
|
private readonly HttpClient client = new HttpClient();
|
|
private string clockVersion = null;
|
|
private Settings settings = new Settings();
|
|
private bool showBalloon = false;
|
|
private OutlookManager outlookManager = new OutlookManager();
|
|
private bool clockSettingsCanBeChanged;
|
|
private string currentAppointment = "";
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
this.Text += " - " + Properties.Settings.Default.Version;
|
|
}
|
|
|
|
private async void MainWindow_Load(object sender, System.EventArgs e)
|
|
{
|
|
this.clockSettingsCanBeChanged = false;
|
|
this.checkBoxAutostart.Checked = this.settings.Autostart;
|
|
this.checkBoxStartMinimized.Checked = this.settings.StartMinimized;
|
|
this.checkBoxEnableBluetooth.Checked = this.settings.StartBluetooth;
|
|
this.checkBoxIgnoreAllDayAppointments.Checked = this.settings.IgnoreAllDayAppointments;
|
|
this.checkBoxIgnoreCancelledAppointments.Checked = this.settings.IgnoreCancelledAppointments;
|
|
this.checkBoxIgnoreFreeAppointments.Checked = this.settings.IgnoreFreeAppointments;
|
|
this.checkBoxIgnoreOutOfOfficeAppointments.Checked = this.settings.IgnoreOutOfOfficeAppointments;
|
|
this.checkBoxIgnoreTentativeAppointments.Checked = this.settings.IgnoreTentativeAppointments;
|
|
this.numericUpDownReminderTime.Value = this.settings.ReminderTime;
|
|
|
|
if (this.settings.StartMinimized)
|
|
{
|
|
this.WindowState = FormWindowState.Minimized;
|
|
}
|
|
|
|
this.bluetoothManager = new BluetoothManager();
|
|
this.bluetoothManager.StateChanged += BluetoothManager_StateChanged;
|
|
|
|
this.meetingClockManager = new MeetingClockManager(bluetoothManager);
|
|
this.meetingClockManager.StateChanged += MeetingClockManager_StateChanged;
|
|
|
|
await this.bluetoothManager.Initialize();
|
|
|
|
if (this.settings.StartBluetooth && this.bluetoothManager.State != BluetoothManager.BluetoothState.On)
|
|
{
|
|
await this.bluetoothManager.Enable();
|
|
}
|
|
}
|
|
|
|
private void UpdateBluetoothState()
|
|
{
|
|
switch (this.bluetoothManager.State)
|
|
{
|
|
case BluetoothManager.BluetoothState.NotInitialized:
|
|
this.labelBluetoothState.Text = "not initialized";
|
|
this.labelBluetoothState.ForeColor = SystemColors.ControlText;
|
|
this.UpdateIcon(Properties.Resources.icon_neutral);
|
|
this.buttonEnableBluetooth.Enabled = false;
|
|
break;
|
|
case BluetoothManager.BluetoothState.Exception:
|
|
this.labelBluetoothState.Text = "system exception";
|
|
this.labelBluetoothState.ForeColor = Color.Red;
|
|
this.UpdateIcon(Properties.Resources.icon_error);
|
|
this.buttonEnableBluetooth.Enabled = false;
|
|
ShowArchitectureWarning();
|
|
break;
|
|
case BluetoothManager.BluetoothState.NoBluetoothAdapter:
|
|
this.labelBluetoothState.Text = "no bluetooth adapter found";
|
|
this.labelBluetoothState.ForeColor = Color.Red;
|
|
this.UpdateIcon(Properties.Resources.icon_error);
|
|
this.buttonEnableBluetooth.Enabled = false;
|
|
break;
|
|
case BluetoothManager.BluetoothState.NoBluetoothRadio:
|
|
this.labelBluetoothState.Text = "no bluetooth radio found";
|
|
this.labelBluetoothState.ForeColor = Color.Red;
|
|
this.UpdateIcon(Properties.Resources.icon_error);
|
|
this.buttonEnableBluetooth.Enabled = false;
|
|
break;
|
|
case BluetoothManager.BluetoothState.Disabled:
|
|
this.labelBluetoothState.Text = "disabled";
|
|
this.labelBluetoothState.ForeColor = SystemColors.ControlText;
|
|
this.UpdateIcon(Properties.Resources.icon_warning);
|
|
this.buttonEnableBluetooth.Enabled = true;
|
|
break;
|
|
case BluetoothManager.BluetoothState.Off:
|
|
this.labelBluetoothState.Text = "off";
|
|
this.labelBluetoothState.ForeColor = Color.DarkOrange;
|
|
this.UpdateIcon(Properties.Resources.icon_warning);
|
|
this.buttonEnableBluetooth.Enabled = true;
|
|
break;
|
|
case BluetoothManager.BluetoothState.On:
|
|
this.labelBluetoothState.Text = "on";
|
|
this.UpdateIcon(Properties.Resources.icon_neutral);
|
|
this.labelBluetoothState.ForeColor = Color.Green;
|
|
this.buttonEnableBluetooth.Enabled = false;
|
|
break;
|
|
case BluetoothManager.BluetoothState.Unknown:
|
|
this.labelBluetoothState.Text = "unknown";
|
|
this.UpdateIcon(Properties.Resources.icon_off);
|
|
this.labelBluetoothState.ForeColor = SystemColors.ControlText;
|
|
this.buttonEnableBluetooth.Enabled = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void BluetoothManager_StateChanged(BluetoothManager manager, BluetoothManager.BluetoothState oldState, BluetoothManager.BluetoothState newState)
|
|
{
|
|
this.BeginInvoke((Action) (() => { this.UpdateBluetoothState(); }));
|
|
}
|
|
|
|
private void UpdateMeetingClockState()
|
|
{
|
|
this.clockSettingsCanBeChanged = false;
|
|
switch (this.meetingClockManager.State)
|
|
{
|
|
case MeetingClockManager.MeetingClockState.NotInitialized:
|
|
this.labelMeetingClockState.Text = "not initialized";
|
|
this.labelMeetingClockState.ForeColor = SystemColors.ControlText;
|
|
this.UpdateIcon(Properties.Resources.icon_neutral);
|
|
this.groupBoxClockSettings.Enabled = false;
|
|
break;
|
|
case MeetingClockManager.MeetingClockState.NoComPort:
|
|
if (this.bluetoothManager.State == BluetoothManager.BluetoothState.On)
|
|
{
|
|
this.labelMeetingClockState.Text = "not paired";
|
|
}
|
|
else
|
|
{
|
|
this.labelMeetingClockState.Text = "bluetooth disabled";
|
|
}
|
|
this.labelMeetingClockState.ForeColor = Color.Red;
|
|
this.UpdateIcon(Properties.Resources.icon_error);
|
|
this.groupBoxClockSettings.Enabled = false;
|
|
break;
|
|
case MeetingClockManager.MeetingClockState.Disconnected:
|
|
this.labelMeetingClockState.Text = "not connected";
|
|
this.labelMeetingClockState.ForeColor = Color.DarkOrange;
|
|
this.UpdateIcon(Properties.Resources.icon_neutral);
|
|
this.groupBoxClockSettings.Enabled = false;
|
|
break;
|
|
case MeetingClockManager.MeetingClockState.Connected:
|
|
this.labelMeetingClockState.Text = "connected on " + this.meetingClockManager.Port + ", " + this.meetingClockManager.Version;
|
|
this.labelMeetingClockState.ForeColor = Color.Green;
|
|
this.UpdateIcon(Properties.Resources.icon_ok);
|
|
if (this.clockVersion != null && this.meetingClockManager.Version != this.clockVersion)
|
|
{
|
|
DialogResult result = MessageBox.Show("A new version of the meeting clock firmware is available.\n\n" +
|
|
"Do you want to open " + LINK_URL + " to download the new version now?", "New Firmware Available", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
|
|
if (result == DialogResult.Yes)
|
|
{
|
|
System.Diagnostics.Process.Start(LINK_URL);
|
|
}
|
|
}
|
|
this.groupBoxClockSettings.Enabled = true;
|
|
this.ReadClockSettings();
|
|
this.ShowNextAppointment();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void MeetingClockManager_StateChanged(MeetingClockManager manager, MeetingClockManager.MeetingClockState oldState, MeetingClockManager.MeetingClockState newState)
|
|
{
|
|
this.BeginInvoke((Action)(() => { this.UpdateMeetingClockState(); }));
|
|
}
|
|
|
|
private void ShowArchitectureWarning()
|
|
{
|
|
String computerArchitecture = Environment.Is64BitOperatingSystem ? "x64" : "x86";
|
|
String programArchitecture = Environment.Is64BitProcess ? "x64" : "x86";
|
|
|
|
String message = "" +
|
|
"This application cannot access the Bluetooth device on your computer. " +
|
|
"This is normally a sign that you downloaded the wrong architecture (x64, x86) of this application.\n" +
|
|
"\n" +
|
|
"Your computer uses " + computerArchitecture + " architecture.\n" +
|
|
"This application is " + programArchitecture + " architecture.\n" +
|
|
"\n" +
|
|
"This application will only work on Windows 10.\n\n" +
|
|
"Please download the correct version of this application from " + LINK_URL + ".\n" +
|
|
"\n" +
|
|
"This application will now exit!\n" +
|
|
"\n" +
|
|
"Do you want to open " + LINK_URL + " now?";
|
|
|
|
DialogResult result = MessageBox.Show(message, "Bluetooth Error", MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
|
|
if (result == DialogResult.Yes)
|
|
{
|
|
System.Diagnostics.Process.Start(LINK_URL);
|
|
}
|
|
|
|
Application.Exit();
|
|
}
|
|
|
|
private void ButtonOpenSystemSettingsPrivacy_Click(object sender, EventArgs e)
|
|
{
|
|
System.Diagnostics.Process.Start("ms-settings:privacy-radios");
|
|
}
|
|
|
|
private void buttonOpenSystemSettingsBluetooth_Click(object sender, EventArgs e)
|
|
{
|
|
System.Diagnostics.Process.Start("ms-settings:bluetooth");
|
|
}
|
|
|
|
private void buttonWebsite_Click(object sender, EventArgs e)
|
|
{
|
|
System.Diagnostics.Process.Start(LINK_URL);
|
|
}
|
|
|
|
private async void ButtonEnableBluetooth_Click(object sender, EventArgs e)
|
|
{
|
|
Windows.Devices.Radios.RadioAccessStatus result = await this.bluetoothManager.Enable();
|
|
DialogResult open = DialogResult.Cancel;
|
|
String openLink = "";
|
|
|
|
switch (result)
|
|
{
|
|
case Windows.Devices.Radios.RadioAccessStatus.DeniedBySystem:
|
|
open = MessageBox.Show(
|
|
"The operating system denied access to the bluetooth radio. Please enable bluetooth yourself.\n\nDo you want to open bluetooth settings now?",
|
|
"Access denied", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
|
|
openLink = "ms-settings:bluetooth";
|
|
break;
|
|
case Windows.Devices.Radios.RadioAccessStatus.DeniedByUser:
|
|
open = MessageBox.Show(
|
|
"Switching the bluetooth state automatically is forbidden by your privacy settings.\n\nDo you want to open privacy settings now?",
|
|
"Access denied", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
|
|
openLink = "ms-settings:privacy-radios";
|
|
break;
|
|
case Windows.Devices.Radios.RadioAccessStatus.Unspecified:
|
|
open = MessageBox.Show(
|
|
"Switching the bluetooth state failed for an unknown reason. Please enable bluetooth yourself.\n\nDo you want to open bluetooth settings now?",
|
|
"Access denied", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
|
|
openLink = "ms-settings:bluetooth";
|
|
break;
|
|
}
|
|
|
|
if (open == DialogResult.Yes)
|
|
{
|
|
System.Diagnostics.Process.Start(openLink);
|
|
}
|
|
}
|
|
|
|
private void UpdateIcon(Icon newIcon)
|
|
{
|
|
this.Icon = newIcon;
|
|
this.notifyIcon.Icon = newIcon;
|
|
}
|
|
|
|
private void MainWindow_FormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
Debug.WriteLine(String.Format("Form was closed because of {0}", e.CloseReason.ToString()));
|
|
this.bluetoothManager.Stop();
|
|
this.meetingClockManager.Stop();
|
|
}
|
|
|
|
private void checkBoxAutostart_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.Autostart = this.checkBoxAutostart.Checked;
|
|
}
|
|
|
|
private void checkBoxStartMinimized_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.StartMinimized = this.checkBoxStartMinimized.Checked;
|
|
}
|
|
|
|
private void checkBoxEnableBluetooth_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.StartBluetooth = this.checkBoxEnableBluetooth.Checked;
|
|
}
|
|
|
|
private void MainWindow_Resize(object sender, EventArgs e)
|
|
{
|
|
if (this.WindowState == FormWindowState.Minimized)
|
|
{
|
|
if (this.showBalloon)
|
|
{
|
|
this.notifyIcon.ShowBalloonTip(3000);
|
|
}
|
|
this.ShowInTaskbar = false;
|
|
this.FormBorderStyle = FormBorderStyle.SizableToolWindow;
|
|
}
|
|
}
|
|
|
|
private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
|
|
{
|
|
this.FormBorderStyle = FormBorderStyle.Sizable;
|
|
this.WindowState = FormWindowState.Normal;
|
|
this.ShowInTaskbar = true;
|
|
}
|
|
|
|
private void timerEnableBalloon_Tick(object sender, EventArgs e)
|
|
{
|
|
this.showBalloon = true;
|
|
this.timerEnableBalloon.Stop();
|
|
}
|
|
|
|
private void checkBoxIgnoreAllDayAppointments_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.IgnoreAllDayAppointments = this.checkBoxIgnoreAllDayAppointments.Checked;
|
|
}
|
|
|
|
private void checkBoxIgnoreCancelledAppointments_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.IgnoreCancelledAppointments = this.checkBoxIgnoreCancelledAppointments.Checked;
|
|
}
|
|
|
|
private void checkBoxIgnoreFreeAppointments_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.IgnoreFreeAppointments = this.checkBoxIgnoreFreeAppointments.Checked;
|
|
}
|
|
|
|
private void checkBoxIgnoreOutOfOfficeAppointments_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.IgnoreOutOfOfficeAppointments = this.checkBoxIgnoreOutOfOfficeAppointments.Checked;
|
|
}
|
|
|
|
private void checkBoxIgnoreTentativeAppointments_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.IgnoreTentativeAppointments = this.checkBoxIgnoreTentativeAppointments.Checked;
|
|
}
|
|
|
|
private void ReadClockSettings()
|
|
{
|
|
this.numericUpDownTimeInterval.Value = this.meetingClockManager.GetTimeInterval() ?? this.numericUpDownTimeInterval.Value;
|
|
this.numericUpDownDateInterval.Value = this.meetingClockManager.GetDateInterval() ?? this.numericUpDownDateInterval.Value;
|
|
this.numericUpDownTemperatureInterval.Value = this.meetingClockManager.GetTemperatureInterval() ?? this.numericUpDownTemperatureInterval.Value;
|
|
|
|
this.trackBarBrightness.Value = this.meetingClockManager.GetBrightness() ?? this.trackBarBrightness.Value;
|
|
this.labelBrightness.Text = this.trackBarBrightness.Value.ToString();
|
|
|
|
this.trackBarScrollSpeed.Value = this.meetingClockManager.GetScrollSpeed() ?? this.trackBarScrollSpeed.Value;
|
|
this.labelScrollSpeed.Text = this.trackBarScrollSpeed.Value.ToString();
|
|
|
|
this.numericUpDownScrollWait.Value = (this.meetingClockManager.GetScrollWait() / 10) ?? this.numericUpDownScrollWait.Value;
|
|
|
|
this.checkBoxDateEnabled.Checked = this.meetingClockManager.GetDateEnabled() ?? this.checkBoxDateEnabled.Checked;
|
|
this.checkBoxTemperatureEnabled.Checked = this.meetingClockManager.GetTemperatureEnabled() ?? this.checkBoxTemperatureEnabled.Checked;
|
|
|
|
this.clockSettingsCanBeChanged = true;
|
|
}
|
|
|
|
private void trackBarBrightness_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
this.labelBrightness.Text = trackBarBrightness.Value.ToString();
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.SetBrightness(trackBarBrightness.Value);
|
|
}
|
|
}
|
|
|
|
private void trackBarScrollSpeed_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
this.labelScrollSpeed.Text = trackBarScrollSpeed.Value.ToString();
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.SetScrollSpeed(trackBarScrollSpeed.Value);
|
|
this.StartScrollDemo();
|
|
}
|
|
}
|
|
|
|
private void numericUpDownScrollWait_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.SetScrollWait((int)(this.numericUpDownScrollWait.Value * 10));
|
|
this.StartScrollDemo();
|
|
}
|
|
}
|
|
|
|
private void StartScrollDemo()
|
|
{
|
|
if (this.timerScrollDemo.Enabled)
|
|
{
|
|
this.timerScrollDemo.Stop();
|
|
}
|
|
else
|
|
{
|
|
this.meetingClockManager.ScrollText("Beispiel-Text");
|
|
}
|
|
|
|
this.timerScrollDemo.Start();
|
|
}
|
|
|
|
private void timerScrollDemo_Tick(object sender, EventArgs e)
|
|
{
|
|
this.meetingClockManager.ScrollText("");
|
|
timerScrollDemo.Stop();
|
|
}
|
|
|
|
private void numericUpDownTimeInterval_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.SetTimeInterval((int)(this.numericUpDownTimeInterval.Value));
|
|
}
|
|
}
|
|
|
|
private void numericUpDownDateInterval_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.SetDateInterval((int)(this.numericUpDownDateInterval.Value));
|
|
}
|
|
}
|
|
|
|
private void numericUpDownTemperatureInterval_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.SetTemperatureInterval((int)(this.numericUpDownTemperatureInterval.Value));
|
|
}
|
|
}
|
|
|
|
private void checkBoxDateEnabled_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.SetDateEnabled(this.checkBoxDateEnabled.Checked);
|
|
}
|
|
}
|
|
|
|
private void checkBoxTemperatureEnabled_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.SetTemperatureEnabled(this.checkBoxTemperatureEnabled.Checked);
|
|
}
|
|
}
|
|
|
|
private void buttonResetDefault_Click(object sender, EventArgs e)
|
|
{
|
|
DialogResult dialogResult = MessageBox.Show("Are you sure? All clock settings will be reset to their default values!", "Confirm Reset",
|
|
MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);
|
|
|
|
if (dialogResult == DialogResult.Yes)
|
|
{
|
|
this.clockSettingsCanBeChanged = false;
|
|
this.meetingClockManager.SetBrightness(15);
|
|
this.meetingClockManager.SetTimeInterval(35);
|
|
this.meetingClockManager.SetDateInterval(3);
|
|
this.meetingClockManager.SetDateEnabled(true);
|
|
this.meetingClockManager.SetDateInterval(3);
|
|
this.meetingClockManager.SetTemperatureEnabled(true);
|
|
this.meetingClockManager.SetTemperatureInterval(3);
|
|
this.meetingClockManager.SetScrollSpeed(5);
|
|
this.meetingClockManager.SetScrollWait(40);
|
|
|
|
this.ReadClockSettings();
|
|
}
|
|
}
|
|
|
|
private void timerAdjustClock_Tick(object sender, EventArgs e)
|
|
{
|
|
if (this.clockSettingsCanBeChanged)
|
|
{
|
|
this.meetingClockManager.Adjust();
|
|
}
|
|
}
|
|
|
|
private void timerGetAppointment_Tick(object sender, EventArgs e)
|
|
{
|
|
this.ShowNextAppointment();
|
|
}
|
|
|
|
private async void ShowNextAppointment() {
|
|
if (!this.clockSettingsCanBeChanged)
|
|
{
|
|
this.currentAppointment = "";
|
|
return;
|
|
}
|
|
|
|
|
|
Outlook.AppointmentItem appointment = await this.outlookManager.GetNextAppointment(
|
|
this.settings.IgnoreAllDayAppointments, this.settings.IgnoreCancelledAppointments, this.settings.IgnoreFreeAppointments,
|
|
this.settings.IgnoreOutOfOfficeAppointments, this.settings.IgnoreTentativeAppointments);
|
|
|
|
if (appointment == null)
|
|
{
|
|
Debug.WriteLine("No upcoming appointment send to clock");
|
|
this.currentAppointment = "";
|
|
return;
|
|
}
|
|
|
|
string appointmentName = String.Format("{0} - {1} {2}", appointment.Start.ToString("t"), appointment.End.ToString("t"), appointment.Subject);
|
|
if (appointment.Start > DateTime.Now.AddMinutes(this.settings.ReminderTime))
|
|
{
|
|
Debug.WriteLine(String.Format("Upcoming appointment is too far in future, not displaying: {0}", appointmentName));
|
|
this.currentAppointment = "";
|
|
return;
|
|
}
|
|
|
|
if (this.currentAppointment == appointmentName)
|
|
{
|
|
Debug.WriteLine("Current appointment is already displayed, not doing anything");
|
|
return;
|
|
}
|
|
|
|
this.currentAppointment = appointmentName;
|
|
this.meetingClockManager.ScrollText(this.currentAppointment);
|
|
this.meetingClockManager.NextDate(appointment.Start);
|
|
Debug.WriteLine(String.Format("Current appointment is set to: {0}", this.currentAppointment));
|
|
}
|
|
|
|
private void numericUpDownReminderTime_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
this.settings.ReminderTime = (int)this.numericUpDownReminderTime.Value;
|
|
}
|
|
}
|
|
}
|