WingMan – Blame information for rev 22

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections.Generic;
14 office 3 using System.Collections.ObjectModel;
1 office 4 using System.Drawing;
9 office 5 using System.IO;
1 office 6 using System.Linq;
7 using System.Net;
7 office 8 using System.Threading;
6 office 9 using System.Threading.Tasks;
1 office 10 using System.Windows.Forms;
4 office 11 using Gma.System.MouseKeyHook;
9 office 12 using MQTTnet.Extensions.ManagedClient;
13 using MQTTnet.Server;
14 office 14 using WingMan.Bindings;
1 office 15 using WingMan.Communication;
7 office 16 using WingMan.Lobby;
5 office 17 using WingMan.Properties;
8 office 18 using WingMan.Utilities;
1 office 19  
20 namespace WingMan
21 {
2 office 22 public partial class WingManForm : Form
1 office 23 {
5 office 24 public WingManForm()
25 {
26 InitializeComponent();
1 office 27  
6 office 28 FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
7 office 29 FormCancellationTokenSource = new CancellationTokenSource();
1 office 30  
9 office 31 MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token);
32 MqttCommunication.OnClientAuthenticationFailed += OnMqttClientAuthenticationFailed;
33 MqttCommunication.OnClientConnectionFailed += OnMqttClientConnectionFailed;
34 MqttCommunication.OnClientDisconnected += OnMqttClientDisconnected;
35 MqttCommunication.OnClientConnected += OnMqttClientConnected;
36 MqttCommunication.OnServerAuthenticationFailed += OnMqttServerAuthenticationFailed;
37 MqttCommunication.OnServerStopped += OnMqttServerStopped;
38 MqttCommunication.OnServerStarted += OnMqttServerStarted;
39 MqttCommunication.OnServerClientConnected += OnMqttServerClientConnected;
40 MqttCommunication.OnServerClientDisconnected += OnMqttServerClientDisconnected;
6 office 41  
10 office 42 LocalKeyBindings = new LocalKeyBindings(new List<KeyBinding>());
14 office 43 RemoteKeyBindings = new RemoteKeyBindings(new ObservableCollection<RemoteKeyBinding>());
1 office 44  
9 office 45 LocalListBoxBindingSource = new BindingSource
5 office 46 {
10 office 47 DataSource = LocalKeyBindings.Bindings
5 office 48 };
9 office 49 LocalBindingsListBox.DisplayMember = "DisplayName";
50 LocalBindingsListBox.ValueMember = "Keys";
51 LocalBindingsListBox.DataSource = LocalListBoxBindingSource;
1 office 52  
10 office 53 KeyBindingsExchange = new KeyBindingsExchange
5 office 54 {
10 office 55 ExchangeBindings = new List<KeyBindingExchange>()
7 office 56 };
57  
9 office 58 RemoteBindingsComboBoxSource = new BindingSource
7 office 59 {
10 office 60 DataSource = KeyBindingsExchange.ExchangeBindings
5 office 61 };
9 office 62 RemoteBindingsComboBox.DisplayMember = "Nick";
10 office 63 RemoteBindingsComboBox.ValueMember = "KeyBindings";
9 office 64 RemoteBindingsComboBox.DataSource = RemoteBindingsComboBoxSource;
4 office 65  
5 office 66 // Start lobby message synchronizer.
9 office 67 LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MqttCommunication, FormTaskScheduler,
7 office 68 FormCancellationTokenSource.Token);
5 office 69 LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived;
4 office 70  
5 office 71 // Start mouse key bindings synchronizer.
10 office 72 KeyBindingsSynchronizer = new KeyBindingsSynchronizer(LocalKeyBindings, MqttCommunication,
7 office 73 FormTaskScheduler, FormCancellationTokenSource.Token);
10 office 74 KeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
9 office 75  
10 office 76 // Start mouse key interceptor.
77 KeyInterceptor = new KeyInterceptor(RemoteKeyBindings, MqttCommunication, FormTaskScheduler,
78 FormCancellationTokenSource.Token);
79 KeyInterceptor.OnMouseKeyBindingMatched += OnMouseKeyBindingMatched;
80  
81 // Start mouse key simulator.
82 KeySimulator = new KeySimulator(LocalKeyBindings, MqttCommunication, FormTaskScheduler,
83 FormCancellationTokenSource.Token);
84 KeySimulator.OnMouseKeyBindingExecuting += OnMouseKeyBindingExecuting;
5 office 85 }
4 office 86  
7 office 87 private static CancellationTokenSource FormCancellationTokenSource { get; set; }
4 office 88  
7 office 89 private static TaskScheduler FormTaskScheduler { get; set; }
4 office 90  
7 office 91 private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; }
4 office 92  
7 office 93 private List<string> MouseKeyCombo { get; set; }
2 office 94  
10 office 95 private LocalKeyBindings LocalKeyBindings { get; }
4 office 96  
10 office 97 private RemoteKeyBindings RemoteKeyBindings { get; }
4 office 98  
9 office 99 private BindingSource LocalListBoxBindingSource { get; }
4 office 100  
9 office 101 private BindingSource RemoteBindingsComboBoxSource { get; }
102  
10 office 103 private KeyBindingsExchange KeyBindingsExchange { get; }
7 office 104  
9 office 105 public MqttCommunication MqttCommunication { get; set; }
7 office 106  
107 public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; }
108  
10 office 109 public KeyBindingsSynchronizer KeyBindingsSynchronizer { get; set; }
7 office 110  
10 office 111 public KeyInterceptor KeyInterceptor { get; set; }
112  
113 public KeySimulator KeySimulator { get; set; }
114  
21 office 115 /// <inheritdoc />
10 office 116 /// <summary>
117 /// Clean up any resources being used.
118 /// </summary>
119 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
120 protected override void Dispose(bool disposing)
8 office 121 {
10 office 122 FormCancellationTokenSource?.Dispose();
123 FormCancellationTokenSource = null;
9 office 124  
10 office 125 if (disposing && components != null)
9 office 126 {
10 office 127 components.Dispose();
128 components = null;
9 office 129 }
10 office 130  
131 base.Dispose(disposing);
9 office 132 }
133  
10 office 134 private void OnMouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args)
135 {
136 ActivityTextBox.AppendText(
137 $"{Strings.Executing_binding_from_remote_client} : {args.Nick} : {args.Name}{Environment.NewLine}");
138 }
139  
140 private void OnMouseKeyBindingMatched(object sender, KeyBindingMatchedEventArgs args)
141 {
142 ActivityTextBox.AppendText(
143 $"{Strings.Matched_remote_key_binding} : {args.Nick} : {args.Name} : {string.Join(" + ", args.KeyCombo)}{Environment.NewLine}");
144 }
145  
9 office 146 private void OnMqttServerClientDisconnected(object sender, MqttClientDisconnectedEventArgs e)
147 {
8 office 148 ActivityTextBox.AppendText(
9 office 149 $"{Strings.Client_disconnected}{Environment.NewLine}");
150 }
151  
152 private void OnMqttServerClientConnected(object sender, MqttClientConnectedEventArgs e)
153 {
154 ActivityTextBox.AppendText(
155 $"{Strings.Client_connected}{Environment.NewLine}");
156 }
157  
158 private void OnMqttServerStarted(object sender, EventArgs e)
159 {
160 ActivityTextBox.AppendText(
161 $"{Strings.Server_started}{Environment.NewLine}");
162 }
163  
164 private void OnMqttServerStopped(object sender, EventArgs e)
165 {
166 ActivityTextBox.AppendText(
167 $"{Strings.Server_stopped}{Environment.NewLine}");
168 }
169  
170 private void OnMqttClientConnected(object sender, MQTTnet.Client.MqttClientConnectedEventArgs e)
171 {
172 ActivityTextBox.AppendText(
173 $"{Strings.Client_connected}{Environment.NewLine}");
174 }
175  
176 private void OnMqttClientDisconnected(object sender, MQTTnet.Client.MqttClientDisconnectedEventArgs e)
177 {
178 ActivityTextBox.AppendText(
179 $"{Strings.Client_disconnected}{Environment.NewLine}");
180 }
181  
182 private void OnMqttClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e)
183 {
184 ActivityTextBox.AppendText(
185 $"{Strings.Client_connection_failed}{Environment.NewLine}");
186 }
187  
10 office 188 private void OnMqttServerAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e)
9 office 189 {
190 ActivityTextBox.AppendText(
10 office 191 $"{Strings.Failed_to_authenticate_client} : {e.Exception}{Environment.NewLine}");
8 office 192 }
193  
10 office 194 private void OnMqttClientAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e)
8 office 195 {
196 ActivityTextBox.AppendText(
10 office 197 $"{Strings.Failed_to_authenticate_with_server} : {e.Exception}{Environment.NewLine}");
8 office 198 }
199  
10 office 200 private void OnMouseKeyBindingsSynchronized(object sender, KeyBindingsSynchronizerEventArgs e)
7 office 201 {
202 ActivityTextBox.AppendText(
10 office 203 $"{Strings.Synchronized_bindings_with_client} : {e.Bindings.Nick} : {e.Bindings.KeyBindings.Count}{Environment.NewLine}");
6 office 204  
10 office 205 var exchangeBindings = KeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding =>
7 office 206 string.Equals(exchangeBinding.Nick, e.Bindings.Nick, StringComparison.Ordinal));
5 office 207  
7 office 208 // If the nick does not exist then add it.
209 if (exchangeBindings == null)
210 {
10 office 211 KeyBindingsExchange.ExchangeBindings.Add(e.Bindings);
9 office 212 RemoteBindingsComboBoxSource.ResetBindings(false);
10 office 213 UpdateRemoteItems();
7 office 214 return;
215 }
5 office 216  
7 office 217 // If the bindings for the nick have not changed then do not update.
10 office 218 if (exchangeBindings.KeyBindings.SequenceEqual(e.Bindings.KeyBindings))
7 office 219 {
9 office 220 RemoteBindingsComboBoxSource.ResetBindings(false);
10 office 221 UpdateRemoteItems();
7 office 222 return;
223 }
5 office 224  
7 office 225 // Update the bindings.
10 office 226 exchangeBindings.KeyBindings = e.Bindings.KeyBindings;
9 office 227 RemoteBindingsComboBoxSource.ResetBindings(false);
10 office 228 UpdateRemoteItems();
7 office 229 }
5 office 230  
10 office 231 private void UpdateRemoteItems()
7 office 232 {
10 office 233 var exchangeBindings = (List<KeyBinding>) RemoteBindingsComboBox.SelectedValue;
234 if (exchangeBindings == null)
7 office 235 return;
5 office 236  
14 office 237 var replaceMouseBindings = new ObservableCollection<RemoteKeyBinding>();
10 office 238 foreach (var remoteBinding in RemoteKeyBindings.Bindings)
239 {
240 if (!exchangeBindings.Any(binding =>
241 string.Equals(binding.Name, remoteBinding.Name, StringComparison.Ordinal)))
242 continue;
243  
244 replaceMouseBindings.Add(remoteBinding);
245 }
246  
21 office 247 RemoteKeyBindings.Bindings.Clear();
248 foreach (var binding in replaceMouseBindings) RemoteKeyBindings.Bindings.Add(binding);
10 office 249  
9 office 250 RemoteBindingsListBox.Items.Clear();
251 RemoteBindingsListBox.DisplayMember = "Name";
252 RemoteBindingsListBox.ValueMember = "Name";
10 office 253 var bindings = exchangeBindings.Select(binding => (object) binding.Name).ToArray();
254 if (bindings.Length == 0)
7 office 255 return;
5 office 256  
10 office 257 RemoteBindingsListBox.Items.AddRange(bindings);
7 office 258 }
5 office 259  
260 private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e)
261 {
9 office 262 LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
5 office 263 }
264  
1 office 265 private void AddressTextBoxClick(object sender, EventArgs e)
266 {
267 Address.BackColor = Color.Empty;
268 }
269  
270 private void PortTextBoxClick(object sender, EventArgs e)
271 {
272 Port.BackColor = Color.Empty;
273 }
274  
275 private async void HostButtonClickAsync(object sender, EventArgs e)
276 {
277 // Stop the MQTT server if it is running.
9 office 278 if (MqttCommunication.Running)
1 office 279 {
10 office 280 await MqttCommunication.Stop();
1 office 281 HostButton.BackColor = Color.Empty;
282  
3 office 283 // Enable controls.
1 office 284 ConnectButton.Enabled = true;
5 office 285 Address.Enabled = true;
286 Port.Enabled = true;
287 Nick.Enabled = true;
10 office 288 Password.Enabled = true;
1 office 289 return;
290 }
291  
21 office 292 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password))
1 office 293 return;
294  
295 // Start the MQTT server.
10 office 296 if (!await MqttCommunication
297 .Start(MqttCommunicationType.Server, ipAddress, port, nick, password))
9 office 298 {
299 ActivityTextBox.AppendText(
300 $"{Strings.Failed_starting_server}{Environment.NewLine}");
301 return;
302 }
303  
1 office 304 HostButton.BackColor = Color.Aquamarine;
305  
3 office 306 // Disable controls
1 office 307 ConnectButton.Enabled = false;
3 office 308 Address.Enabled = false;
309 Port.Enabled = false;
310 Nick.Enabled = false;
10 office 311 Password.Enabled = false;
3 office 312 }
313  
21 office 314 private bool ValidateConnectionParameters(
315 out IPAddress address,
316 out int port,
317 out string nick,
318 out string password)
1 office 319 {
320 address = IPAddress.Any;
321 port = 0;
2 office 322 nick = string.Empty;
8 office 323 password = string.Empty;
1 office 324  
325 if (string.IsNullOrEmpty(Address.Text) &&
2 office 326 string.IsNullOrEmpty(Port.Text) &&
8 office 327 string.IsNullOrEmpty(Nick.Text) &&
328 string.IsNullOrEmpty(Password.Text))
1 office 329 {
330 Address.BackColor = Color.LightPink;
331 Port.BackColor = Color.LightPink;
2 office 332 Nick.BackColor = Color.LightPink;
8 office 333 Password.BackColor = Color.LightPink;
1 office 334 return false;
335 }
336  
337 if (!IPAddress.TryParse(Address.Text, out address))
21 office 338 try
339 {
340 address = Dns.GetHostAddresses(Address.Text).FirstOrDefault();
341 }
342 catch (Exception ex)
343 {
344 ActivityTextBox.AppendText(
345 $"{Strings.Could_not_resolve_hostname} : {ex.Message}{Environment.NewLine}");
1 office 346  
21 office 347 Address.BackColor = Color.LightPink;
348 return false;
349 }
350  
1 office 351 if (!uint.TryParse(Port.Text, out var uPort))
352 {
353 Port.BackColor = Color.LightPink;
354 return false;
355 }
356  
357 port = (int) uPort;
358  
2 office 359 if (string.IsNullOrEmpty(Nick.Text))
360 {
361 Nick.BackColor = Color.LightPink;
362 return false;
363 }
364  
365 nick = Nick.Text;
366  
8 office 367 if (string.IsNullOrEmpty(Password.Text))
368 {
369 Password.BackColor = Color.LightPink;
370 return false;
371 }
372  
10 office 373 password = AES.ExpandKey(Password.Text);
8 office 374  
1 office 375 Address.BackColor = Color.Empty;
376 Port.BackColor = Color.Empty;
2 office 377 Nick.BackColor = Color.Empty;
8 office 378 Password.BackColor = Color.Empty;
1 office 379  
380 return true;
381 }
382  
383 private async void ConnectButtonClickAsync(object sender, EventArgs e)
384 {
9 office 385 if (MqttCommunication.Running)
1 office 386 {
10 office 387 await MqttCommunication.Stop();
5 office 388 ConnectButton.Text = Strings.Connect;
1 office 389 ConnectButton.BackColor = Color.Empty;
390  
5 office 391 Address.Enabled = true;
392 Port.Enabled = true;
393 Nick.Enabled = true;
10 office 394 Password.Enabled = true;
1 office 395 HostButton.Enabled = true;
396 return;
397 }
398  
21 office 399 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password))
1 office 400 return;
401  
10 office 402 if (!await MqttCommunication
403 .Start(MqttCommunicationType.Client, ipAddress, port, nick, password))
9 office 404 {
405 ActivityTextBox.AppendText(
406 $"{Strings.Failed_starting_client}{Environment.NewLine}");
407 return;
408 }
1 office 409  
5 office 410 ConnectButton.Text = Strings.Disconnect;
1 office 411 ConnectButton.BackColor = Color.Aquamarine;
412  
413 HostButton.Enabled = false;
5 office 414 Address.Enabled = false;
415 Port.Enabled = false;
416 Nick.Enabled = false;
10 office 417 Password.Enabled = false;
1 office 418 }
419  
2 office 420 private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e)
421 {
422 if (e.KeyCode != Keys.Enter)
423 return;
424  
10 office 425 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text);
2 office 426  
5 office 427 LobbySayTextBox.Text = string.Empty;
2 office 428 }
4 office 429  
10 office 430 private void LocalAddBindingButtonClick(object sender, EventArgs e)
4 office 431 {
9 office 432 if (string.IsNullOrEmpty(LocalNameTextBox.Text))
4 office 433 {
9 office 434 LocalNameTextBox.BackColor = Color.LightPink;
4 office 435 return;
436 }
437  
10 office 438 // Only unique names allowed.
439 if (LocalKeyBindings.Bindings.Any(binding =>
440 string.Equals(binding.Name, LocalNameTextBox.Text, StringComparison.Ordinal)))
441 {
442 LocalNameTextBox.BackColor = Color.LightPink;
443 LocalBindingsListBox.BackColor = Color.LightPink;
444 return;
445 }
446  
447 LocalNameTextBox.BackColor = Color.Empty;
448 LocalBindingsListBox.BackColor = Color.Empty;
449  
8 office 450 ShowOverlayPanel();
4 office 451  
452 MouseKeyCombo = new List<string>();
453  
10 office 454 MouseKeyApplicationHook = Hook.GlobalEvents();
9 office 455 MouseKeyApplicationHook.KeyUp += LocalMouseKeyHookOnKeyUp;
456 MouseKeyApplicationHook.KeyDown += LocalMouseKeyHookOnKeyDown;
4 office 457 }
458  
8 office 459 private void ShowOverlayPanel()
460 {
461 OverlayPanel.BringToFront();
462 OverlayPanel.Visible = true;
463 OverlayPanel.Invalidate();
464 }
465  
14 office 466 private async void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
4 office 467 {
10 office 468 LocalKeyBindings.Bindings.Add(new KeyBinding(LocalNameTextBox.Text, MouseKeyCombo));
4 office 469  
9 office 470 LocalListBoxBindingSource.ResetBindings(false);
4 office 471  
9 office 472 MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
473 MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
4 office 474  
475 MouseKeyApplicationHook.Dispose();
476  
9 office 477 LocalNameTextBox.Text = string.Empty;
8 office 478 HideOverlayPanel();
9 office 479  
14 office 480 await SaveLocalMouseKeyBindings();
4 office 481 }
482  
8 office 483 private void HideOverlayPanel()
484 {
485 OverlayPanel.SendToBack();
486 OverlayPanel.Visible = false;
487 OverlayPanel.Invalidate();
488 }
489  
9 office 490 private void LocalMouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
4 office 491 {
492 e.SuppressKeyPress = true;
493  
10 office 494 KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key);
495  
496 MouseKeyCombo.Add(key);
4 office 497 }
498  
10 office 499 private void LocalNameTextBoxClick(object sender, EventArgs e)
4 office 500 {
9 office 501 LocalNameTextBox.BackColor = Color.Empty;
4 office 502 }
503  
14 office 504 private async void LocalBindingsRemoveButtonClick(object sender, EventArgs e)
4 office 505 {
10 office 506 var helmBinding = (KeyBinding) LocalBindingsListBox.SelectedItem;
5 office 507 if (helmBinding == null)
508 return;
4 office 509  
10 office 510 LocalKeyBindings.Bindings.Remove(helmBinding);
9 office 511 LocalListBoxBindingSource.ResetBindings(false);
512  
14 office 513 await SaveLocalMouseKeyBindings();
4 office 514 }
515  
5 office 516 private async void LobbySayButtonClick(object sender, EventArgs e)
4 office 517 {
10 office 518 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text);
4 office 519  
5 office 520 LobbySayTextBox.Text = string.Empty;
4 office 521 }
522  
9 office 523 private void RemoteBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e)
4 office 524 {
10 office 525 UpdateRemoteItems();
4 office 526 }
8 office 527  
14 office 528 private async void WingManFormOnLoad(object sender, EventArgs e)
8 office 529 {
14 office 530 await LoadLocalMouseKeyBindings();
10 office 531  
14 office 532 await LoadRemoteMouseKeyBindings();
8 office 533 }
9 office 534  
10 office 535 private void RemoteBindingsBindButtonClicked(object sender, EventArgs e)
9 office 536 {
10 office 537 if (string.IsNullOrEmpty((string) RemoteBindingsListBox.SelectedItem))
9 office 538 {
10 office 539 RemoteBindingsListBox.BackColor = Color.LightPink;
540 return;
541 }
9 office 542  
10 office 543 RemoteBindingsListBox.BackColor = Color.Empty;
9 office 544  
10 office 545 ShowOverlayPanel();
9 office 546  
10 office 547 MouseKeyCombo = new List<string>();
9 office 548  
10 office 549 MouseKeyApplicationHook = Hook.GlobalEvents();
21 office 550 MouseKeyApplicationHook.KeyUp += RemoteKeyHookOnKeyUp;
551 MouseKeyApplicationHook.KeyDown += RemoteKeyHookOnKeyDown;
9 office 552 }
553  
10 office 554 private void RemoteBindingsUnbindButtonClicked(object sender, EventArgs e)
9 office 555 {
10 office 556 var item = (string) RemoteBindingsListBox.SelectedItem;
557 if (string.IsNullOrEmpty(item))
558 {
559 RemoteBindingsListBox.BackColor = Color.LightPink;
560 return;
561 }
9 office 562  
10 office 563 RemoteBindingsListBox.BackColor = Color.Empty;
9 office 564  
10 office 565 var remoteKeyBinding = RemoteKeyBindings.Bindings.FirstOrDefault(binding =>
566 string.Equals(binding.Name, item, StringComparison.Ordinal));
567  
568 if (remoteKeyBinding == null)
569 return;
570  
571 RemoteKeyBindings.Bindings.Remove(remoteKeyBinding);
572 RemoteBindingsBindToBox.Text = string.Empty;
9 office 573 }
574  
21 office 575 private void RemoteKeyHookOnKeyDown(object sender, KeyEventArgs e)
9 office 576 {
577 e.SuppressKeyPress = true;
578  
21 office 579 if (!KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key))
580 return;
9 office 581  
10 office 582 MouseKeyCombo.Add(key);
9 office 583 }
584  
21 office 585 private async void RemoteKeyHookOnKeyUp(object sender, KeyEventArgs e)
9 office 586 {
10 office 587 RemoteKeyBindings.Bindings.Add(new RemoteKeyBinding(RemoteBindingsComboBox.Text,
9 office 588 (string) RemoteBindingsListBox.SelectedItem, MouseKeyCombo));
589  
21 office 590 MouseKeyApplicationHook.KeyDown -= RemoteKeyHookOnKeyDown;
591 MouseKeyApplicationHook.KeyUp -= RemoteKeyHookOnKeyUp;
9 office 592  
593 MouseKeyApplicationHook.Dispose();
594  
595 RemoteBindingsBindToBox.Text = string.Join(" + ", MouseKeyCombo);
596 HideOverlayPanel();
597  
14 office 598 await SaveRemoteMouseKeyBindings();
9 office 599 }
600  
10 office 601 private void RemoteBindingsListBoxSelectedValueChanged(object sender, EventArgs e)
9 office 602 {
10 office 603 RemoteBindingsBindToBox.Text = "";
9 office 604  
10 office 605 var name = (string) RemoteBindingsListBox.SelectedItem;
606 if (string.IsNullOrEmpty(name))
607 return;
9 office 608  
14 office 609 var nick = RemoteBindingsComboBox.Text;
610 if (string.IsNullOrEmpty(nick))
611 return;
612  
10 office 613 foreach (var binding in RemoteKeyBindings.Bindings)
614 {
14 office 615 if (!string.Equals(binding.Nick, nick) || !string.Equals(binding.Name, name))
10 office 616 continue;
9 office 617  
10 office 618 RemoteBindingsBindToBox.Text = string.Join(" + ", binding.Keys);
619 break;
620 }
621 }
9 office 622  
10 office 623 #region Saving and loading
624  
625 private async Task SaveLocalMouseKeyBindings()
626 {
627 try
628 {
629 using (var memoryStream = new MemoryStream())
630 {
631 LocalKeyBindings.XmlSerializer.Serialize(memoryStream, LocalKeyBindings);
632  
633 memoryStream.Position = 0L;
634  
635 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Create))
636 {
637 await memoryStream.CopyToAsync(fileStream);
638 }
639 }
640 }
641 catch (Exception)
642 {
643 ActivityTextBox.AppendText(
644 $"{Strings.Failed_saving_local_bindings}{Environment.NewLine}");
645 }
9 office 646 }
647  
10 office 648 private async Task LoadLocalMouseKeyBindings()
649 {
650 try
651 {
652 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Open))
653 {
654 using (var memoryStream = new MemoryStream())
655 {
656 await fileStream.CopyToAsync(memoryStream);
657  
658 memoryStream.Position = 0L;
659  
660 var loadedBindings =
661 (LocalKeyBindings) LocalKeyBindings.XmlSerializer.Deserialize(memoryStream);
662  
21 office 663 foreach (var binding in loadedBindings.Bindings)
664 LocalKeyBindings.Bindings.Add(binding);
10 office 665  
666 LocalListBoxBindingSource.ResetBindings(false);
667 }
668 }
669 }
670 catch (Exception)
671 {
672 ActivityTextBox.AppendText(
673 $"{Strings.Failed_loading_local_bindings}{Environment.NewLine}");
674 }
675 }
676  
9 office 677 private async Task SaveRemoteMouseKeyBindings()
678 {
679 try
680 {
681 using (var memoryStream = new MemoryStream())
682 {
10 office 683 RemoteKeyBindings.XmlSerializer.Serialize(memoryStream, RemoteKeyBindings);
9 office 684  
685 memoryStream.Position = 0L;
686  
10 office 687 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Create))
9 office 688 {
10 office 689 await memoryStream.CopyToAsync(fileStream);
9 office 690 }
691 }
692 }
693 catch (Exception)
694 {
695 ActivityTextBox.AppendText(
696 $"{Strings.Failed_saving_remote_bindings}{Environment.NewLine}");
697 }
698 }
699  
700 private async Task LoadRemoteMouseKeyBindings()
701 {
702 try
703 {
10 office 704 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Open))
9 office 705 {
706 using (var memoryStream = new MemoryStream())
707 {
10 office 708 await fileStream.CopyToAsync(memoryStream);
9 office 709  
710 memoryStream.Position = 0L;
711  
712 var loadedBindings =
10 office 713 (RemoteKeyBindings) RemoteKeyBindings.XmlSerializer.Deserialize(memoryStream);
9 office 714  
21 office 715 foreach (var binding in loadedBindings.Bindings)
716 RemoteKeyBindings.Bindings.Add(binding);
9 office 717 }
718 }
719 }
720 catch (Exception)
721 {
722 ActivityTextBox.AppendText(
723 $"{Strings.Failed_loading_remote_bindings}{Environment.NewLine}");
724 }
725 }
10 office 726  
727 #endregion
22 office 728  
729 private void WingManFormResized(object sender, EventArgs e)
730 {
731 if (WindowState == FormWindowState.Minimized)
732 {
733 Hide();
734 notifyIcon1.Visible = true;
735 }
736 }
737  
738 private void NotifyIconDoubleClick(object sender, EventArgs e)
739 {
740 Show();
741 WindowState = FormWindowState.Normal;
742 notifyIcon1.Visible = false;
743 }
1 office 744 }
745 }