using System; using System.ComponentModel; using System.Drawing; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; using InTheHand.Net.Bluetooth; using InTheHand.Net.Sockets; using Serilog; using Zzz.Clients; using Zzz.Properties; using Zzz.Utilities; namespace Zzz { public partial class SettingsForm : Form { #region Private Delegates, Events, Enums, Properties, Indexers and Fields private BindingSource _bluetoothWatchListBindingSource; private readonly MqttClient _mqttClient; private readonly Configuration.Configuration _configuration; private BindingSource _windowsWatchListBindingSource; private BluetoothClient _bluetoothClient; private BluetoothComponent _bluetoothComponent; private ScheduledContinuation MqttRestartContinuation; private CancellationTokenSource CancellationTokenSource; private CancellationToken CancellationToken; #endregion #region Constructors, Destructors and Finalizers public SettingsForm() { InitializeComponent(); CancellationTokenSource = new CancellationTokenSource(); CancellationToken = CancellationTokenSource.Token; MqttRestartContinuation = new ScheduledContinuation(); try { _bluetoothClient = new BluetoothClient(); _bluetoothComponent = new BluetoothComponent(_bluetoothClient); _bluetoothComponent.DiscoverDevicesProgress += LocalComponent_DiscoverDevicesProgress; _bluetoothComponent.DiscoverDevicesComplete += LocalComponent_DiscoverDevicesComplete; } catch(Exception ex) { Log.Warning(ex, $"Bluetooth stack is not supported"); } } public SettingsForm(MqttClient mqttClient, Configuration.Configuration configuration) : this() { _mqttClient = mqttClient; _configuration = configuration; } /// /// 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(); } if (_bluetoothComponent != null) { _bluetoothComponent.DiscoverDevicesProgress -= LocalComponent_DiscoverDevicesProgress; _bluetoothComponent.DiscoverDevicesComplete -= LocalComponent_DiscoverDevicesComplete; } _mqttClient.MqttConnectionFailed -= MqttClient_MqttConnectionFailed; _mqttClient.MqttConnectionSucceeded -= MqttClient_MqttConnectionSucceeded; _mqttClient.MqttDisconnected -= MqttClient_MqttDisconnected; _mqttClient.MqttSubscribeFailed -= MqttClient_MqttSubscribeFailed; _mqttClient.MqttSubscribeSucceeded -= MqttClient_MqttSubscribeSucceeded; _bluetoothComponent?.Dispose(); _bluetoothComponent = null; _bluetoothClient?.Dispose(); _bluetoothClient = null; base.Dispose(disposing); } #endregion #region Event Handlers private void MqttSettings_Changed(object sender, EventArgs e) { MqttRestartContinuation.Schedule(TimeSpan.FromSeconds(1), async () => { switch (_configuration.MqttEnable) { case false: await _mqttClient.Stop(); break; default: await _mqttClient.Restart(); break; } }, CancellationToken); } private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e) { CancellationTokenSource.Cancel(); } private void SettingsForm_Load(object sender, EventArgs e) { Utilities.WindowState.FormTracker.Track(this); pictureBox1.BackColor = _mqttClient.Connected ? Color.Green : Color.Red; pictureBox2.BackColor = _mqttClient.Subscribed ? Color.Green : Color.Red; _mqttClient.MqttConnectionFailed += MqttClient_MqttConnectionFailed; _mqttClient.MqttConnectionSucceeded += MqttClient_MqttConnectionSucceeded; _mqttClient.MqttDisconnected += MqttClient_MqttDisconnected; _mqttClient.MqttSubscribeFailed += MqttClient_MqttSubscribeFailed; _mqttClient.MqttSubscribeSucceeded += MqttClient_MqttSubscribeSucceeded; // Bind the bluetooth watch list binding source. _bluetoothWatchListBindingSource = new BindingSource(_configuration.BluetoothWatchList, ""); ; listBox1.DataSource = _bluetoothWatchListBindingSource; // Bind the windows watch list binding source. _windowsWatchListBindingSource = new BindingSource(_configuration.WindowsWatchList, ""); listBox2.DataSource = _windowsWatchListBindingSource; // Bind the rest of the settings. checkBox1.DataBindings.Add(nameof(checkBox1.Checked), _configuration, nameof(_configuration.LaunchOnBoot), true, DataSourceUpdateMode.OnPropertyChanged); trackBar2.DataBindings.Add(nameof(trackBar2.Value), _configuration, nameof(_configuration.Timeout), true, DataSourceUpdateMode.OnPropertyChanged); numericUpDown3.DataBindings.Add(nameof(numericUpDown3.Value), _configuration, nameof(_configuration.Timeout), true, DataSourceUpdateMode.OnPropertyChanged); numericUpDown5.DataBindings.Add(nameof(numericUpDown5.Value), _configuration, nameof(_configuration.HibernateTimeout), true, DataSourceUpdateMode.OnPropertyChanged); comboBox3.DataBindings.Add(nameof(comboBox3.Text), _configuration, nameof(_configuration.Action), true, DataSourceUpdateMode.OnPropertyChanged); comboBox1.DataBindings.Add(nameof(comboBox1.Text), _configuration, nameof(_configuration.ActionClick), true, DataSourceUpdateMode.OnPropertyChanged); comboBox2.DataBindings.Add(nameof(comboBox2.Text), _configuration, nameof(_configuration.ActionDoubleClick), true, DataSourceUpdateMode.OnPropertyChanged); trackBar4.DataBindings.Add(nameof(trackBar4.Value), _configuration, nameof(_configuration.ClickActionDelay), true, DataSourceUpdateMode.OnPropertyChanged); checkBox2.DataBindings.Add(nameof(checkBox2.Checked), _configuration, nameof(_configuration.MonitorMouse), true, DataSourceUpdateMode.OnPropertyChanged); checkBox3.DataBindings.Add(nameof(checkBox3.Checked), _configuration, nameof(_configuration.MonitorKeyboard), true, DataSourceUpdateMode.OnPropertyChanged); checkBox5.DataBindings.Add(nameof(checkBox5.Checked), _configuration, nameof(_configuration.MonitorBluetooth), true, DataSourceUpdateMode.OnPropertyChanged); checkBox6.DataBindings.Add(nameof(checkBox6.Checked), _configuration, nameof(_configuration.MonitorWindows), true, DataSourceUpdateMode.OnPropertyChanged); trackBar1.DataBindings.Add(nameof(trackBar1.Value), _configuration, nameof(_configuration.MouseMoveTolerance), true, DataSourceUpdateMode.OnPropertyChanged); numericUpDown1.DataBindings.Add(nameof(numericUpDown1.Value), _configuration, nameof(_configuration.MouseMoveTolerance), true, DataSourceUpdateMode.OnPropertyChanged); trackBar3.DataBindings.Add(nameof(trackBar3.Value), _configuration, nameof(_configuration.BluetoothScanInterval), true, DataSourceUpdateMode.OnPropertyChanged); numericUpDown4.DataBindings.Add(nameof(numericUpDown4.Value), _configuration, nameof(_configuration.BluetoothScanInterval), true, DataSourceUpdateMode.OnPropertyChanged); checkBox4.DataBindings.Add(nameof(checkBox4.Checked), _configuration, nameof(_configuration.MqttEnable), true, DataSourceUpdateMode.OnPropertyChanged); textBox1.DataBindings.Add(nameof(textBox1.Text), _configuration, nameof(_configuration.MqttServer), true, DataSourceUpdateMode.OnPropertyChanged); numericUpDown2.DataBindings.Add(nameof(numericUpDown2.Value), _configuration, nameof(_configuration.MqttPort), true, DataSourceUpdateMode.OnPropertyChanged); textBox2.DataBindings.Add(nameof(textBox2.Text), _configuration, nameof(_configuration.MqttUsername), true, DataSourceUpdateMode.OnPropertyChanged); textBox3.DataBindings.Add(nameof(textBox3.Text), _configuration, nameof(_configuration.MqttPassword), true, DataSourceUpdateMode.OnPropertyChanged); textBox4.DataBindings.Add(nameof(textBox4.Text), _configuration, nameof(_configuration.MqttTopic), true, DataSourceUpdateMode.OnPropertyChanged); } private void MqttClient_MqttSubscribeSucceeded(object sender, MQTTnet.Client.MqttClientSubscribeResultCode e) { pictureBox2.BackColor = Color.Green; } private void MqttClient_MqttSubscribeFailed(object sender, MQTTnet.Client.MqttClientSubscribeResultCode e) { pictureBox2.BackColor = Color.Red; } private void MqttClient_MqttDisconnected(object sender, EventArgs e) { pictureBox1.BackColor = Color.Red; pictureBox2.BackColor = Color.Red; } private void MqttClient_MqttConnectionSucceeded(object sender, EventArgs e) { pictureBox1.BackColor = Color.Green; } private void MqttClient_MqttConnectionFailed(object sender, EventArgs e) { pictureBox1.BackColor = Color.Red; pictureBox2.BackColor = Color.Red; } private void Button2_Click(object sender, EventArgs e) { foreach (var item in listBox1.SelectedItems) { _configuration.BluetoothWatchList.Remove((string) item); } _bluetoothWatchListBindingSource.ResetBindings(true); } private void Button1_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(textBox5.Text)) { return; } if (_configuration.BluetoothWatchList.Contains(textBox5.Text)) { return; } _configuration.BluetoothWatchList.Add(textBox5.Text); _bluetoothWatchListBindingSource.ResetBindings(true); } private void Button3_Click(object sender, EventArgs e) { if (!BluetoothRadio.IsSupported) { Log.Information("Bluetooth radio is not supported."); return; } _bluetoothComponent.DiscoverDevicesAsync(255, true, true, true, true, null); Log.Information("Bluetooth scan started."); } private void LocalComponent_DiscoverDevicesComplete(object sender, DiscoverDevicesEventArgs e) { Log.Information("Bluetooth scan finished."); _bluetoothWatchListBindingSource.ResetBindings(true); } private void LocalComponent_DiscoverDevicesProgress(object sender, DiscoverDevicesEventArgs e) { foreach (var deviceInfo in e.Devices) { if (!_configuration.BluetoothWatchList.Contains(deviceInfo.DeviceName)) { _configuration.BluetoothWatchList.Add(deviceInfo.DeviceName); _bluetoothWatchListBindingSource.ResetBindings(true); } } } private void Button5_Click(object sender, EventArgs e) { foreach (var item in listBox2.SelectedItems) { _configuration.WindowsWatchList.Remove((string) item); } _windowsWatchListBindingSource.ResetBindings(true); } private void Button4_Click(object sender, EventArgs e) { foreach (var item in listBox3.SelectedItems) { if (_configuration.WindowsWatchList.Contains((string) item)) { continue; } _configuration.WindowsWatchList.Add((string) item); } _windowsWatchListBindingSource.ResetBindings(true); } private void Button6_Click(object sender, EventArgs e) { listBox3.Items.Clear(); foreach (var handle in Helpers.FindWindows((wnd, param) => true)) { var title = Helpers.GetWindowTitle(handle); if (string.IsNullOrEmpty(title)) { continue; } listBox3.Items.Add(title); } } private void SettingsForm_ResizeBegin(object sender, EventArgs e) { SuspendLayout(); } private void SettingsForm_ResizeEnd(object sender, EventArgs e) { ResumeLayout(true); } #endregion } }