Mercurial > servermonitor
diff ServerMonitor/Forms/ServerForm.cs @ 0:3e1a2131f897
Initial commit. Ping check, scheduling, UI working. SSH check mostly working.
author | Brad Greco <brad@bgreco.net> |
---|---|
date | Mon, 31 Dec 2018 18:32:14 -0500 |
parents | |
children | 3142e52cbe69 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ServerMonitor/Forms/ServerForm.cs Mon Dec 31 18:32:14 2018 -0500 @@ -0,0 +1,362 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ServerMonitorApp +{ + public partial class ServerForm : Form + { + private bool isNewServer; + private bool changedPassword; + private DateTime lastSaveTime; + private ServerMonitor monitor; + private BindingList<CheckResult> logResults, logResultsFiltered; + private CheckStatus[] filteredStatuses; + private readonly Dictionary<int, CheckForm> checkForms = new Dictionary<int, CheckForm>(); + private readonly Dictionary<CheckBox, CheckStatus> filterChecks; + + public Server Server { get; private set; } + + private IEnumerable<Check> SelectedChecks { get { return CheckGrid.SelectedRows.Cast<DataGridViewRow>().Select(r => r.DataBoundItem).Cast<Check>(); } } + + private Check SelectedCheck { get { return SelectedChecks.FirstOrDefault(); } } + + public ServerForm(ServerMonitor monitor, Server server, bool isNewServer = false) + { + InitializeComponent(); + this.monitor = monitor; + this.isNewServer = isNewServer; + Server = server; + filterChecks = new Dictionary<CheckBox, CheckStatus> + { + { LogSuccessCheckBox, CheckStatus.Success }, + { LogInformationCheckBox, CheckStatus.Information }, + { LogWarningCheckBox, CheckStatus.Warning }, + { LogErrorCheckBox, CheckStatus.Error }, + }; + } + + private void ServerForm_Load(object sender, EventArgs e) + { + CheckBindingSource.DataSource = Server.Checks; + monitor.CheckStatusChanged += Monitor_CheckStatusChanged; + CheckGrid.ClearSelection(); + if (isNewServer) + { + LoginComboBox.SelectedIndex = 0; + } + else + { + Text = Server.Name; + TitleLabel.Text = Server.Name; + NameTextBox.Text = Server.Name; + HostTextBox.Text = Server.Host; + PortTextBox.Text = Server.Port.ToString(); + UsernameTextBox.Text = Server.Username; + PasswordTextBox.Text = "********************"; + LoginComboBox.SelectedIndex = (int)Server.LoginType; + KeyTextBox.Text = Server.KeyFile; + changedPassword = false; + } + + BindChangeListeners(); + FormatImageButtons(); + UpdateCheckButtons(); + } + + private void Monitor_CheckStatusChanged(object sender, CheckStatusChangedEventArgs e) + { + CheckGrid.Refresh(); + if (e.CheckResult != null && logResults != null) + { + logResults.Insert(0, e.CheckResult); + if (logResultsFiltered != null && MatchesFilter(e.CheckResult)) + logResultsFiltered.Insert(0, e.CheckResult); + } + } + + /// <summary>Update the server with the current input values</summary> + /// <param name="forceSave"> + /// If true, immediately update the config file on disk. + /// If false, only update the config file if it has not been recently updated. + /// </param> + private void UpdateServer(bool forceSave = true) + { + Server.Name = NameTextBox.Text; + Server.Host = HostTextBox.Text.Trim(); + Server.Port = int.TryParse(PortTextBox.Text, out int port) ? port : 0; + Server.Username = UsernameTextBox.Text.Trim(); + Server.LoginType = (LoginType)LoginComboBox.SelectedIndex; + Server.KeyFile = KeyTextBox.Text.Trim(); + if (changedPassword) + Server.Password = PasswordTextBox.Text; + + if (forceSave || lastSaveTime < DateTime.Now.AddSeconds(-5)) + { + lastSaveTime = DateTime.Now; + monitor.SaveServers(); + } + } + + private void NameTextBox_TextChanged(object sender, EventArgs e) + { + Text = NameTextBox.Text; + TitleLabel.Text = NameTextBox.Text; + } + + private void LoginComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (LoginComboBox.SelectedIndex == (int)LoginType.PrivateKey) + { + PasswordTextBox.Visible = false; + KeyTextBox.Visible = true; + KeyBrowseButton.Visible = true; + } + else + { + PasswordTextBox.Visible = true; + KeyTextBox.Visible = false; + KeyBrowseButton.Visible = false; + } + } + + private void NewCheckButton_Click(object sender, EventArgs e) + { + ShowCheckForm(null); + } + + private void EditCheckButton_Click(object sender, EventArgs e) + { + EditSelectedCheck(); + } + + private void RunButton_Click(object sender, EventArgs e) + { + ExecuteChecks(SelectedChecks); + } + + private void RunAllButton_Click(object sender, EventArgs e) + { + ExecuteChecks(Server.Checks); + } + + private void ShowCheckForm(Check check) + { + if (check != null) + { + if (!checkForms.TryGetValue(check.Id, out CheckForm form)) + { + form = new CheckForm(monitor, check); + checkForms[check.Id] = form; + form.FormClosing += CheckForm_FormClosing; + form.Show(); + } + else + { + form.Activate(); + } + } + else + { + new CheckForm(monitor, Server).Show(); + } + } + + private void EditSelectedCheck() + { + ShowCheckForm(SelectedCheck); + } + + private void DeleteSelectedChecks() + { + if (Properties.Settings.Default.ConfirmDeleteCheck) + { + string message = "Delete " + (SelectedChecks.Count() == 1 ? "\"" + SelectedCheck.Name + "\"" : "selected checks") + "?"; + using (CheckBoxDialog dialog = new CheckBoxDialog { Message = message }) + { + DialogResult result = dialog.ShowDialog(); + if (dialog.Checked && result == DialogResult.OK) + { + Properties.Settings.Default.ConfirmDeleteCheck = false; + Properties.Settings.Default.Save(); + } + if (result != DialogResult.OK) + return; + } + } + foreach (Check check in SelectedChecks) + Server.DeleteCheck(check); + } + + private async void ExecuteChecks(IEnumerable<Check> checks) + { + await Task.WhenAll(checks.Select(c => monitor.ExecuteCheckAsync(c))); + } + + private void ShowLog(Check check) + { + LogCheckComboBox.SelectedItem = check; + CheckTabControl.SelectedTab = LogTabPage; + } + + private void UpdateCheckButtons() + { + RunAllButton.Enabled = CheckGrid.RowCount > 0; + RunButton.Enabled = DeleteCheckButton.Enabled = CheckGrid.SelectedRows.Count > 0; + EditCheckButton.Enabled = CheckGrid.SelectedRows.Count == 1; + } + + private void FormatImageButtons() + { + Button[] buttons = new Button[] { NewCheckButton, RunAllButton, RunButton, EditCheckButton, DeleteCheckButton }; + foreach (Button button in buttons) + Helpers.FormatImageButton(button); + } + + private void BindChangeListeners() + { + foreach (Control control in ServerInfoPanel.Controls.OfType<Control>().Where(c => c is TextBox)) + control.TextChanged += (sender, e) => UpdateServer(false); + foreach (Control control in Controls.OfType<Control>().Where(c => c is ComboBox)) + control.TextChanged += (sender, e) => UpdateServer(); + foreach (CheckBox control in LogTabPage.Controls.OfType<CheckBox>()) + control.CheckedChanged += FilterChanged; + } + + private void CheckForm_FormClosing(object sender, FormClosingEventArgs e) + { + CheckForm form = (CheckForm)sender; + form.FormClosing -= CheckForm_FormClosing; + checkForms.Remove(form.CheckId); + if (form.DialogResult == DialogResult.OK) + CheckGrid.Refresh(); + } + + private void CheckGrid_SelectionChanged(object sender, EventArgs e) + { + UpdateCheckButtons(); + } + + private void PasswordTextBox_TextChanged(object sender, EventArgs e) + { + changedPassword = true; + } + + private void ServerForm_FormClosing(object sender, FormClosingEventArgs e) + { + UpdateServer(); + } + + private void CheckGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e) + { + EditSelectedCheck(); + } + + private void CheckGrid_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + { + EditSelectedCheck(); + e.Handled = true; + } + } + + private void DeleteCheckButton_Click(object sender, EventArgs e) + { + DeleteSelectedChecks(); + UpdateServer(); + } + + private void CheckGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) + { + if (e.ColumnIndex == StatusColumn.Index) + { + e.Value = ((CheckStatus)e.Value).GetIcon(); + } + } + + private void LogGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) + { + if (e.ColumnIndex == LogStatusColumn.Index) + { + e.Value = ((CheckStatus)e.Value).GetIcon(); + } + } + + private void CheckBindingSource_ListChanged(object sender, ListChangedEventArgs e) + { + if (Server?.Checks != null) + { + //TODO this might result in the selection being reset to all (if a new check is added, for example.) Restore selected index. + LogCheckComboBox.Items.Clear(); + LogCheckComboBox.Items.Add("(All)"); + LogCheckComboBox.Items.AddRange(Server.Checks.ToArray()); + LogCheckComboBox.SelectedIndex = 0; + } + } + + private void CheckTabControl_SelectedIndexChanged(object sender, EventArgs e) + { + if (logResults == null && CheckTabControl.SelectedTab == LogTabPage) + { + logResults = new BindingList<CheckResult>(monitor.GetLog(Server)); + LogGrid.DataSource = logResults; + } + } + + private void CheckGrid_CellMouseEnter(object sender, DataGridViewCellEventArgs e) + { + if (e.ColumnIndex == StatusColumn.Index) + CheckGrid.Cursor = Cursors.Hand; + } + + private void CheckGrid_CellMouseLeave(object sender, DataGridViewCellEventArgs e) + { + if (e.ColumnIndex == StatusColumn.Index) + CheckGrid.Cursor = Cursors.Default; + } + + private void CheckGrid_CellClick(object sender, DataGridViewCellEventArgs e) + { + if (e.ColumnIndex == StatusColumn.Index) + ShowLog((Check)CheckBindingSource[e.RowIndex]); + } + + private void CheckGrid_CellContentClick(object sender, DataGridViewCellEventArgs e) + { + // The status column is set to read-only, and updates are manually done here. + // Otherwise, the change doesn't take effect until the cell loses focus. + if (e.ColumnIndex == EnabledColumn.Index) + { + Check check = (Check)CheckBindingSource[e.RowIndex]; + check.Enabled = !(bool)CheckGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; ; + Server.UpdateCheck(check); + } + } + + private void FilterChanged(object sender, EventArgs e) + { + filteredStatuses = filterChecks.Where(fc => fc.Key.Checked).Select(fc => fc.Value).ToArray(); + if (filteredStatuses.Length == filterChecks.Count && LogCheckComboBox.SelectedIndex == 0) { + LogGrid.DataSource = logResults; + logResultsFiltered = null; + } + else + { + logResultsFiltered = new BindingList<CheckResult>(logResults.Where(result => MatchesFilter(result)).ToList()); + LogGrid.DataSource = logResultsFiltered; + } + } + + private bool MatchesFilter(CheckResult result) + { + return filteredStatuses.Contains(result.CheckStatus) && (LogCheckComboBox.SelectedIndex == 0 || LogCheckComboBox.SelectedItem == result.Check); + } + } +}