Zzz – Rev 5

Subversion Repositories:
Rev:
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;
        }

        /// <summary>
        ///     Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        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
    }
}

Generated by GNU Enscript 1.6.5.90.