Mercurial > servermonitor
comparison ServerMonitor/Forms/CheckForm.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 | 9e92780ebc0f |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3e1a2131f897 |
---|---|
1 using System; | |
2 using System.Collections.Generic; | |
3 using System.ComponentModel; | |
4 using System.Data; | |
5 using System.Drawing; | |
6 using System.Linq; | |
7 using System.Text; | |
8 using System.Threading; | |
9 using System.Windows.Forms; | |
10 | |
11 namespace ServerMonitorApp | |
12 { | |
13 public partial class CheckForm : Form | |
14 { | |
15 //private static readonly Dictionary<Type, CheckInfo> checkInfo = new Dictionary<Type, CheckInfo>(); | |
16 private readonly List<CheckControl> checkControls = new List<CheckControl>(); | |
17 private bool helpShown; | |
18 private CancellationTokenSource cancellationTokenSource; | |
19 private Check workCheck; | |
20 private CheckControl checkControl; | |
21 private QuickHelpForm helpForm; | |
22 private Server server; | |
23 private ServerMonitor monitor; | |
24 | |
25 public event EventHandler<HelpLocationChangedEventArgs> HelpLocationChanged; | |
26 | |
27 public Check Check { get; private set; } | |
28 | |
29 public int CheckId { get; private set; } | |
30 | |
31 public Point HelpLocation { get { return TypeHelpPictureBox.PointToScreen(Point.Empty); } } | |
32 | |
33 public CheckForm(ServerMonitor monitor, Check check) | |
34 { | |
35 InitializeComponent(); | |
36 | |
37 Check = check; | |
38 CheckId = Check.Id; | |
39 server = Check.Server; | |
40 this.monitor = monitor; | |
41 } | |
42 | |
43 public CheckForm(ServerMonitor monitor, Server server) | |
44 { | |
45 InitializeComponent(); | |
46 this.server = server; | |
47 this.monitor = monitor; | |
48 } | |
49 | |
50 private void CheckForm_Load(object sender, EventArgs e) | |
51 { | |
52 CheckTypeComboBox.Items.AddRange(Check.CheckTypes); | |
53 FrequencyUnitsComboBox.DataSource = Enum.GetValues(typeof(FrequencyUnits)); | |
54 Helpers.FormatImageButton(RunButton); | |
55 Helpers.FormatImageButton(CancelRunButton); | |
56 | |
57 Move += CheckForm_Move; | |
58 CheckTypePanel.LocationChanged += CheckTypePanel_LocationChanged; | |
59 GeneralGroupBox.Click += Control_Click; | |
60 CheckSettingsPanel.Click += Control_Click; | |
61 | |
62 CheckTypeComboBox.SelectedItem = Check?.GetType(); | |
63 if (Check != null) | |
64 LoadCheck(Check); | |
65 } | |
66 | |
67 private void CheckTypeComboBox_SelectedIndexChanged(object sender, EventArgs e) | |
68 { | |
69 ShowCheckControl(); | |
70 workCheck = (Check)Activator.CreateInstance((Type)CheckTypeComboBox.SelectedItem); | |
71 } | |
72 | |
73 private void CheckTypeComboBox_Format(object sender, ListControlConvertEventArgs e) | |
74 { | |
75 e.Value = Helpers.GetDisplayName((Type)e.ListItem); | |
76 } | |
77 | |
78 /*private void showGroupBox(GroupBox groupBox) | |
79 { | |
80 | |
81 }*/ | |
82 | |
83 /*private Type GetCheckType() | |
84 { | |
85 return (Type)CheckTypeComboBox.SelectedItem; | |
86 }*/ | |
87 | |
88 private void ShowCheckControl() | |
89 { | |
90 IEnumerable<CheckControl> checkControls = CheckSettingsPanel.Controls.OfType<CheckControl>(); | |
91 foreach (CheckControl control in checkControls) | |
92 control.Hide(); | |
93 Type type = (Type)CheckTypeComboBox.SelectedItem; | |
94 checkControl = checkControls.FirstOrDefault(c => c.CheckType == type); | |
95 if (checkControl == null) | |
96 { | |
97 checkControl = CheckControl.Create(type); | |
98 if (checkControl != null) | |
99 { | |
100 checkControl.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right; | |
101 checkControl.Click += Control_Click; | |
102 CheckSettingsPanel.Controls.Add(checkControl); | |
103 } | |
104 } | |
105 if (checkControl != null) | |
106 { | |
107 CheckSettingsPanel.Height = checkControl.Height; | |
108 //Height = 230 + checkControl.Height; | |
109 checkControl.Show(); | |
110 } | |
111 } | |
112 | |
113 private void LoadCheck(Check check) | |
114 { | |
115 NameTextBox.Text = Check.Name; | |
116 EnabledCheckBox.Checked = check.Enabled; | |
117 TimeoutInput.Value = check.Timeout; | |
118 FrequencyUnitsComboBox.SelectedItem = check.Schedule.Units; | |
119 FrequencyUpDown.Value = check.Schedule.Frequency; | |
120 StartTimePicker.Value = new DateTime(1970, 1, 1) + check.Schedule.StartTime; | |
121 EndTimePicker.Value = new DateTime(1970, 1, 1) + check.Schedule.EndTime; | |
122 checkControl?.LoadCheck(check); | |
123 } | |
124 | |
125 private bool UpdateCheck(Check check, bool saving = true) | |
126 { | |
127 string result; | |
128 if (CheckTypeComboBox.SelectedIndex == -1) | |
129 { | |
130 result = "Check type cannot be blank."; | |
131 } | |
132 else | |
133 { | |
134 check.Id = CheckId; | |
135 check.Server = server; | |
136 check.Name = NameTextBox.Text; | |
137 check.Enabled = EnabledCheckBox.Checked; | |
138 check.Timeout = (int)TimeoutInput.Value; | |
139 check.Schedule = new Schedule((FrequencyUnits)FrequencyUnitsComboBox.SelectedItem, (int)FrequencyUpDown.Value, StartTimePicker.Value.TimeOfDay, EndTimePicker.Value.TimeOfDay); | |
140 checkControl?.UpdateCheck(check); | |
141 result = check.Validate(saving); | |
142 } | |
143 if (!result.IsNullOrEmpty()) | |
144 { | |
145 MessageBox.Show(result, "Error validating check", MessageBoxButtons.OK, MessageBoxIcon.Error); | |
146 return false; | |
147 } | |
148 return true; | |
149 } | |
150 | |
151 private void OkButton_Click(object sender, EventArgs e) | |
152 { | |
153 if (!UpdateCheck(workCheck)) | |
154 return; | |
155 Check = workCheck; | |
156 server.UpdateCheck(Check); | |
157 monitor.SaveServers(); | |
158 Close(); | |
159 } | |
160 | |
161 private void CancelCheckButton_Click(object sender, EventArgs e) | |
162 { | |
163 Close(); | |
164 } | |
165 | |
166 private async void RunButton_Click(object sender, EventArgs e) | |
167 { | |
168 if (!UpdateCheck(workCheck, false)) | |
169 return; | |
170 | |
171 RunButton.Enabled = false; | |
172 RunButton.Text = "Running"; | |
173 ResultLabel.Visible = ResultIconPictureBox.Visible = false; | |
174 CancelRunButton.Visible = true; | |
175 | |
176 // Create a CancellationTokenSource for this execution, and set it to both variables. | |
177 // localCancellationTokenSource will mantain a reference to the token for this execution, | |
178 // while cancellationTokenSource might end up referencing a different token if the Cancel | |
179 // button is clicked (but the Task itself is unable to be cancelled), then Run is clicked | |
180 // again. | |
181 CancellationTokenSource localCancellationTokenSource = new CancellationTokenSource(); | |
182 cancellationTokenSource = localCancellationTokenSource; | |
183 CheckResult result = await workCheck.ExecuteAsync(cancellationTokenSource.Token, false); | |
184 if (!localCancellationTokenSource.IsCancellationRequested) | |
185 OnRunFinished(result); | |
186 localCancellationTokenSource.Dispose(); | |
187 localCancellationTokenSource = null; | |
188 } | |
189 | |
190 //private void RunButton_Click(object sender, EventArgs e) | |
191 //{ | |
192 // if (!Check.Server.SshClient.IsConnected) | |
193 // Check.Server.SshClient.Connect(); | |
194 // using (Renci.SshNet.SshCommand command = Check.Server.SshClient.CreateCommand("ls")) | |
195 // { | |
196 // //token.Register(command.CancelAsync); | |
197 // //command.BeginExecute(asyncResult => | |
198 // //{ | |
199 // // string result = command.EndExecute(asyncResult); | |
200 // // //tcs.SetResult(new CheckResult(this, CheckStatus.Success, result)); | |
201 // //}); | |
202 // IAsyncResult iar = command.BeginExecute(z); | |
203 // command.EndExecute(iar); | |
204 // //string result = command.Execute(); | |
205 // //System.Console.Write(result); | |
206 // } | |
207 //} | |
208 | |
209 //private void z(IAsyncResult ar) | |
210 //{ | |
211 // throw new NotImplementedException(); | |
212 //} | |
213 | |
214 private void CancelRunButton_Click(object sender, EventArgs e) | |
215 { | |
216 cancellationTokenSource.Cancel(); | |
217 OnRunFinished(); | |
218 } | |
219 | |
220 /// <summary>Updates the UI after a check is finished running.</summary> | |
221 /// <param name="result">Result of the check execution. If null, the check was cancelled before it completed.</param> | |
222 private void OnRunFinished(CheckResult result = null) | |
223 { | |
224 RunButton.Enabled = true; | |
225 RunButton.Text = "Run"; | |
226 CancelRunButton.Visible = false; | |
227 if (result != null) | |
228 { | |
229 ResultLabel.Text = result.Message; | |
230 //ResultLabel.ForeColor = result.CheckStatus == CheckStatus.Success ? Color.Green : Color.Red; | |
231 ResultIconPictureBox.Image = result.CheckStatus.GetIcon(); | |
232 ResultLabel.Visible = ResultIconPictureBox.Visible = true; | |
233 } | |
234 } | |
235 | |
236 /*private class CheckInfo | |
237 { | |
238 public GroupBox GroupBox { get; private set; } | |
239 | |
240 public Func<string> ValidateFunction { get; private set; } | |
241 | |
242 public CheckInfo(GroupBox groupBox, Func<string> validateFunction) | |
243 { | |
244 GroupBox = groupBox; | |
245 ValidateFunction = validateFunction; | |
246 } | |
247 }*/ | |
248 | |
249 private string BuildHelpText() | |
250 { | |
251 StringBuilder rtf = new StringBuilder(@"{\rtf1\ansi "); | |
252 foreach (Type checkType in Check.CheckTypes) | |
253 { | |
254 // Arguments to AppendLine() must end with a \ for the RichTextBox to render the newline character | |
255 rtf.Append(@"\b ").Append(Helpers.GetDisplayName(checkType)).AppendLine(@"\b0 \") | |
256 .Append(checkType.GetAttribute<DescriptionAttribute>()?.Description ?? "No description provided.").AppendLine(@"\").AppendLine(@"\"); | |
257 } | |
258 return rtf.ToString().TrimEnd(' ', '\r', '\n', '\\'); | |
259 } | |
260 | |
261 private void TypeHelpPictureBox_Click(object sender, EventArgs e) | |
262 { | |
263 if (helpShown) | |
264 { | |
265 helpForm.Close(); | |
266 } | |
267 else | |
268 { | |
269 helpForm = new QuickHelpForm(BuildHelpText()); | |
270 helpForm.FormClosed += QuickHelpForm_FormClosed; | |
271 helpForm.Show(this); | |
272 Activate(); | |
273 helpShown = true; | |
274 OnHelpLocationChanged(); | |
275 } | |
276 } | |
277 | |
278 private void QuickHelpForm_FormClosed(object sender, FormClosedEventArgs e) | |
279 { | |
280 helpShown = false; | |
281 helpForm.FormClosed -= QuickHelpForm_FormClosed; | |
282 helpForm.Dispose(); | |
283 } | |
284 | |
285 private void OnHelpLocationChanged() | |
286 { | |
287 HelpLocationChanged?.Invoke(this, new HelpLocationChangedEventArgs(HelpLocation)); | |
288 } | |
289 | |
290 private void CheckTypePanel_LocationChanged(object sender, EventArgs e) | |
291 { | |
292 OnHelpLocationChanged(); | |
293 } | |
294 | |
295 private void CheckForm_Move(object sender, EventArgs e) | |
296 { | |
297 OnHelpLocationChanged(); | |
298 } | |
299 | |
300 private void Control_Click(object sender, EventArgs e) | |
301 { | |
302 if (helpShown) | |
303 helpForm.Close(); | |
304 } | |
305 | |
306 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) | |
307 { | |
308 if (keyData == Keys.Escape && helpShown) | |
309 { | |
310 helpForm.Close(); | |
311 return true; | |
312 } | |
313 return base.ProcessCmdKey(ref msg, keyData); | |
314 } | |
315 | |
316 private void FrequencyUnitsComboBox_SelectedIndexChanged(object sender, EventArgs e) | |
317 { | |
318 ScheduleBetweenPanel.Visible = !(ScheduleAtPanel.Visible = FrequencyUnitsComboBox.SelectedIndex == 3); | |
319 } | |
320 | |
321 private void FrequencyUnitsComboBox_Format(object sender, ListControlConvertEventArgs e) | |
322 { | |
323 e.Value = e.Value.ToString().ToLower() + 's'; | |
324 } | |
325 } | |
326 | |
327 public class HelpLocationChangedEventArgs : EventArgs | |
328 { | |
329 public Point HelpLocation { get; private set; } | |
330 | |
331 public HelpLocationChangedEventArgs(Point helpLocation) | |
332 { | |
333 HelpLocation = helpLocation; | |
334 } | |
335 } | |
336 } |