WingMan – Blame information for rev 23

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