diff --git a/App.config b/App.config
new file mode 100644
index 0000000..a203aac
--- /dev/null
+++ b/App.config
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ v. 1.0.0
+
+
+
+
+
+
+ True
+
+
+ False
+
+
+ False
+
+
+ True
+
+
+ True
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ 10
+
+
+
+
\ No newline at end of file
diff --git a/BluetoothManager.cs b/BluetoothManager.cs
new file mode 100644
index 0000000..3235285
--- /dev/null
+++ b/BluetoothManager.cs
@@ -0,0 +1,171 @@
+using System;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using System.Timers;
+using Windows.Devices.Bluetooth;
+using Windows.Devices.Radios;
+
+namespace MeetingClock
+{
+ public class BluetoothManager
+ {
+ public enum BluetoothState
+ {
+ NotInitialized,
+ Exception,
+ NoBluetoothAdapter,
+ NoBluetoothRadio,
+ Disabled,
+ Off,
+ On,
+ Unknown
+ }
+
+ public delegate void BluetoothStateChangeHandler(BluetoothManager manager, BluetoothState oldState, BluetoothState newState);
+ public event BluetoothStateChangeHandler StateChanged;
+
+ public BluetoothState State { get; private set; } = BluetoothState.NotInitialized;
+
+ private BluetoothAdapter adapter;
+ private Radio radio;
+ private Timer updateTimer;
+
+ public BluetoothManager()
+ {
+ this.updateTimer = new Timer(100);
+ this.updateTimer.Elapsed += UpdateTimer_Elapsed;
+ }
+
+ public async Task Initialize()
+ {
+ await this.InitializePrivate(true);
+ }
+
+ private async Task InitializePrivate(bool withLog)
+ {
+ try
+ {
+ this.adapter = await BluetoothAdapter.GetDefaultAsync();
+ if (this.adapter == null)
+ {
+ if (withLog)
+ {
+ Debug.WriteLine("No BluetoothAdapter found");
+ }
+ this.State = BluetoothState.NoBluetoothAdapter;
+ this.StateChanged(this, BluetoothState.NotInitialized, BluetoothState.NoBluetoothAdapter);
+ this.updateTimer.Start();
+ return;
+ }
+ if (withLog)
+ {
+ Debug.WriteLine(String.Format("Found BluetoothAdapter device id: {0}, address: {1}", this.adapter.DeviceId, this.adapter.BluetoothAddress));
+ }
+
+ this.radio = await this.adapter.GetRadioAsync();
+ if (this.radio == null)
+ {
+ if (withLog)
+ {
+ Debug.WriteLine("No Radio found");
+ }
+ this.State = BluetoothState.NoBluetoothRadio;
+ this.StateChanged(this, BluetoothState.NotInitialized, BluetoothState.NoBluetoothRadio);
+ this.updateTimer.Start();
+ return;
+ }
+ if (withLog)
+ {
+ Debug.WriteLine(String.Format("Found Bluetooth Radio device: {0}", this.radio.Name));
+ }
+
+ this.radio.StateChanged += Radio_StateChanged;
+ this.UpdateState();
+
+ if (withLog)
+ {
+ Debug.WriteLine(String.Format("Bluetooth State: {0}", this.State));
+ }
+
+ this.updateTimer.Start();
+ }
+ catch (Exception exception)
+ {
+
+ if (withLog)
+ {
+ Debug.WriteLine(String.Format("Exception while discovering bluetooth adapter, radio, and state: {0}", exception.Message));
+ }
+ this.State = BluetoothState.Exception;
+ this.StateChanged(this, BluetoothState.NotInitialized, BluetoothState.Exception);
+ }
+ }
+
+ private void UpdateState() {
+ RadioState state = this.radio.State;
+ BluetoothState oldState = this.State;
+ BluetoothState btState;
+ switch (state)
+ {
+ case RadioState.Disabled:
+ btState = BluetoothState.Disabled;
+ break;
+ case RadioState.Off:
+ btState = BluetoothState.Off;
+ break;
+ case RadioState.On:
+ btState = BluetoothState.On;
+ break;
+ default:
+ btState = BluetoothState.Unknown;
+ break;
+ }
+
+ if (btState != this.State)
+ {
+ Debug.WriteLine(String.Format("New Bluetooth state detected. Old state {0}, new state {1}", this.State, btState));
+ this.State = btState;
+ if (this.StateChanged != null)
+ {
+ this.StateChanged(this, oldState, btState);
+ }
+ }
+ }
+
+ private void Radio_StateChanged(Radio sender, object args)
+ {
+ this.UpdateState();
+ }
+
+ private async void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ switch (this.State)
+ {
+ case BluetoothState.Exception:
+ this.updateTimer.Stop();
+ break;
+ case BluetoothState.NotInitialized:
+ case BluetoothState.NoBluetoothAdapter:
+ case BluetoothState.NoBluetoothRadio:
+ await this.InitializePrivate(false);
+ break;
+ default:
+ this.UpdateState();
+ break;
+ }
+ }
+
+ public async Task Enable()
+ {
+ if (this.radio != null) {
+ return await this.radio.SetStateAsync(RadioState.On);
+ }
+ return RadioAccessStatus.Unspecified;
+ }
+
+ public void Stop()
+ {
+ this.updateTimer.Stop();
+ }
+ }
+}
diff --git a/MainWindow.Designer.cs b/MainWindow.Designer.cs
new file mode 100644
index 0000000..f21c1db
--- /dev/null
+++ b/MainWindow.Designer.cs
@@ -0,0 +1,752 @@
+
+namespace MeetingClock
+{
+ partial class MainWindow
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow));
+ this.groupBoxState = new System.Windows.Forms.GroupBox();
+ this.buttonWebsite = new System.Windows.Forms.Button();
+ this.buttonOpenSystemSettingsBluetooth = new System.Windows.Forms.Button();
+ this.labelMeetingClockState = new System.Windows.Forms.Label();
+ this.labelMeetingClockStateTitle = new System.Windows.Forms.Label();
+ this.buttonOpenSystemSettingsPrivacy = new System.Windows.Forms.Button();
+ this.buttonEnableBluetooth = new System.Windows.Forms.Button();
+ this.labelBluetoothState = new System.Windows.Forms.Label();
+ this.labelBluetoothStateTitle = new System.Windows.Forms.Label();
+ this.groupBoxApplicationSettings = new System.Windows.Forms.GroupBox();
+ this.checkBoxEnableBluetooth = new System.Windows.Forms.CheckBox();
+ this.checkBoxCheckForUpdates = new System.Windows.Forms.CheckBox();
+ this.checkBoxStartMinimized = new System.Windows.Forms.CheckBox();
+ this.checkBoxAutostart = new System.Windows.Forms.CheckBox();
+ this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
+ this.timerEnableBalloon = new System.Windows.Forms.Timer(this.components);
+ this.groupBoxAppointmentSettings = new System.Windows.Forms.GroupBox();
+ this.checkBoxIgnoreTentativeAppointments = new System.Windows.Forms.CheckBox();
+ this.checkBoxIgnoreOutOfOfficeAppointments = new System.Windows.Forms.CheckBox();
+ this.checkBoxIgnoreFreeAppointments = new System.Windows.Forms.CheckBox();
+ this.checkBoxIgnoreCancelledAppointments = new System.Windows.Forms.CheckBox();
+ this.checkBoxIgnoreAllDayAppointments = new System.Windows.Forms.CheckBox();
+ this.groupBoxClockSettings = new System.Windows.Forms.GroupBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.numericUpDownScrollWait = new System.Windows.Forms.NumericUpDown();
+ this.labelScrollWaitTitle = new System.Windows.Forms.Label();
+ this.labelScrollSpeed = new System.Windows.Forms.Label();
+ this.labelScrollSpeedTitle = new System.Windows.Forms.Label();
+ this.trackBarScrollSpeed = new System.Windows.Forms.TrackBar();
+ this.labelBrightness = new System.Windows.Forms.Label();
+ this.labelBrightnessTitle = new System.Windows.Forms.Label();
+ this.trackBarBrightness = new System.Windows.Forms.TrackBar();
+ this.labelTemperatureIntervalTitleSeconds = new System.Windows.Forms.Label();
+ this.numericUpDownTemperatureInterval = new System.Windows.Forms.NumericUpDown();
+ this.checkBoxTemperatureEnabled = new System.Windows.Forms.CheckBox();
+ this.labelDateIntervalTitleSeconds = new System.Windows.Forms.Label();
+ this.numericUpDownDateInterval = new System.Windows.Forms.NumericUpDown();
+ this.labelTimeIntervalTitleSeconds = new System.Windows.Forms.Label();
+ this.numericUpDownTimeInterval = new System.Windows.Forms.NumericUpDown();
+ this.labelTimeIntervalTitle = new System.Windows.Forms.Label();
+ this.checkBoxDateEnabled = new System.Windows.Forms.CheckBox();
+ this.timerScrollDemo = new System.Windows.Forms.Timer(this.components);
+ this.buttonResetDefault = new System.Windows.Forms.Button();
+ this.timerAdjustClock = new System.Windows.Forms.Timer(this.components);
+ this.timerGetAppointment = new System.Windows.Forms.Timer(this.components);
+ this.label2 = new System.Windows.Forms.Label();
+ this.numericUpDownReminderTime = new System.Windows.Forms.NumericUpDown();
+ this.labelStartReminderTitle = new System.Windows.Forms.Label();
+ this.groupBoxState.SuspendLayout();
+ this.groupBoxApplicationSettings.SuspendLayout();
+ this.groupBoxAppointmentSettings.SuspendLayout();
+ this.groupBoxClockSettings.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownScrollWait)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.trackBarScrollSpeed)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.trackBarBrightness)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownTemperatureInterval)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownDateInterval)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownTimeInterval)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownReminderTime)).BeginInit();
+ this.SuspendLayout();
+ //
+ // groupBoxState
+ //
+ this.groupBoxState.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBoxState.Controls.Add(this.buttonWebsite);
+ this.groupBoxState.Controls.Add(this.buttonOpenSystemSettingsBluetooth);
+ this.groupBoxState.Controls.Add(this.labelMeetingClockState);
+ this.groupBoxState.Controls.Add(this.labelMeetingClockStateTitle);
+ this.groupBoxState.Controls.Add(this.buttonOpenSystemSettingsPrivacy);
+ this.groupBoxState.Controls.Add(this.buttonEnableBluetooth);
+ this.groupBoxState.Controls.Add(this.labelBluetoothState);
+ this.groupBoxState.Controls.Add(this.labelBluetoothStateTitle);
+ this.groupBoxState.Location = new System.Drawing.Point(12, 12);
+ this.groupBoxState.Name = "groupBoxState";
+ this.groupBoxState.Size = new System.Drawing.Size(560, 100);
+ this.groupBoxState.TabIndex = 0;
+ this.groupBoxState.TabStop = false;
+ this.groupBoxState.Text = "State";
+ //
+ // buttonWebsite
+ //
+ this.buttonWebsite.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonWebsite.Location = new System.Drawing.Point(392, 65);
+ this.buttonWebsite.Name = "buttonWebsite";
+ this.buttonWebsite.Size = new System.Drawing.Size(162, 23);
+ this.buttonWebsite.TabIndex = 8;
+ this.buttonWebsite.Text = "Open Website";
+ this.buttonWebsite.UseVisualStyleBackColor = true;
+ this.buttonWebsite.Click += new System.EventHandler(this.buttonWebsite_Click);
+ //
+ // buttonOpenSystemSettingsBluetooth
+ //
+ this.buttonOpenSystemSettingsBluetooth.Location = new System.Drawing.Point(197, 65);
+ this.buttonOpenSystemSettingsBluetooth.Name = "buttonOpenSystemSettingsBluetooth";
+ this.buttonOpenSystemSettingsBluetooth.Size = new System.Drawing.Size(185, 23);
+ this.buttonOpenSystemSettingsBluetooth.TabIndex = 7;
+ this.buttonOpenSystemSettingsBluetooth.Text = "Open System Settings: Bluetooth";
+ this.buttonOpenSystemSettingsBluetooth.UseVisualStyleBackColor = true;
+ this.buttonOpenSystemSettingsBluetooth.Click += new System.EventHandler(this.buttonOpenSystemSettingsBluetooth_Click);
+ //
+ // labelMeetingClockState
+ //
+ this.labelMeetingClockState.AutoSize = true;
+ this.labelMeetingClockState.Location = new System.Drawing.Point(99, 46);
+ this.labelMeetingClockState.Name = "labelMeetingClockState";
+ this.labelMeetingClockState.Size = new System.Drawing.Size(51, 13);
+ this.labelMeetingClockState.TabIndex = 6;
+ this.labelMeetingClockState.Text = "unknown";
+ //
+ // labelMeetingClockStateTitle
+ //
+ this.labelMeetingClockStateTitle.AutoSize = true;
+ this.labelMeetingClockStateTitle.Location = new System.Drawing.Point(7, 46);
+ this.labelMeetingClockStateTitle.Name = "labelMeetingClockStateTitle";
+ this.labelMeetingClockStateTitle.Size = new System.Drawing.Size(78, 13);
+ this.labelMeetingClockStateTitle.TabIndex = 5;
+ this.labelMeetingClockStateTitle.Text = "Meeting Clock:";
+ //
+ // buttonOpenSystemSettingsPrivacy
+ //
+ this.buttonOpenSystemSettingsPrivacy.Location = new System.Drawing.Point(6, 65);
+ this.buttonOpenSystemSettingsPrivacy.Name = "buttonOpenSystemSettingsPrivacy";
+ this.buttonOpenSystemSettingsPrivacy.Size = new System.Drawing.Size(185, 23);
+ this.buttonOpenSystemSettingsPrivacy.TabIndex = 3;
+ this.buttonOpenSystemSettingsPrivacy.Text = "Open System Settings: Privacy";
+ this.buttonOpenSystemSettingsPrivacy.UseVisualStyleBackColor = true;
+ this.buttonOpenSystemSettingsPrivacy.Click += new System.EventHandler(this.ButtonOpenSystemSettingsPrivacy_Click);
+ //
+ // buttonEnableBluetooth
+ //
+ this.buttonEnableBluetooth.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonEnableBluetooth.Enabled = false;
+ this.buttonEnableBluetooth.Location = new System.Drawing.Point(392, 19);
+ this.buttonEnableBluetooth.Name = "buttonEnableBluetooth";
+ this.buttonEnableBluetooth.Size = new System.Drawing.Size(162, 40);
+ this.buttonEnableBluetooth.TabIndex = 2;
+ this.buttonEnableBluetooth.Text = "Enable Bluetooth";
+ this.buttonEnableBluetooth.UseVisualStyleBackColor = true;
+ this.buttonEnableBluetooth.Click += new System.EventHandler(this.ButtonEnableBluetooth_Click);
+ //
+ // labelBluetoothState
+ //
+ this.labelBluetoothState.AutoSize = true;
+ this.labelBluetoothState.Location = new System.Drawing.Point(99, 24);
+ this.labelBluetoothState.Name = "labelBluetoothState";
+ this.labelBluetoothState.Size = new System.Drawing.Size(51, 13);
+ this.labelBluetoothState.TabIndex = 1;
+ this.labelBluetoothState.Text = "unknown";
+ //
+ // labelBluetoothStateTitle
+ //
+ this.labelBluetoothStateTitle.AutoSize = true;
+ this.labelBluetoothStateTitle.Location = new System.Drawing.Point(7, 24);
+ this.labelBluetoothStateTitle.Name = "labelBluetoothStateTitle";
+ this.labelBluetoothStateTitle.Size = new System.Drawing.Size(83, 13);
+ this.labelBluetoothStateTitle.TabIndex = 0;
+ this.labelBluetoothStateTitle.Text = "Bluetooth State:";
+ //
+ // groupBoxApplicationSettings
+ //
+ this.groupBoxApplicationSettings.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBoxApplicationSettings.Controls.Add(this.checkBoxEnableBluetooth);
+ this.groupBoxApplicationSettings.Controls.Add(this.checkBoxCheckForUpdates);
+ this.groupBoxApplicationSettings.Controls.Add(this.checkBoxStartMinimized);
+ this.groupBoxApplicationSettings.Controls.Add(this.checkBoxAutostart);
+ this.groupBoxApplicationSettings.Location = new System.Drawing.Point(12, 118);
+ this.groupBoxApplicationSettings.Name = "groupBoxApplicationSettings";
+ this.groupBoxApplicationSettings.Size = new System.Drawing.Size(560, 116);
+ this.groupBoxApplicationSettings.TabIndex = 1;
+ this.groupBoxApplicationSettings.TabStop = false;
+ this.groupBoxApplicationSettings.Text = "Application Settings";
+ //
+ // checkBoxEnableBluetooth
+ //
+ this.checkBoxEnableBluetooth.AutoSize = true;
+ this.checkBoxEnableBluetooth.Location = new System.Drawing.Point(6, 91);
+ this.checkBoxEnableBluetooth.Name = "checkBoxEnableBluetooth";
+ this.checkBoxEnableBluetooth.Size = new System.Drawing.Size(172, 17);
+ this.checkBoxEnableBluetooth.TabIndex = 3;
+ this.checkBoxEnableBluetooth.Text = "Automatically Enable Bluetooth";
+ this.checkBoxEnableBluetooth.UseVisualStyleBackColor = true;
+ this.checkBoxEnableBluetooth.CheckedChanged += new System.EventHandler(this.checkBoxEnableBluetooth_CheckedChanged);
+ //
+ // checkBoxCheckForUpdates
+ //
+ this.checkBoxCheckForUpdates.AutoSize = true;
+ this.checkBoxCheckForUpdates.Location = new System.Drawing.Point(6, 67);
+ this.checkBoxCheckForUpdates.Name = "checkBoxCheckForUpdates";
+ this.checkBoxCheckForUpdates.Size = new System.Drawing.Size(180, 17);
+ this.checkBoxCheckForUpdates.TabIndex = 2;
+ this.checkBoxCheckForUpdates.Text = "Automatically Check for Updates";
+ this.checkBoxCheckForUpdates.UseVisualStyleBackColor = true;
+ this.checkBoxCheckForUpdates.CheckedChanged += new System.EventHandler(this.checkBoxCheckForUpdates_CheckedChanged);
+ //
+ // checkBoxStartMinimized
+ //
+ this.checkBoxStartMinimized.AutoSize = true;
+ this.checkBoxStartMinimized.Location = new System.Drawing.Point(6, 43);
+ this.checkBoxStartMinimized.Name = "checkBoxStartMinimized";
+ this.checkBoxStartMinimized.Size = new System.Drawing.Size(97, 17);
+ this.checkBoxStartMinimized.TabIndex = 1;
+ this.checkBoxStartMinimized.Text = "Start Minimized";
+ this.checkBoxStartMinimized.UseVisualStyleBackColor = true;
+ this.checkBoxStartMinimized.CheckedChanged += new System.EventHandler(this.checkBoxStartMinimized_CheckedChanged);
+ //
+ // checkBoxAutostart
+ //
+ this.checkBoxAutostart.AutoSize = true;
+ this.checkBoxAutostart.Location = new System.Drawing.Point(6, 19);
+ this.checkBoxAutostart.Name = "checkBoxAutostart";
+ this.checkBoxAutostart.Size = new System.Drawing.Size(182, 17);
+ this.checkBoxAutostart.TabIndex = 0;
+ this.checkBoxAutostart.Text = "Automatically Start with Windows";
+ this.checkBoxAutostart.UseVisualStyleBackColor = true;
+ this.checkBoxAutostart.CheckedChanged += new System.EventHandler(this.checkBoxAutostart_CheckedChanged);
+ //
+ // notifyIcon
+ //
+ this.notifyIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
+ this.notifyIcon.BalloonTipText = "Meeting Clock was minimized to the tray";
+ this.notifyIcon.BalloonTipTitle = "Minimized to Tray";
+ this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon")));
+ this.notifyIcon.Text = "Meeting Clock";
+ this.notifyIcon.Visible = true;
+ this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.NotifyIcon_MouseDoubleClick);
+ //
+ // timerEnableBalloon
+ //
+ this.timerEnableBalloon.Enabled = true;
+ this.timerEnableBalloon.Interval = 1000;
+ this.timerEnableBalloon.Tick += new System.EventHandler(this.timerEnableBalloon_Tick);
+ //
+ // groupBoxAppointmentSettings
+ //
+ this.groupBoxAppointmentSettings.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBoxAppointmentSettings.Controls.Add(this.label2);
+ this.groupBoxAppointmentSettings.Controls.Add(this.checkBoxIgnoreTentativeAppointments);
+ this.groupBoxAppointmentSettings.Controls.Add(this.numericUpDownReminderTime);
+ this.groupBoxAppointmentSettings.Controls.Add(this.labelStartReminderTitle);
+ this.groupBoxAppointmentSettings.Controls.Add(this.checkBoxIgnoreOutOfOfficeAppointments);
+ this.groupBoxAppointmentSettings.Controls.Add(this.checkBoxIgnoreFreeAppointments);
+ this.groupBoxAppointmentSettings.Controls.Add(this.checkBoxIgnoreCancelledAppointments);
+ this.groupBoxAppointmentSettings.Controls.Add(this.checkBoxIgnoreAllDayAppointments);
+ this.groupBoxAppointmentSettings.Location = new System.Drawing.Point(12, 241);
+ this.groupBoxAppointmentSettings.Name = "groupBoxAppointmentSettings";
+ this.groupBoxAppointmentSettings.Size = new System.Drawing.Size(560, 166);
+ this.groupBoxAppointmentSettings.TabIndex = 2;
+ this.groupBoxAppointmentSettings.TabStop = false;
+ this.groupBoxAppointmentSettings.Text = "Appointment Settings";
+ //
+ // checkBoxIgnoreTentativeAppointments
+ //
+ this.checkBoxIgnoreTentativeAppointments.AutoSize = true;
+ this.checkBoxIgnoreTentativeAppointments.Location = new System.Drawing.Point(6, 115);
+ this.checkBoxIgnoreTentativeAppointments.Name = "checkBoxIgnoreTentativeAppointments";
+ this.checkBoxIgnoreTentativeAppointments.Size = new System.Drawing.Size(234, 17);
+ this.checkBoxIgnoreTentativeAppointments.TabIndex = 4;
+ this.checkBoxIgnoreTentativeAppointments.Text = "Ignore Appointments Marked as \"Tentative\"";
+ this.checkBoxIgnoreTentativeAppointments.UseVisualStyleBackColor = true;
+ this.checkBoxIgnoreTentativeAppointments.CheckedChanged += new System.EventHandler(this.checkBoxIgnoreTentativeAppointments_CheckedChanged);
+ //
+ // checkBoxIgnoreOutOfOfficeAppointments
+ //
+ this.checkBoxIgnoreOutOfOfficeAppointments.AutoSize = true;
+ this.checkBoxIgnoreOutOfOfficeAppointments.Location = new System.Drawing.Point(6, 91);
+ this.checkBoxIgnoreOutOfOfficeAppointments.Name = "checkBoxIgnoreOutOfOfficeAppointments";
+ this.checkBoxIgnoreOutOfOfficeAppointments.Size = new System.Drawing.Size(249, 17);
+ this.checkBoxIgnoreOutOfOfficeAppointments.TabIndex = 3;
+ this.checkBoxIgnoreOutOfOfficeAppointments.Text = "Ignore Appointments Marked as \"Out of Office\"";
+ this.checkBoxIgnoreOutOfOfficeAppointments.UseVisualStyleBackColor = true;
+ this.checkBoxIgnoreOutOfOfficeAppointments.CheckedChanged += new System.EventHandler(this.checkBoxIgnoreOutOfOfficeAppointments_CheckedChanged);
+ //
+ // checkBoxIgnoreFreeAppointments
+ //
+ this.checkBoxIgnoreFreeAppointments.AutoSize = true;
+ this.checkBoxIgnoreFreeAppointments.Location = new System.Drawing.Point(6, 67);
+ this.checkBoxIgnoreFreeAppointments.Name = "checkBoxIgnoreFreeAppointments";
+ this.checkBoxIgnoreFreeAppointments.Size = new System.Drawing.Size(210, 17);
+ this.checkBoxIgnoreFreeAppointments.TabIndex = 2;
+ this.checkBoxIgnoreFreeAppointments.Text = "Ignore Appointments Marked as \"Free\"";
+ this.checkBoxIgnoreFreeAppointments.UseVisualStyleBackColor = true;
+ this.checkBoxIgnoreFreeAppointments.CheckedChanged += new System.EventHandler(this.checkBoxIgnoreFreeAppointments_CheckedChanged);
+ //
+ // checkBoxIgnoreCancelledAppointments
+ //
+ this.checkBoxIgnoreCancelledAppointments.AutoSize = true;
+ this.checkBoxIgnoreCancelledAppointments.Location = new System.Drawing.Point(6, 43);
+ this.checkBoxIgnoreCancelledAppointments.Name = "checkBoxIgnoreCancelledAppointments";
+ this.checkBoxIgnoreCancelledAppointments.Size = new System.Drawing.Size(173, 17);
+ this.checkBoxIgnoreCancelledAppointments.TabIndex = 1;
+ this.checkBoxIgnoreCancelledAppointments.Text = "Ignore Cancelled Appointments";
+ this.checkBoxIgnoreCancelledAppointments.UseVisualStyleBackColor = true;
+ this.checkBoxIgnoreCancelledAppointments.CheckedChanged += new System.EventHandler(this.checkBoxIgnoreCancelledAppointments_CheckedChanged);
+ //
+ // checkBoxIgnoreAllDayAppointments
+ //
+ this.checkBoxIgnoreAllDayAppointments.AutoSize = true;
+ this.checkBoxIgnoreAllDayAppointments.Location = new System.Drawing.Point(6, 19);
+ this.checkBoxIgnoreAllDayAppointments.Name = "checkBoxIgnoreAllDayAppointments";
+ this.checkBoxIgnoreAllDayAppointments.Size = new System.Drawing.Size(159, 17);
+ this.checkBoxIgnoreAllDayAppointments.TabIndex = 0;
+ this.checkBoxIgnoreAllDayAppointments.Text = "Ignore All-Day Appointments";
+ this.checkBoxIgnoreAllDayAppointments.UseVisualStyleBackColor = true;
+ this.checkBoxIgnoreAllDayAppointments.CheckedChanged += new System.EventHandler(this.checkBoxIgnoreAllDayAppointments_CheckedChanged);
+ //
+ // groupBoxClockSettings
+ //
+ this.groupBoxClockSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBoxClockSettings.Controls.Add(this.buttonResetDefault);
+ this.groupBoxClockSettings.Controls.Add(this.label1);
+ this.groupBoxClockSettings.Controls.Add(this.numericUpDownScrollWait);
+ this.groupBoxClockSettings.Controls.Add(this.labelScrollWaitTitle);
+ this.groupBoxClockSettings.Controls.Add(this.labelScrollSpeed);
+ this.groupBoxClockSettings.Controls.Add(this.labelScrollSpeedTitle);
+ this.groupBoxClockSettings.Controls.Add(this.trackBarScrollSpeed);
+ this.groupBoxClockSettings.Controls.Add(this.labelBrightness);
+ this.groupBoxClockSettings.Controls.Add(this.labelBrightnessTitle);
+ this.groupBoxClockSettings.Controls.Add(this.trackBarBrightness);
+ this.groupBoxClockSettings.Controls.Add(this.labelTemperatureIntervalTitleSeconds);
+ this.groupBoxClockSettings.Controls.Add(this.numericUpDownTemperatureInterval);
+ this.groupBoxClockSettings.Controls.Add(this.checkBoxTemperatureEnabled);
+ this.groupBoxClockSettings.Controls.Add(this.labelDateIntervalTitleSeconds);
+ this.groupBoxClockSettings.Controls.Add(this.numericUpDownDateInterval);
+ this.groupBoxClockSettings.Controls.Add(this.labelTimeIntervalTitleSeconds);
+ this.groupBoxClockSettings.Controls.Add(this.numericUpDownTimeInterval);
+ this.groupBoxClockSettings.Controls.Add(this.labelTimeIntervalTitle);
+ this.groupBoxClockSettings.Controls.Add(this.checkBoxDateEnabled);
+ this.groupBoxClockSettings.Enabled = false;
+ this.groupBoxClockSettings.Location = new System.Drawing.Point(12, 413);
+ this.groupBoxClockSettings.Name = "groupBoxClockSettings";
+ this.groupBoxClockSettings.Size = new System.Drawing.Size(560, 200);
+ this.groupBoxClockSettings.TabIndex = 3;
+ this.groupBoxClockSettings.TabStop = false;
+ this.groupBoxClockSettings.Text = "Clock Settings";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(227, 170);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(49, 13);
+ this.label1.TabIndex = 18;
+ this.label1.Text = "Seconds";
+ //
+ // numericUpDownScrollWait
+ //
+ this.numericUpDownScrollWait.DecimalPlaces = 1;
+ this.numericUpDownScrollWait.Location = new System.Drawing.Point(162, 166);
+ this.numericUpDownScrollWait.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 65536});
+ this.numericUpDownScrollWait.Name = "numericUpDownScrollWait";
+ this.numericUpDownScrollWait.Size = new System.Drawing.Size(63, 20);
+ this.numericUpDownScrollWait.TabIndex = 17;
+ this.numericUpDownScrollWait.Value = new decimal(new int[] {
+ 4,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownScrollWait.ValueChanged += new System.EventHandler(this.numericUpDownScrollWait_ValueChanged);
+ //
+ // labelScrollWaitTitle
+ //
+ this.labelScrollWaitTitle.AutoSize = true;
+ this.labelScrollWaitTitle.Location = new System.Drawing.Point(6, 170);
+ this.labelScrollWaitTitle.Name = "labelScrollWaitTitle";
+ this.labelScrollWaitTitle.Size = new System.Drawing.Size(106, 13);
+ this.labelScrollWaitTitle.TabIndex = 16;
+ this.labelScrollWaitTitle.Text = "Wait Before Scrolling";
+ //
+ // labelScrollSpeed
+ //
+ this.labelScrollSpeed.AutoSize = true;
+ this.labelScrollSpeed.Location = new System.Drawing.Point(503, 131);
+ this.labelScrollSpeed.Name = "labelScrollSpeed";
+ this.labelScrollSpeed.Size = new System.Drawing.Size(13, 13);
+ this.labelScrollSpeed.TabIndex = 15;
+ this.labelScrollSpeed.Text = "5";
+ //
+ // labelScrollSpeedTitle
+ //
+ this.labelScrollSpeedTitle.AutoSize = true;
+ this.labelScrollSpeedTitle.Location = new System.Drawing.Point(6, 131);
+ this.labelScrollSpeedTitle.Name = "labelScrollSpeedTitle";
+ this.labelScrollSpeedTitle.Size = new System.Drawing.Size(67, 13);
+ this.labelScrollSpeedTitle.TabIndex = 14;
+ this.labelScrollSpeedTitle.Text = "Scroll Speed";
+ //
+ // trackBarScrollSpeed
+ //
+ this.trackBarScrollSpeed.Location = new System.Drawing.Point(162, 126);
+ this.trackBarScrollSpeed.Maximum = 100;
+ this.trackBarScrollSpeed.Name = "trackBarScrollSpeed";
+ this.trackBarScrollSpeed.Size = new System.Drawing.Size(334, 45);
+ this.trackBarScrollSpeed.TabIndex = 13;
+ this.trackBarScrollSpeed.TickFrequency = 5;
+ this.trackBarScrollSpeed.Value = 5;
+ this.trackBarScrollSpeed.ValueChanged += new System.EventHandler(this.trackBarScrollSpeed_ValueChanged);
+ //
+ // labelBrightness
+ //
+ this.labelBrightness.AutoSize = true;
+ this.labelBrightness.Location = new System.Drawing.Point(503, 93);
+ this.labelBrightness.Name = "labelBrightness";
+ this.labelBrightness.Size = new System.Drawing.Size(19, 13);
+ this.labelBrightness.TabIndex = 12;
+ this.labelBrightness.Text = "15";
+ //
+ // labelBrightnessTitle
+ //
+ this.labelBrightnessTitle.AutoSize = true;
+ this.labelBrightnessTitle.Location = new System.Drawing.Point(6, 93);
+ this.labelBrightnessTitle.Name = "labelBrightnessTitle";
+ this.labelBrightnessTitle.Size = new System.Drawing.Size(56, 13);
+ this.labelBrightnessTitle.TabIndex = 11;
+ this.labelBrightnessTitle.Text = "Brightness";
+ //
+ // trackBarBrightness
+ //
+ this.trackBarBrightness.Location = new System.Drawing.Point(162, 88);
+ this.trackBarBrightness.Maximum = 15;
+ this.trackBarBrightness.Minimum = 1;
+ this.trackBarBrightness.Name = "trackBarBrightness";
+ this.trackBarBrightness.Size = new System.Drawing.Size(334, 45);
+ this.trackBarBrightness.TabIndex = 10;
+ this.trackBarBrightness.Value = 15;
+ this.trackBarBrightness.ValueChanged += new System.EventHandler(this.trackBarBrightness_ValueChanged);
+ //
+ // labelTemperatureIntervalTitleSeconds
+ //
+ this.labelTemperatureIntervalTitleSeconds.AutoSize = true;
+ this.labelTemperatureIntervalTitleSeconds.Location = new System.Drawing.Point(227, 68);
+ this.labelTemperatureIntervalTitleSeconds.Name = "labelTemperatureIntervalTitleSeconds";
+ this.labelTemperatureIntervalTitleSeconds.Size = new System.Drawing.Size(49, 13);
+ this.labelTemperatureIntervalTitleSeconds.TabIndex = 9;
+ this.labelTemperatureIntervalTitleSeconds.Text = "Seconds";
+ //
+ // numericUpDownTemperatureInterval
+ //
+ this.numericUpDownTemperatureInterval.Location = new System.Drawing.Point(162, 64);
+ this.numericUpDownTemperatureInterval.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownTemperatureInterval.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownTemperatureInterval.Name = "numericUpDownTemperatureInterval";
+ this.numericUpDownTemperatureInterval.Size = new System.Drawing.Size(63, 20);
+ this.numericUpDownTemperatureInterval.TabIndex = 8;
+ this.numericUpDownTemperatureInterval.Value = new decimal(new int[] {
+ 3,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownTemperatureInterval.ValueChanged += new System.EventHandler(this.numericUpDownTemperatureInterval_ValueChanged);
+ //
+ // checkBoxTemperatureEnabled
+ //
+ this.checkBoxTemperatureEnabled.AutoSize = true;
+ this.checkBoxTemperatureEnabled.Location = new System.Drawing.Point(6, 66);
+ this.checkBoxTemperatureEnabled.Name = "checkBoxTemperatureEnabled";
+ this.checkBoxTemperatureEnabled.Size = new System.Drawing.Size(149, 17);
+ this.checkBoxTemperatureEnabled.TabIndex = 7;
+ this.checkBoxTemperatureEnabled.Text = "Show the Temperature for";
+ this.checkBoxTemperatureEnabled.UseVisualStyleBackColor = true;
+ this.checkBoxTemperatureEnabled.CheckedChanged += new System.EventHandler(this.checkBoxTemperatureEnabled_CheckedChanged);
+ //
+ // labelDateIntervalTitleSeconds
+ //
+ this.labelDateIntervalTitleSeconds.AutoSize = true;
+ this.labelDateIntervalTitleSeconds.Location = new System.Drawing.Point(227, 45);
+ this.labelDateIntervalTitleSeconds.Name = "labelDateIntervalTitleSeconds";
+ this.labelDateIntervalTitleSeconds.Size = new System.Drawing.Size(49, 13);
+ this.labelDateIntervalTitleSeconds.TabIndex = 6;
+ this.labelDateIntervalTitleSeconds.Text = "Seconds";
+ //
+ // numericUpDownDateInterval
+ //
+ this.numericUpDownDateInterval.Location = new System.Drawing.Point(162, 41);
+ this.numericUpDownDateInterval.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownDateInterval.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownDateInterval.Name = "numericUpDownDateInterval";
+ this.numericUpDownDateInterval.Size = new System.Drawing.Size(63, 20);
+ this.numericUpDownDateInterval.TabIndex = 5;
+ this.numericUpDownDateInterval.Value = new decimal(new int[] {
+ 3,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownDateInterval.ValueChanged += new System.EventHandler(this.numericUpDownDateInterval_ValueChanged);
+ //
+ // labelTimeIntervalTitleSeconds
+ //
+ this.labelTimeIntervalTitleSeconds.AutoSize = true;
+ this.labelTimeIntervalTitleSeconds.Location = new System.Drawing.Point(227, 22);
+ this.labelTimeIntervalTitleSeconds.Name = "labelTimeIntervalTitleSeconds";
+ this.labelTimeIntervalTitleSeconds.Size = new System.Drawing.Size(49, 13);
+ this.labelTimeIntervalTitleSeconds.TabIndex = 4;
+ this.labelTimeIntervalTitleSeconds.Text = "Seconds";
+ //
+ // numericUpDownTimeInterval
+ //
+ this.numericUpDownTimeInterval.Location = new System.Drawing.Point(162, 18);
+ this.numericUpDownTimeInterval.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownTimeInterval.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownTimeInterval.Name = "numericUpDownTimeInterval";
+ this.numericUpDownTimeInterval.Size = new System.Drawing.Size(63, 20);
+ this.numericUpDownTimeInterval.TabIndex = 3;
+ this.numericUpDownTimeInterval.Value = new decimal(new int[] {
+ 35,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownTimeInterval.ValueChanged += new System.EventHandler(this.numericUpDownTimeInterval_ValueChanged);
+ //
+ // labelTimeIntervalTitle
+ //
+ this.labelTimeIntervalTitle.AutoSize = true;
+ this.labelTimeIntervalTitle.Location = new System.Drawing.Point(6, 22);
+ this.labelTimeIntervalTitle.Name = "labelTimeIntervalTitle";
+ this.labelTimeIntervalTitle.Size = new System.Drawing.Size(93, 13);
+ this.labelTimeIntervalTitle.TabIndex = 2;
+ this.labelTimeIntervalTitle.Text = "Show the Time for";
+ //
+ // checkBoxDateEnabled
+ //
+ this.checkBoxDateEnabled.AutoSize = true;
+ this.checkBoxDateEnabled.Location = new System.Drawing.Point(6, 43);
+ this.checkBoxDateEnabled.Name = "checkBoxDateEnabled";
+ this.checkBoxDateEnabled.Size = new System.Drawing.Size(112, 17);
+ this.checkBoxDateEnabled.TabIndex = 1;
+ this.checkBoxDateEnabled.Text = "Show the Date for";
+ this.checkBoxDateEnabled.UseVisualStyleBackColor = true;
+ this.checkBoxDateEnabled.CheckedChanged += new System.EventHandler(this.checkBoxDateEnabled_CheckedChanged);
+ //
+ // timerScrollDemo
+ //
+ this.timerScrollDemo.Interval = 10000;
+ this.timerScrollDemo.Tick += new System.EventHandler(this.timerScrollDemo_Tick);
+ //
+ // buttonResetDefault
+ //
+ this.buttonResetDefault.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonResetDefault.Location = new System.Drawing.Point(392, 18);
+ this.buttonResetDefault.Name = "buttonResetDefault";
+ this.buttonResetDefault.Size = new System.Drawing.Size(162, 43);
+ this.buttonResetDefault.TabIndex = 19;
+ this.buttonResetDefault.Text = "Reset All to Default";
+ this.buttonResetDefault.UseVisualStyleBackColor = true;
+ this.buttonResetDefault.Click += new System.EventHandler(this.buttonResetDefault_Click);
+ //
+ // timerAdjustClock
+ //
+ this.timerAdjustClock.Enabled = true;
+ this.timerAdjustClock.Interval = 7200000;
+ this.timerAdjustClock.Tick += new System.EventHandler(this.timerAdjustClock_Tick);
+ //
+ // timerGetAppointment
+ //
+ this.timerGetAppointment.Enabled = true;
+ this.timerGetAppointment.Interval = 60000;
+ this.timerGetAppointment.Tick += new System.EventHandler(this.timerGetAppointment_Tick);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(227, 142);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(188, 13);
+ this.label2.TabIndex = 22;
+ this.label2.Text = "Minutes Before the Appointment Starts";
+ //
+ // numericUpDownReminderTime
+ //
+ this.numericUpDownReminderTime.Location = new System.Drawing.Point(162, 138);
+ this.numericUpDownReminderTime.Maximum = new decimal(new int[] {
+ 60,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownReminderTime.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownReminderTime.Name = "numericUpDownReminderTime";
+ this.numericUpDownReminderTime.Size = new System.Drawing.Size(63, 20);
+ this.numericUpDownReminderTime.TabIndex = 21;
+ this.numericUpDownReminderTime.Value = new decimal(new int[] {
+ 10,
+ 0,
+ 0,
+ 0});
+ this.numericUpDownReminderTime.ValueChanged += new System.EventHandler(this.numericUpDownReminderTime_ValueChanged);
+ //
+ // labelStartReminderTitle
+ //
+ this.labelStartReminderTitle.AutoSize = true;
+ this.labelStartReminderTitle.Location = new System.Drawing.Point(6, 142);
+ this.labelStartReminderTitle.Name = "labelStartReminderTitle";
+ this.labelStartReminderTitle.Size = new System.Drawing.Size(149, 13);
+ this.labelStartReminderTitle.TabIndex = 20;
+ this.labelStartReminderTitle.Text = "Show Appointment Reminders";
+ //
+ // MainWindow
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(584, 641);
+ this.Controls.Add(this.groupBoxClockSettings);
+ this.Controls.Add(this.groupBoxAppointmentSettings);
+ this.Controls.Add(this.groupBoxApplicationSettings);
+ this.Controls.Add(this.groupBoxState);
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MaximumSize = new System.Drawing.Size(800, 800);
+ this.MinimumSize = new System.Drawing.Size(600, 680);
+ this.Name = "MainWindow";
+ this.Text = "Meeting Clock";
+ this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainWindow_FormClosed);
+ this.Load += new System.EventHandler(this.MainWindow_Load);
+ this.Resize += new System.EventHandler(this.MainWindow_Resize);
+ this.groupBoxState.ResumeLayout(false);
+ this.groupBoxState.PerformLayout();
+ this.groupBoxApplicationSettings.ResumeLayout(false);
+ this.groupBoxApplicationSettings.PerformLayout();
+ this.groupBoxAppointmentSettings.ResumeLayout(false);
+ this.groupBoxAppointmentSettings.PerformLayout();
+ this.groupBoxClockSettings.ResumeLayout(false);
+ this.groupBoxClockSettings.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownScrollWait)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.trackBarScrollSpeed)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.trackBarBrightness)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownTemperatureInterval)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownDateInterval)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownTimeInterval)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDownReminderTime)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBoxState;
+ private System.Windows.Forms.Label labelBluetoothState;
+ private System.Windows.Forms.Label labelBluetoothStateTitle;
+ private System.Windows.Forms.Button buttonOpenSystemSettingsPrivacy;
+ private System.Windows.Forms.Button buttonEnableBluetooth;
+ private System.Windows.Forms.Label labelMeetingClockState;
+ private System.Windows.Forms.Label labelMeetingClockStateTitle;
+ private System.Windows.Forms.Button buttonOpenSystemSettingsBluetooth;
+ private System.Windows.Forms.Button buttonWebsite;
+ private System.Windows.Forms.GroupBox groupBoxApplicationSettings;
+ private System.Windows.Forms.CheckBox checkBoxEnableBluetooth;
+ private System.Windows.Forms.CheckBox checkBoxCheckForUpdates;
+ private System.Windows.Forms.CheckBox checkBoxStartMinimized;
+ private System.Windows.Forms.CheckBox checkBoxAutostart;
+ private System.Windows.Forms.NotifyIcon notifyIcon;
+ private System.Windows.Forms.Timer timerEnableBalloon;
+ private System.Windows.Forms.GroupBox groupBoxAppointmentSettings;
+ private System.Windows.Forms.CheckBox checkBoxIgnoreAllDayAppointments;
+ private System.Windows.Forms.CheckBox checkBoxIgnoreCancelledAppointments;
+ private System.Windows.Forms.CheckBox checkBoxIgnoreFreeAppointments;
+ private System.Windows.Forms.CheckBox checkBoxIgnoreOutOfOfficeAppointments;
+ private System.Windows.Forms.CheckBox checkBoxIgnoreTentativeAppointments;
+ private System.Windows.Forms.GroupBox groupBoxClockSettings;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.NumericUpDown numericUpDownScrollWait;
+ private System.Windows.Forms.Label labelScrollWaitTitle;
+ private System.Windows.Forms.Label labelScrollSpeed;
+ private System.Windows.Forms.Label labelScrollSpeedTitle;
+ private System.Windows.Forms.TrackBar trackBarScrollSpeed;
+ private System.Windows.Forms.Label labelBrightness;
+ private System.Windows.Forms.Label labelBrightnessTitle;
+ private System.Windows.Forms.TrackBar trackBarBrightness;
+ private System.Windows.Forms.Label labelTemperatureIntervalTitleSeconds;
+ private System.Windows.Forms.NumericUpDown numericUpDownTemperatureInterval;
+ private System.Windows.Forms.CheckBox checkBoxTemperatureEnabled;
+ private System.Windows.Forms.Label labelDateIntervalTitleSeconds;
+ private System.Windows.Forms.NumericUpDown numericUpDownDateInterval;
+ private System.Windows.Forms.Label labelTimeIntervalTitleSeconds;
+ private System.Windows.Forms.NumericUpDown numericUpDownTimeInterval;
+ private System.Windows.Forms.Label labelTimeIntervalTitle;
+ private System.Windows.Forms.CheckBox checkBoxDateEnabled;
+ private System.Windows.Forms.Timer timerScrollDemo;
+ private System.Windows.Forms.Button buttonResetDefault;
+ private System.Windows.Forms.Timer timerAdjustClock;
+ private System.Windows.Forms.Timer timerGetAppointment;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.NumericUpDown numericUpDownReminderTime;
+ private System.Windows.Forms.Label labelStartReminderTitle;
+ }
+}
\ No newline at end of file
diff --git a/MainWindow.cs b/MainWindow.cs
new file mode 100644
index 0000000..ea0c528
--- /dev/null
+++ b/MainWindow.cs
@@ -0,0 +1,563 @@
+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 readonly string LINK_URL_UPDATE = "https://zechert.net/meeting-clock/update.txt";
+
+ 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.checkBoxCheckForUpdates.Checked = this.settings.CheckForUpdates;
+ 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;
+ }
+
+ if (this.settings.CheckForUpdates)
+ {
+ this.CheckForUpdate();
+ }
+
+ 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 async void CheckForUpdate()
+ {
+ HttpResponseMessage response = await this.client.GetAsync(LINK_URL_UPDATE);
+ if (response.StatusCode == System.Net.HttpStatusCode.OK)
+ {
+ string responseBody = await response.Content.ReadAsStringAsync();
+ string[] versions = responseBody.Split('\n');
+ Debug.WriteLine(String.Format("Versions available:\n{0}", responseBody));
+
+ if (versions.Length >= 2)
+ {
+ string winVersion = versions[0].Trim();
+ this.clockVersion = versions[1].Trim();
+
+ if (winVersion != Properties.Settings.Default.Version)
+ {
+ DialogResult result = MessageBox.Show("A new version of this software is available.\n\n" +
+ "Do you want to open " + LINK_URL + " to download the new version now?", "New Version Available", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
+ if (result == DialogResult.Yes)
+ {
+ System.Diagnostics.Process.Start(LINK_URL);
+ }
+ }
+ }
+ } else
+ {
+ Debug.WriteLine(String.Format("Check for update failed: {0}", response.StatusCode));
+ }
+ }
+
+ 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 checkBoxCheckForUpdates_CheckedChanged(object sender, EventArgs e)
+ {
+ this.settings.CheckForUpdates = this.checkBoxCheckForUpdates.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;
+ }
+ }
+}
diff --git a/MainWindow.resx b/MainWindow.resx
new file mode 100644
index 0000000..37e890b
--- /dev/null
+++ b/MainWindow.resx
@@ -0,0 +1,372 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+
+ AAABAAIAQEAAAAEACAAoFgAAJgAAAEBAAgABAAEAMAQAAE4WAAAoAAAAQAAAAIAAAAABAAgAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAA/38AAP+ADQD/gyYA/4QqAP+HOAD/iDsA/4pAAP+KQgD/i0UA/4xHAP+P
+ TwD/kFEA/5FVAP+TWgD/lV8A/5djAP+YZQD/mWgA/51uAP+ecQD/n3MA/6F3AP+ieAD/onkA/6N6AP+l
+ fgD/pn8A/6aAAP+ngQD/p4IA/6yJAP+tiwD/ro0A/6+PAP+wkAD/sJEA/7GTAP+0lwD/tZgA/7WZAP+5
+ nwD/uqAA/7yjAP+8pAD/vqcA/7+nAP/BqgD/x7QA/8i2AP/JtgD/zbwA/829AP/OvgD/0MAA/9HCAP/S
+ wwD/0sQA/9PFAP/UxgD/1McA/9XIAP/YywD/2c4A/9vQAP/c0QD/3dIA/9/VAP/f1gD/4toA/+TcAP/l
+ 3QD/5+AA/+jiAP/p4gD/6eMA/+3oAP/u6QD/7+sA//HtAP/x7gD/8u8A//PvAP/08AD/9PEA//XyAP/1
+ 8wD/+PYA//n3AP/5+AD/+/oA//z7AP/9/AD//v0A//7+AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU0snAQAAAAAAAAAAHF1A
+ EgAAAAAAAAAAADpWMQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNeXk0eAAAAAAAA
+ ABxeXl1CCgAAAAAAAAA6Xl5XLwAAAAAAAAAPOU1ZXl5eXl5bVEMgAAAAAAAAAAAAAAAAAABTXl5eOgAA
+ AAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMAAAAAAAAhWV5eXl5eXl5eXl5eXjkAAAAAAAAAAAAAAAAAU15e
+ XjoAAAAAAAAAHF5eXl4cAAAAAAAAADpeXl5TAAAAAAALWF5eXl5eXl5eXl5eXl5eKAAAAAAAAAAAAAAA
+ AFNeXl46AAAAAAAAABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAAMF5eXl5eXl5eXl5eXl5eXksAAAAAAAAA
+ AAAAAABTXl5eOgAAAAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMAAAAAAEVeXl5dMycmJiYmLVNeXl5eCAAA
+ AAAAAAAAAAAAU15eXjoAAAAAAAAAHF5eXl4cAAAAAAAAADpeXl5TAAAAAABNXl5eRAAAAAAAAAApXl5e
+ XhMAAAAAAAAAAAAAAFNeXl46AAAAAAAAABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAAUl5eXjsAAAAAAAAA
+ HV5eXl4bAAAAAAAAAAAAAABTXl5eOgAAAAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMAAAAAAFNeXl46AAAA
+ AAAAABxeXl5eHAAAAAAAAAAAAAAAU15eXjoAAAAAAAAAHF5eXl4cAAAAAAAAADpeXl5TAAAAAABTXl5e
+ OgAAAAAAAAAOS15eXhwAAAAAAAAAAAAAAFNeXl46AAAAAAAAABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAA
+ U15eXjoAAAAAAAAAAAAiR14cAAAAAAAAAAAAAABTXl5eOgAAAAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMA
+ AAAAAFNeXl46AAAAAAAAAAAAAAAMAwAAAAAAAAAAAAAAU15eXjoAAAAAAAAAHF5eXl4cAAAAAAAAADpe
+ Xl5TAAAAAABTXl5eOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNeXl46AAAAAAAAABxeXl5eHAAAAAAA
+ AAA6Xl5eUwAAAAAAU15eXjoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTXl5eOgAAAAAAAAAcXl5eXhwA
+ AAAAAAAAOl5eXlMAAAAAAFNeXl46AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU15eXjoAAAAAAAAAHF5e
+ Xl4cAAAAAAAAADpeXl5TAAAAAABTXl5eOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNeXl46AAAAAAAA
+ ABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAAU15eXjoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTXl5eOgAA
+ AAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMAAAAAAFNeXl46AAAAAAAAABxdTT4uCAAAAAAAAAAAAAAAU15e
+ XjoAAAAAAAAAHF5eXl4cAAAAAAAAADpeXl5TAAAAAABTXl5eOgAAAAAAAAAcXl5eXhwAAAAAAAAAAAAA
+ AFNeXl46AAAAAAAAABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAAU15eXjoAAAAAAAAAHF5eXl4cAAAAAAAA
+ AAAAAABOXl5eQAAAAAAAAAAkXl5eXiQAAAAAAAAAQF5eXk4AAAAAAE9eXl4/AAAAAAAAAB5eXl5eFQAA
+ AAAAAAAAAAAASV5eXlgZAQAAAAAKRl5eXl5GCgAAAAABGVheXl5IAAAAAABKXl5eVxgBAAAAAAlBXl5e
+ Xg0AAAAAAAAAAAAAADheXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eNwAAAAAAOV5eXl5eXl5eXl5e
+ Xl5eXlUAAAAAAAAAAAAAAAAUXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXhMAAAAAABZeXl5eXl5e
+ Xl5eXl5eXl40AAAAAAAAAAAAAAAAADNeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXjIAAAAAAAAANV5e
+ Xl5eXl5eXl5eXl5MBAAAAAAAAAAAAAAAAAAAK1BeXl5eXl5eXl5cPTZaXl5eXl5eXl5eUCoAAAAAAAAA
+ AAAsUV5eXl5eXl5eXlk8BgAAAAAAAAAAAAAAAAAAAAAAEB8lJiYmJiQdBwAABRokJiYmJiUfEAAAAAAA
+ AAAAAAAAAAARHyUmJiYmIxcCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAACgAAABAAAAAgAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAA=
+
+
+
+ 123, 17
+
+
+ 280, 17
+
+
+ 423, 17
+
+
+ 568, 17
+
+
+
+ AAABAAIAQEAAAAEACAAoFgAAJgAAAEBAAgABAAEAMAQAAE4WAAAoAAAAQAAAAIAAAAABAAgAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAA/38AAP+ADQD/gyYA/4QqAP+HOAD/iDsA/4pAAP+KQgD/i0UA/4xHAP+P
+ TwD/kFEA/5FVAP+TWgD/lV8A/5djAP+YZQD/mWgA/51uAP+ecQD/n3MA/6F3AP+ieAD/onkA/6N6AP+l
+ fgD/pn8A/6aAAP+ngQD/p4IA/6yJAP+tiwD/ro0A/6+PAP+wkAD/sJEA/7GTAP+0lwD/tZgA/7WZAP+5
+ nwD/uqAA/7yjAP+8pAD/vqcA/7+nAP/BqgD/x7QA/8i2AP/JtgD/zbwA/829AP/OvgD/0MAA/9HCAP/S
+ wwD/0sQA/9PFAP/UxgD/1McA/9XIAP/YywD/2c4A/9vQAP/c0QD/3dIA/9/VAP/f1gD/4toA/+TcAP/l
+ 3QD/5+AA/+jiAP/p4gD/6eMA/+3oAP/u6QD/7+sA//HtAP/x7gD/8u8A//PvAP/08AD/9PEA//XyAP/1
+ 8wD/+PYA//n3AP/5+AD/+/oA//z7AP/9/AD//v0A//7+AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU0snAQAAAAAAAAAAHF1A
+ EgAAAAAAAAAAADpWMQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNeXk0eAAAAAAAA
+ ABxeXl1CCgAAAAAAAAA6Xl5XLwAAAAAAAAAPOU1ZXl5eXl5bVEMgAAAAAAAAAAAAAAAAAABTXl5eOgAA
+ AAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMAAAAAAAAhWV5eXl5eXl5eXl5eXjkAAAAAAAAAAAAAAAAAU15e
+ XjoAAAAAAAAAHF5eXl4cAAAAAAAAADpeXl5TAAAAAAALWF5eXl5eXl5eXl5eXl5eKAAAAAAAAAAAAAAA
+ AFNeXl46AAAAAAAAABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAAMF5eXl5eXl5eXl5eXl5eXksAAAAAAAAA
+ AAAAAABTXl5eOgAAAAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMAAAAAAEVeXl5dMycmJiYmLVNeXl5eCAAA
+ AAAAAAAAAAAAU15eXjoAAAAAAAAAHF5eXl4cAAAAAAAAADpeXl5TAAAAAABNXl5eRAAAAAAAAAApXl5e
+ XhMAAAAAAAAAAAAAAFNeXl46AAAAAAAAABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAAUl5eXjsAAAAAAAAA
+ HV5eXl4bAAAAAAAAAAAAAABTXl5eOgAAAAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMAAAAAAFNeXl46AAAA
+ AAAAABxeXl5eHAAAAAAAAAAAAAAAU15eXjoAAAAAAAAAHF5eXl4cAAAAAAAAADpeXl5TAAAAAABTXl5e
+ OgAAAAAAAAAOS15eXhwAAAAAAAAAAAAAAFNeXl46AAAAAAAAABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAA
+ U15eXjoAAAAAAAAAAAAiR14cAAAAAAAAAAAAAABTXl5eOgAAAAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMA
+ AAAAAFNeXl46AAAAAAAAAAAAAAAMAwAAAAAAAAAAAAAAU15eXjoAAAAAAAAAHF5eXl4cAAAAAAAAADpe
+ Xl5TAAAAAABTXl5eOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNeXl46AAAAAAAAABxeXl5eHAAAAAAA
+ AAA6Xl5eUwAAAAAAU15eXjoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTXl5eOgAAAAAAAAAcXl5eXhwA
+ AAAAAAAAOl5eXlMAAAAAAFNeXl46AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU15eXjoAAAAAAAAAHF5e
+ Xl4cAAAAAAAAADpeXl5TAAAAAABTXl5eOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNeXl46AAAAAAAA
+ ABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAAU15eXjoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTXl5eOgAA
+ AAAAAAAcXl5eXhwAAAAAAAAAOl5eXlMAAAAAAFNeXl46AAAAAAAAABxdTT4uCAAAAAAAAAAAAAAAU15e
+ XjoAAAAAAAAAHF5eXl4cAAAAAAAAADpeXl5TAAAAAABTXl5eOgAAAAAAAAAcXl5eXhwAAAAAAAAAAAAA
+ AFNeXl46AAAAAAAAABxeXl5eHAAAAAAAAAA6Xl5eUwAAAAAAU15eXjoAAAAAAAAAHF5eXl4cAAAAAAAA
+ AAAAAABOXl5eQAAAAAAAAAAkXl5eXiQAAAAAAAAAQF5eXk4AAAAAAE9eXl4/AAAAAAAAAB5eXl5eFQAA
+ AAAAAAAAAAAASV5eXlgZAQAAAAAKRl5eXl5GCgAAAAABGVheXl5IAAAAAABKXl5eVxgBAAAAAAlBXl5e
+ Xg0AAAAAAAAAAAAAADheXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eNwAAAAAAOV5eXl5eXl5eXl5e
+ Xl5eXlUAAAAAAAAAAAAAAAAUXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXhMAAAAAABZeXl5eXl5e
+ Xl5eXl5eXl40AAAAAAAAAAAAAAAAADNeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXjIAAAAAAAAANV5e
+ Xl5eXl5eXl5eXl5MBAAAAAAAAAAAAAAAAAAAK1BeXl5eXl5eXl5cPTZaXl5eXl5eXl5eUCoAAAAAAAAA
+ AAAsUV5eXl5eXl5eXlk8BgAAAAAAAAAAAAAAAAAAAAAAEB8lJiYmJiQdBwAABRokJiYmJiUfEAAAAAAA
+ AAAAAAAAAAARHyUmJiYmIxcCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAACgAAABAAAAAgAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAA=
+
+
+
\ No newline at end of file
diff --git a/Meeting-Clock.csproj b/Meeting-Clock.csproj
new file mode 100644
index 0000000..4aa8736
--- /dev/null
+++ b/Meeting-Clock.csproj
@@ -0,0 +1,163 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}
+ WinExe
+ MeetingClock
+ Meeting Clock
+ v4.7.2
+ 512
+ true
+ true
+
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ MeetingClock.MeetingClock
+
+
+
+
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ 7.3
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ 7.3
+ prompt
+ true
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE
+ full
+ x86
+ 7.3
+ prompt
+ true
+
+
+ bin\x86\Release\
+ TRACE
+ true
+ pdbonly
+ x86
+ 7.3
+ prompt
+ true
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ MainWindow.cs
+
+
+
+
+
+
+
+ MainWindow.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+ True
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+ 10.0.19041.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Meeting-Clock.sln b/Meeting-Clock.sln
new file mode 100644
index 0000000..c7a42df
--- /dev/null
+++ b/Meeting-Clock.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30717.126
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meeting-Clock", "Meeting-Clock.csproj", "{97CA08CF-C8F9-4D6C-8C15-77695A995169}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Debug|x64.ActiveCfg = Debug|x64
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Debug|x64.Build.0 = Debug|x64
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Debug|x86.ActiveCfg = Debug|x86
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Debug|x86.Build.0 = Debug|x86
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Release|Any CPU.Build.0 = Release|Any CPU
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Release|x64.ActiveCfg = Release|x64
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Release|x64.Build.0 = Release|x64
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Release|x86.ActiveCfg = Release|x86
+ {97CA08CF-C8F9-4D6C-8C15-77695A995169}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8BF71566-EA72-4AF7-B52D-0D54EE96FC46}
+ EndGlobalSection
+EndGlobal
diff --git a/MeetingClock.cs b/MeetingClock.cs
new file mode 100644
index 0000000..e824fc8
--- /dev/null
+++ b/MeetingClock.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Windows.Forms;
+
+namespace MeetingClock
+{
+ static class MeetingClock
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new MainWindow());
+ }
+ }
+}
diff --git a/MeetingClockManager.cs b/MeetingClockManager.cs
new file mode 100644
index 0000000..14d0956
--- /dev/null
+++ b/MeetingClockManager.cs
@@ -0,0 +1,479 @@
+using Microsoft.Win32;
+using System;
+using System.Diagnostics;
+using System.IO.Ports;
+using System.Text;
+using System.Timers;
+using System.Windows.Forms;
+
+namespace MeetingClock
+{
+ public class MeetingClockManager
+ {
+ private const string MTC = "MTC";
+
+ public enum MeetingClockState
+ {
+ NotInitialized,
+ NoComPort,
+ Disconnected,
+ Connected
+ }
+
+ public MeetingClockState State { get; private set; } = MeetingClockState.NotInitialized;
+ public string Version { get; private set; }
+ public string Port {
+ get
+ {
+ if (this.serialPort != null && this.serialPort.IsOpen)
+ {
+ return this.serialPort.PortName;
+ }
+ return "";
+ }
+ }
+
+ public delegate void MeetingClockStateChangeHandler(MeetingClockManager manager, MeetingClockState oldState, MeetingClockState newState);
+ public event MeetingClockStateChangeHandler StateChanged;
+
+ private System.Timers.Timer startTimer;
+ private System.Timers.Timer checkTimer;
+ private BluetoothManager bluetoothManager;
+ private SerialPort serialPort;
+
+ public MeetingClockManager(BluetoothManager bluetoothManager)
+ {
+ this.NewSerialPort();
+
+ this.startTimer = new System.Timers.Timer(1000);
+ this.startTimer.AutoReset = false;
+ this.startTimer.Elapsed += ConnectTimer_Elapsed;
+
+ this.checkTimer = new System.Timers.Timer(30000);
+ this.checkTimer.AutoReset = false;
+ this.checkTimer.Elapsed += CheckTimer_Elapsed;
+ this.checkTimer.Start();
+
+ this.bluetoothManager = bluetoothManager;
+ this.bluetoothManager.StateChanged += BluetoothManager_StateChanged;
+ }
+
+ private void NewSerialPort() {
+ lock (this) {
+ if (this.serialPort != null)
+ {
+ try
+ {
+ this.serialPort.Close();
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ }
+ this.serialPort = new SerialPort();
+ this.serialPort.BaudRate = 9600;
+ this.serialPort.Parity = Parity.None;
+ this.serialPort.DataBits = 8;
+ this.serialPort.StopBits = StopBits.One;
+ this.serialPort.Encoding = Encoding.GetEncoding("iso8859-1");
+ this.serialPort.ReadTimeout = 1000;
+ this.serialPort.WriteTimeout = 1000;
+ }
+ }
+
+ private void BluetoothManager_StateChanged(BluetoothManager manager, BluetoothManager.BluetoothState oldState, BluetoothManager.BluetoothState newState)
+ {
+ switch (newState)
+ {
+ case BluetoothManager.BluetoothState.On:
+ this.startTimer.Start();
+ break;
+ default:
+ this.Disconnect();
+ break;
+ }
+ }
+
+ private void ConnectTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ this.Connect();
+ }
+
+ private void Connect()
+ {
+ lock (this)
+ {
+ if (this.State == MeetingClockState.Connected && this.serialPort.IsOpen)
+ {
+ Debug.WriteLine("Meeting clock already connected. Not trying to connect again.");
+ return;
+ }
+
+ string[] portNames = SerialPort.GetPortNames();
+ if (portNames.Length == 0)
+ {
+ Debug.WriteLine("No COM ports are available at the moment.");
+ this.ChangeState(MeetingClockState.NoComPort);
+ return;
+ }
+
+ this.ChangeState(MeetingClockState.Disconnected);
+ this.NewSerialPort();
+
+ foreach (string portName in portNames)
+ {
+ Debug.WriteLine(String.Format("Trying to connect to {0}", portName));
+ try
+ {
+ this.serialPort.PortName = portName;
+ this.serialPort.Open();
+
+ if (this.Handshake())
+ {
+ Debug.WriteLine(String.Format("Successfully connected to meeting clock {0} on port {1}", this.Version, portName));
+ this.Adjust();
+ this.ScrollText("");
+ this.NextDate(DateTime.Now.AddMinutes(-5));
+ this.ChangeState(MeetingClockState.Connected);
+ return;
+ }
+ else
+ {
+ Debug.WriteLine(String.Format("Failed to connect to meeting clock on port {0}. Invalid Handshake.", portName));
+ }
+ }
+ catch (Exception exception)
+ {
+ Debug.WriteLine(String.Format("Failed to connect to meeting clock on port {0}. {1}", portName, exception.Message));
+ }
+
+ this.Disconnect();
+ }
+ }
+ }
+
+ private void Disconnect()
+ {
+ lock (this)
+ {
+ if (this.serialPort.IsOpen)
+ {
+ Debug.WriteLine(String.Format("Closing connection on port {0}", this.serialPort.PortName));
+ try
+ {
+ this.serialPort.Close();
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ }
+
+ this.ChangeState(MeetingClockState.Disconnected);
+ this.NewSerialPort();
+ }
+ }
+
+ private bool Handshake()
+ {
+ string rx = this.SendAndReceive(MTC);
+
+ if (rx == null)
+ {
+ return false;
+ }
+
+ if (rx.StartsWith(MTC))
+ {
+ this.Version = rx.Substring(MTC.Length).Trim();
+ return true;
+ }
+
+ return false;
+ }
+
+ public void Adjust()
+ {
+ this.SendAndReceive(String.Format("ADJ {0}", DateTime.Now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss")));
+ }
+
+ private string SendAndReceive(string tx)
+ {
+ lock (this)
+ {
+ try
+ {
+ if (this.serialPort.IsOpen)
+ {
+ Debug.WriteLine(String.Format(">>> {0}", tx));
+ this.serialPort.WriteLine(tx);
+ string rx = this.serialPort.ReadLine().Trim();
+ Debug.WriteLine(String.Format("<<< {0}", rx));
+ return rx;
+ }
+ }
+ catch (Exception exception)
+ {
+ Debug.WriteLine(String.Format("Failed to send/receiv on port {0}. {1}", this.serialPort.PortName, exception.Message));
+ this.Disconnect();
+ }
+
+ return null;
+ }
+ }
+
+ private void ChangeState(MeetingClockState newState)
+ {
+ MeetingClockState oldState = this.State;
+ this.State = newState;
+
+ if (newState != oldState)
+ {
+ Debug.WriteLine("Meeting Clock state change detected. Old state: {0}, new state {1}.", oldState, newState);
+
+ if (this.StateChanged != null)
+ {
+ this.StateChanged(this, oldState, newState);
+ }
+ }
+ }
+
+ private void CheckTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ if (this.serialPort.IsOpen)
+ {
+ if (!this.Handshake())
+ {
+ this.Disconnect();
+ }
+ }
+ else if (this.bluetoothManager.State == BluetoothManager.BluetoothState.On)
+ {
+ this.Connect();
+ }
+
+ this.checkTimer.Start();
+ }
+
+ public void Stop()
+ {
+ this.Disconnect();
+ this.checkTimer.Stop();
+ this.startTimer.Stop();
+ }
+
+ public int? GetTimeInterval()
+ {
+ try
+ {
+ string rx = this.SendAndReceive("GET TI").Substring(7);
+ return int.Parse(rx);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ public void SetTimeInterval(int value)
+ {
+ try
+ {
+ this.SendAndReceive("SET TI " + value);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public int? GetDateInterval()
+ {
+ try
+ {
+ string rx = this.SendAndReceive("GET DI").Substring(7);
+ return int.Parse(rx);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ public void SetDateInterval(int value)
+ {
+ try
+ {
+ this.SendAndReceive("SET DI " + value);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public int? GetTemperatureInterval()
+ {
+ try
+ {
+ string rx = this.SendAndReceive("GET CI").Substring(7);
+ return int.Parse(rx);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+ public void SetTemperatureInterval(int value)
+ {
+ try
+ {
+ this.SendAndReceive("SET CI " + value);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public int? GetBrightness()
+ {
+ try
+ {
+ string rx = this.SendAndReceive("GET IN").Substring(7);
+ return int.Parse(rx);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ public int? GetScrollSpeed()
+ {
+ try
+ {
+ string rx = this.SendAndReceive("GET SS").Substring(7);
+ return int.Parse(rx);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ public int? GetScrollWait()
+ {
+ try
+ {
+ string rx = this.SendAndReceive("GET SW").Substring(7);
+ return int.Parse(rx);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ public void SetBrightness(int value)
+ {
+ try
+ {
+ this.SendAndReceive("SET IN " + value);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public void SetScrollSpeed(int value)
+ {
+ try
+ {
+ this.SendAndReceive("SET SS " + value);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public void SetScrollWait(int value)
+ {
+ try
+ {
+ this.SendAndReceive("SET SW " + value);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public void ScrollText(string value)
+ {
+ try
+ {
+ this.SendAndReceive("SCR " + value);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public bool? GetDateEnabled()
+ {
+ try
+ {
+ string rx = this.SendAndReceive("GET DE").Substring(7);
+ return int.Parse(rx) > 0;
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ public void SetDateEnabled(bool value)
+ {
+ try
+ {
+ this.SendAndReceive("SET DE " + (value ? "1" : "0"));
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public bool? GetTemperatureEnabled()
+ {
+ try
+ {
+ string rx = this.SendAndReceive("GET CE").Substring(7);
+ return int.Parse(rx) > 0;
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ public void SetTemperatureEnabled(bool value)
+ {
+ try
+ {
+ this.SendAndReceive("SET CE " + (value ? "1" : "0"));
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ internal void NextDate(DateTime value)
+ {
+ try
+ {
+ this.SendAndReceive("NXT " + value.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss"));
+ }
+ catch (Exception)
+ {
+ }
+ }
+ }
+}
diff --git a/OutlookManager.cs b/OutlookManager.cs
new file mode 100644
index 0000000..09b6886
--- /dev/null
+++ b/OutlookManager.cs
@@ -0,0 +1,181 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Outlook = Microsoft.Office.Interop.Outlook;
+
+namespace MeetingClock
+{
+ public class OutlookManager
+ {
+ private Outlook.Application application;
+
+ public OutlookManager()
+ {
+ }
+
+ public async Task GetNextAppointment(
+ bool ignoreAllDayEvents, bool ignoreCancelledMeetings, bool ignoreFreeMeetings, bool ignoreOutOfOfficeMeetings, bool ignoreTentativeMeetings)
+ {
+ await Task.Run(() =>
+ {
+ lock(this)
+ {
+ int retries = 5;
+ while (this.application == null && retries-- > 0)
+ {
+ try
+ {
+ this.application = new Outlook.Application();
+ }
+ catch (Exception exception)
+ {
+ this.application = null;
+ Debug.WriteLine(String.Format("Failed to start outlook application: {0}", exception.Message));
+ Thread.Sleep(3000);
+ }
+ }
+ }
+ });
+
+ List appointmentItems = new List();
+
+ lock (this)
+ {
+ if (this.application == null)
+ {
+ return null; // not available at the moment
+ }
+ try
+ {
+ Outlook.Folder calendarFolder = this.application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
+ DateTime start = DateTime.Now;
+ DateTime end = start.AddHours(2);
+
+ string filter = String.Format("[Start] >= '{0}' AND [Start] <= '{1}'", start.ToString("g"), end.ToString("g"));
+ Debug.WriteLine(String.Format("Filtering Outlook Events: {0}", filter));
+
+ Outlook.Items appointments = calendarFolder.Items;
+ appointments.IncludeRecurrences = true;
+ appointments.Sort("[Start]", Type.Missing);
+ Outlook.Items filteredAppointments = appointments.Restrict(filter);
+
+ Debug.WriteLine(String.Format("Found {0} outlook appointments between {1} and {2}", filteredAppointments.Count, start.ToString("g"), end.ToString("g")));
+
+ DateTime? firstAppointmentTime = null;
+
+ foreach (Outlook.AppointmentItem appointment in filteredAppointments)
+ {
+ Debug.WriteLine(String.Format("{0}-{5} ({6}): {1} ({2}), allday: {3}, busy: {4}, importance: {7}, recurring: {8}, scheduled: {9}, conflict: {10}",
+ appointment.Start.ToString("g"), appointment.Subject, appointment.MeetingStatus, appointment.AllDayEvent, appointment.BusyStatus, appointment.End.ToString("g"),
+ appointment.Duration, appointment.Importance, appointment.RecurrenceState, appointment.CreationTime.ToString("g"), appointment.IsConflict));
+
+ if (ignoreAllDayEvents && appointment.AllDayEvent)
+ {
+ continue; // ignore all day events
+ }
+ if (ignoreCancelledMeetings
+ && (appointment.MeetingStatus == Outlook.OlMeetingStatus.olMeetingCanceled || appointment.MeetingStatus == Outlook.OlMeetingStatus.olMeetingReceivedAndCanceled))
+ {
+ continue; // ignore cancelled meetings
+ }
+
+ if (ignoreFreeMeetings && appointment.BusyStatus == Outlook.OlBusyStatus.olFree)
+ {
+ continue; // ignore free meetings
+ }
+
+ if (ignoreOutOfOfficeMeetings && appointment.BusyStatus == Outlook.OlBusyStatus.olOutOfOffice)
+ {
+ continue; // ignore out of office meetings
+ }
+
+ if (ignoreTentativeMeetings && appointment.BusyStatus == Outlook.OlBusyStatus.olTentative)
+ {
+ continue; // ignore tentative meetings
+ }
+
+ if (firstAppointmentTime == null)
+ {
+ firstAppointmentTime = appointment.Start;
+ }
+
+ // ignore appointments that do not start first
+ if (firstAppointmentTime < appointment.Start)
+ {
+ continue; // ignore later appointments
+ }
+
+ appointmentItems.Add(appointment);
+ Debug.WriteLine(String.Format("Next possible appointment is {0}-{1}: {2}", appointment.Start.ToString("t"), appointment.End.ToString("t"), appointment.Subject));
+ }
+
+ }
+ catch (Exception exception)
+ {
+ Debug.WriteLine(String.Format("Exception getting outlook appointments: {0}", exception.Message));
+ this.application = null;
+ }
+ }
+
+ if (appointmentItems.Count == 0)
+ {
+ return null; // no appointments upcoming
+ }
+
+ if (appointmentItems.Count == 1)
+ {
+ return appointmentItems[0]; // exactly one appointment upcoming
+ }
+
+ // remove cancelled events
+ appointmentItems = appointmentItems.AsQueryable()
+ .Where(item => item.MeetingStatus != Outlook.OlMeetingStatus.olMeetingCanceled && item.MeetingStatus != Outlook.OlMeetingStatus.olMeetingReceivedAndCanceled).ToList();
+ if (appointmentItems.Count == 1)
+ {
+ return appointmentItems[0]; // one appointment still left
+ }
+
+ // remove duplicates by priority, select highest priority
+ Outlook.OlImportance importance = appointmentItems.AsQueryable().OrderByDescending(item => (int)item.Importance).Select(item => item.Importance).First();
+ appointmentItems = appointmentItems.AsQueryable().Where(item => item.Importance == importance).ToList();
+ if (appointmentItems.Count == 1)
+ {
+ return appointmentItems[0]; // one appointment still left
+ }
+
+ // remove all day events
+ appointmentItems = appointmentItems.AsQueryable().Where(item => !item.AllDayEvent).ToList();
+ if (appointmentItems.Count == 1)
+ {
+ return appointmentItems[0]; // one appointment still left
+ }
+
+ // remove free appointment
+ appointmentItems = appointmentItems.AsQueryable().Where(item => item.BusyStatus != Outlook.OlBusyStatus.olFree).ToList();
+ if (appointmentItems.Count == 1)
+ {
+ return appointmentItems[0]; // one appointment still left
+ }
+
+ // remove tentative appointment
+ appointmentItems = appointmentItems.AsQueryable().Where(item => item.BusyStatus != Outlook.OlBusyStatus.olTentative).ToList();
+ if (appointmentItems.Count == 1)
+ {
+ return appointmentItems[0]; // one appointment still left
+ }
+
+ // remove out of office appointment
+ appointmentItems = appointmentItems.AsQueryable().Where(item => item.BusyStatus != Outlook.OlBusyStatus.olOutOfOffice).ToList();
+ if (appointmentItems.Count == 1)
+ {
+ return appointmentItems[0]; // one appointment still left
+ }
+
+ return appointmentItems[0];
+ }
+ }
+}
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..fbd51d2
--- /dev/null
+++ b/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+using System.Resources;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Meeting-Clock")]
+[assembly: AssemblyDescription("Meeting Clock")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Frank Zechert")]
+[assembly: AssemblyProduct("Meeting-Clock")]
+[assembly: AssemblyCopyright("Copyright © 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("97ca08cf-c8f9-4d6c-8c15-77695a995169")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: NeutralResourcesLanguage("en")]
diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..9d34586
--- /dev/null
+++ b/Properties/Resources.Designer.cs
@@ -0,0 +1,113 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace MeetingClock.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MeetingClock.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ internal static System.Drawing.Icon icon_error {
+ get {
+ object obj = ResourceManager.GetObject("icon_error", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ internal static System.Drawing.Icon icon_neutral {
+ get {
+ object obj = ResourceManager.GetObject("icon_neutral", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ internal static System.Drawing.Icon icon_off {
+ get {
+ object obj = ResourceManager.GetObject("icon_off", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ internal static System.Drawing.Icon icon_ok {
+ get {
+ object obj = ResourceManager.GetObject("icon_ok", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ internal static System.Drawing.Icon icon_warning {
+ get {
+ object obj = ResourceManager.GetObject("icon_warning", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+ }
+}
diff --git a/Properties/Resources.resx b/Properties/Resources.resx
new file mode 100644
index 0000000..a1c5f61
--- /dev/null
+++ b/Properties/Resources.resx
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\icons\icon-error.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\icons\icon-neutral.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\icons\icon-off.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\icons\icon-ok.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\icons\icon-warning.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..cf6eef9
--- /dev/null
+++ b/Properties/Settings.Designer.cs
@@ -0,0 +1,143 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace MeetingClock.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("v. 1.0.0")]
+ public string Version {
+ get {
+ return ((string)(this["Version"]));
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool CheckForUpdates {
+ get {
+ return ((bool)(this["CheckForUpdates"]));
+ }
+ set {
+ this["CheckForUpdates"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool StartMinimized {
+ get {
+ return ((bool)(this["StartMinimized"]));
+ }
+ set {
+ this["StartMinimized"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool StartBluetooth {
+ get {
+ return ((bool)(this["StartBluetooth"]));
+ }
+ set {
+ this["StartBluetooth"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool IgnoreAllDayAppointments {
+ get {
+ return ((bool)(this["IgnoreAllDayAppointments"]));
+ }
+ set {
+ this["IgnoreAllDayAppointments"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool IgnoreCancelledAppointments {
+ get {
+ return ((bool)(this["IgnoreCancelledAppointments"]));
+ }
+ set {
+ this["IgnoreCancelledAppointments"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool IgnoreFreeAppointments {
+ get {
+ return ((bool)(this["IgnoreFreeAppointments"]));
+ }
+ set {
+ this["IgnoreFreeAppointments"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool IgnoreOutOfOfficeAppointments {
+ get {
+ return ((bool)(this["IgnoreOutOfOfficeAppointments"]));
+ }
+ set {
+ this["IgnoreOutOfOfficeAppointments"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool IgnoreTentativeAppointments {
+ get {
+ return ((bool)(this["IgnoreTentativeAppointments"]));
+ }
+ set {
+ this["IgnoreTentativeAppointments"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("10")]
+ public int ReminderTime {
+ get {
+ return ((int)(this["ReminderTime"]));
+ }
+ set {
+ this["ReminderTime"] = value;
+ }
+ }
+ }
+}
diff --git a/Properties/Settings.settings b/Properties/Settings.settings
new file mode 100644
index 0000000..46d7fbd
--- /dev/null
+++ b/Properties/Settings.settings
@@ -0,0 +1,36 @@
+
+
+
+
+
+ v. 1.0.0
+
+
+ True
+
+
+ False
+
+
+ False
+
+
+ True
+
+
+ True
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ 10
+
+
+
\ No newline at end of file
diff --git a/Settings.cs b/Settings.cs
new file mode 100644
index 0000000..5f4b574
--- /dev/null
+++ b/Settings.cs
@@ -0,0 +1,164 @@
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace MeetingClock
+{
+ public class Settings
+ {
+
+ private readonly string AUTOSTART_REGKEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
+ private readonly string AUTOSTART_VALUE = "Meeting-Clock";
+
+ public bool Autostart
+ {
+ get
+ {
+ using (RegistryKey key = Registry.CurrentUser.OpenSubKey(AUTOSTART_REGKEY, false))
+ {
+ return (string) key.GetValue(AUTOSTART_VALUE) == "\"" + Application.ExecutablePath + "\"";
+ }
+ }
+
+ set
+ {
+ using (RegistryKey key = Registry.CurrentUser.OpenSubKey(AUTOSTART_REGKEY, true))
+ {
+ if (value)
+ {
+ key.SetValue(AUTOSTART_VALUE, "\"" + Application.ExecutablePath + "\"");
+ }
+ else
+ {
+ key.DeleteValue(AUTOSTART_VALUE, false);
+ }
+ }
+ }
+ }
+
+ public bool StartMinimized
+ {
+ get
+ {
+ return Properties.Settings.Default.StartMinimized;
+ }
+ set
+ {
+ Properties.Settings.Default.StartMinimized = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ public bool CheckForUpdates
+ {
+ get
+ {
+ return Properties.Settings.Default.CheckForUpdates;
+ }
+ set
+ {
+ Properties.Settings.Default.CheckForUpdates = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ public bool StartBluetooth
+ {
+ get
+ {
+ return Properties.Settings.Default.StartBluetooth;
+ }
+ set
+ {
+ Properties.Settings.Default.StartBluetooth = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ public bool IgnoreAllDayAppointments
+ {
+ get
+ {
+ return Properties.Settings.Default.IgnoreAllDayAppointments;
+ }
+ set
+ {
+ Properties.Settings.Default.IgnoreAllDayAppointments = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ public bool IgnoreCancelledAppointments
+ {
+ get
+ {
+ return Properties.Settings.Default.IgnoreCancelledAppointments;
+ }
+ set
+ {
+ Properties.Settings.Default.IgnoreCancelledAppointments = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ public bool IgnoreFreeAppointments
+ {
+ get
+ {
+ return Properties.Settings.Default.IgnoreFreeAppointments;
+ }
+ set
+ {
+ Properties.Settings.Default.IgnoreFreeAppointments = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ public bool IgnoreOutOfOfficeAppointments
+ {
+ get
+ {
+ return Properties.Settings.Default.IgnoreOutOfOfficeAppointments;
+ }
+ set
+ {
+ Properties.Settings.Default.IgnoreOutOfOfficeAppointments = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ public bool IgnoreTentativeAppointments
+ {
+ get
+ {
+ return Properties.Settings.Default.IgnoreTentativeAppointments;
+ }
+ set
+ {
+ Properties.Settings.Default.IgnoreTentativeAppointments = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ public int ReminderTime
+ {
+ get
+ {
+ return Properties.Settings.Default.ReminderTime;
+ }
+ set
+ {
+ Properties.Settings.Default.ReminderTime = value;
+ Properties.Settings.Default.Save();
+ }
+ }
+
+
+ }
+}
+
diff --git a/icons/icon-error.ico b/icons/icon-error.ico
new file mode 100644
index 0000000..0dd53ea
Binary files /dev/null and b/icons/icon-error.ico differ
diff --git a/icons/icon-error.xcf b/icons/icon-error.xcf
new file mode 100644
index 0000000..a6dfabd
Binary files /dev/null and b/icons/icon-error.xcf differ
diff --git a/icons/icon-neutral.ico b/icons/icon-neutral.ico
new file mode 100644
index 0000000..e8d2ff2
Binary files /dev/null and b/icons/icon-neutral.ico differ
diff --git a/icons/icon-neutral.xcf b/icons/icon-neutral.xcf
new file mode 100644
index 0000000..f548d13
Binary files /dev/null and b/icons/icon-neutral.xcf differ
diff --git a/icons/icon-off.ico b/icons/icon-off.ico
new file mode 100644
index 0000000..3a43957
Binary files /dev/null and b/icons/icon-off.ico differ
diff --git a/icons/icon-off.xcf b/icons/icon-off.xcf
new file mode 100644
index 0000000..08f9e88
Binary files /dev/null and b/icons/icon-off.xcf differ
diff --git a/icons/icon-ok.ico b/icons/icon-ok.ico
new file mode 100644
index 0000000..43b0004
Binary files /dev/null and b/icons/icon-ok.ico differ
diff --git a/icons/icon-ok.xcf b/icons/icon-ok.xcf
new file mode 100644
index 0000000..6e6f909
Binary files /dev/null and b/icons/icon-ok.xcf differ
diff --git a/icons/icon-warning.ico b/icons/icon-warning.ico
new file mode 100644
index 0000000..c37ee0c
Binary files /dev/null and b/icons/icon-warning.ico differ
diff --git a/icons/icon-warning.xcf b/icons/icon-warning.xcf
new file mode 100644
index 0000000..1d15602
Binary files /dev/null and b/icons/icon-warning.xcf differ