You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConfigForm.cs 25 kB

10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
10 years ago
12 years ago
12 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
5 years ago
5 years ago
5 years ago
12 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. using Shadowsocks.Controller;
  2. using Shadowsocks.Model;
  3. using Shadowsocks.Properties;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Drawing;
  7. using System.Linq;
  8. using System.Windows.Forms;
  9. namespace Shadowsocks.View
  10. {
  11. public partial class ConfigForm : Form
  12. {
  13. private ShadowsocksController controller;
  14. // this is a copy of configuration that we are working on
  15. private Configuration _modifiedConfiguration;
  16. private int _lastSelectedIndex = -1;
  17. private bool isChange = false;
  18. private class EncryptionMethod
  19. {
  20. public readonly string name;
  21. public readonly bool deprecated;
  22. // Edit here to add/delete encryption method displayed in UI
  23. private static string[] deprecatedMethod = new string[]
  24. {
  25. "rc4-md5",
  26. "salsa20",
  27. "chacha20",
  28. "bf-cfb",
  29. "chacha20-ietf",
  30. "aes-256-cfb",
  31. "aes-192-cfb",
  32. "aes-128-cfb",
  33. "aes-256-ctr",
  34. "aes-192-ctr",
  35. "aes-128-ctr",
  36. "camellia-256-cfb",
  37. "camellia-192-cfb",
  38. "camellia-128-cfb",
  39. };
  40. private static string[] inuseMethod = new string[]
  41. {
  42. "aes-256-gcm",
  43. "aes-192-gcm",
  44. "aes-128-gcm",
  45. "chacha20-ietf-poly1305",
  46. "xchacha20-ietf-poly1305",
  47. };
  48. public static EncryptionMethod[] AllMethods
  49. {
  50. get
  51. {
  52. if (!init) Init();
  53. return allMethods;
  54. }
  55. }
  56. private static bool init = false;
  57. private static EncryptionMethod[] allMethods;
  58. private static Dictionary<string, EncryptionMethod> methodByName = new Dictionary<string, EncryptionMethod>();
  59. private static void Init()
  60. {
  61. var all = new List<EncryptionMethod>();
  62. all.AddRange(inuseMethod.Select(i => new EncryptionMethod(i, false)));
  63. all.AddRange(deprecatedMethod.Select(d => new EncryptionMethod(d, true)));
  64. allMethods = all.ToArray();
  65. foreach (var item in all)
  66. {
  67. methodByName[item.name] = item;
  68. }
  69. init = true;
  70. }
  71. public static EncryptionMethod GetMethod(string name)
  72. {
  73. if (!init) Init();
  74. bool success = methodByName.TryGetValue(name, out EncryptionMethod method);
  75. if (!success)
  76. {
  77. string defaultMethod = Server.DefaultMethod;
  78. MessageBox.Show(I18N.GetString("Encryption method {0} not exist, will replace with {1}", name, defaultMethod), I18N.GetString("Shadowsocks"));
  79. return methodByName[defaultMethod];
  80. }
  81. return method;
  82. }
  83. private EncryptionMethod(string name, bool deprecated)
  84. {
  85. this.name = name;
  86. this.deprecated = deprecated;
  87. }
  88. public override string ToString()
  89. {
  90. return deprecated ? $"{name} ({I18N.GetString("deprecated")})" : name;
  91. }
  92. }
  93. public ConfigForm(ShadowsocksController controller)
  94. {
  95. Font = SystemFonts.MessageBoxFont;
  96. InitializeComponent();
  97. EncryptionSelect.Items.AddRange(EncryptionMethod.AllMethods);
  98. // a dirty hack
  99. ServersListBox.Dock = DockStyle.Fill;
  100. tableLayoutPanel5.Dock = DockStyle.Fill;
  101. PerformLayout();
  102. UpdateTexts();
  103. SetupValueChangedListeners();
  104. Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
  105. this.controller = controller;
  106. controller.ConfigChanged += Controller_ConfigChanged;
  107. LoadCurrentConfiguration();
  108. }
  109. private void UpdateTexts()
  110. {
  111. I18N.TranslateForm(this);
  112. toolTip1.SetToolTip(PortableModeCheckBox, I18N.GetString("Restart required"));
  113. }
  114. private void SetupValueChangedListeners()
  115. {
  116. IPTextBox.TextChanged += ConfigValueChanged;
  117. ProxyPortTextBox.TextChanged += ConfigValueChanged;
  118. PasswordTextBox.TextChanged += ConfigValueChanged;
  119. EncryptionSelect.SelectedIndexChanged += ConfigValueChanged;
  120. PluginTextBox.TextChanged += ConfigValueChanged;
  121. PluginArgumentsTextBox.TextChanged += ConfigValueChanged;
  122. PluginOptionsTextBox.TextChanged += ConfigValueChanged;
  123. RemarksTextBox.TextChanged += ConfigValueChanged;
  124. TimeoutTextBox.TextChanged += ConfigValueChanged;
  125. PortableModeCheckBox.CheckedChanged += ConfigValueChanged;
  126. ServerPortTextBox.TextChanged += ConfigValueChanged;
  127. }
  128. private void Controller_ConfigChanged(object sender, EventArgs e)
  129. {
  130. LoadCurrentConfiguration();
  131. }
  132. private void ConfigValueChanged(object sender, EventArgs e)
  133. {
  134. isChange = true;
  135. ApplyButton.Enabled = true;
  136. }
  137. private bool ValidateAndSaveSelectedServerDetails(bool isSave = false, bool isCopy = false)
  138. {
  139. try
  140. {
  141. if (_lastSelectedIndex == -1 || _lastSelectedIndex >= _modifiedConfiguration.configs.Count)
  142. {
  143. return true;
  144. }
  145. bool verify = GetServerDetailsFromUI(out Server server, isSave, isCopy);
  146. if (server != null)
  147. {
  148. if (isSave || isCopy)
  149. Configuration.CheckServer(server);
  150. _modifiedConfiguration.configs[_lastSelectedIndex] = server;
  151. }
  152. return verify;
  153. }
  154. catch (Exception ex)
  155. {
  156. MessageBox.Show(ex.Message);
  157. }
  158. return false;
  159. }
  160. private bool GetServerDetailsFromUI(out Server server, bool isSave = false, bool isCopy = false)
  161. {
  162. server = null;
  163. bool? checkIP = false;
  164. bool? checkPort = false;
  165. bool? checkPassword = false;
  166. bool? checkTimeout = false;
  167. if ((checkIP = CheckIPTextBox(out string address, isSave, isCopy)).GetValueOrDefault(false) && address != null
  168. && (checkPort = CheckServerPortTextBox(out int? addressPort, isSave, isCopy)).GetValueOrDefault(false) && addressPort.HasValue
  169. && (checkPassword = CheckPasswordTextBox(out string serverPassword, isSave, isCopy)).GetValueOrDefault(false) && serverPassword != null
  170. && (checkTimeout = CheckTimeoutTextBox(out int? timeout, isSave, isCopy)).GetValueOrDefault(false) && timeout.HasValue)
  171. {
  172. server = new Server()
  173. {
  174. server = address,
  175. server_port = addressPort.Value,
  176. password = serverPassword,
  177. method = ((EncryptionMethod)EncryptionSelect.SelectedItem).name,
  178. plugin = PluginTextBox.Text,
  179. plugin_opts = PluginOptionsTextBox.Text,
  180. plugin_args = PluginArgumentsTextBox.Text,
  181. remarks = RemarksTextBox.Text,
  182. timeout = timeout.Value,
  183. };
  184. return true;
  185. }
  186. if (checkIP == null || checkPort == null || checkTimeout == null)
  187. {
  188. _modifiedConfiguration.configs.RemoveAt(_lastSelectedIndex);
  189. ServersListBox.SelectedIndexChanged -= ServersListBox_SelectedIndexChanged;
  190. int lastIndex = ServersListBox.SelectedIndex;
  191. LoadServerNameListToUI(_modifiedConfiguration);
  192. _lastSelectedIndex = (ServersListBox.SelectedIndex = (_lastSelectedIndex == ServersListBox.Items.Count ? lastIndex : lastIndex - 1));
  193. ServersListBox.SelectedIndexChanged += ServersListBox_SelectedIndexChanged;
  194. return true;
  195. }
  196. else
  197. return false;
  198. }
  199. #region GetServerDetailsFromUI Check
  200. private bool? CheckIPTextBox(out string address, bool isSave, bool isCopy)
  201. {
  202. address = null;
  203. string outAddress;
  204. if (Uri.CheckHostName(outAddress = IPTextBox.Text.Trim()) == UriHostNameType.Unknown)
  205. {
  206. if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString()))
  207. {
  208. DialogResult result = MessageBox.Show(I18N.GetString("Whether to discard unconfigured servers"), I18N.GetString("Operation failure"), MessageBoxButtons.OKCancel);
  209. if (result == DialogResult.OK)
  210. return null;
  211. }
  212. else if (isChange && !isSave && !isCopy)
  213. {
  214. var result = MessageBox.Show(I18N.GetString("Invalid server address, Cannot automatically save or discard changes"), I18N.GetString("Auto save failed"), MessageBoxButtons.OKCancel);
  215. if (result == DialogResult.Cancel)
  216. return false;
  217. else
  218. {
  219. address = _modifiedConfiguration.configs[_lastSelectedIndex].server;
  220. return true;
  221. }
  222. }
  223. else
  224. {
  225. MessageBox.Show(I18N.GetString("Invalid server address"), I18N.GetString("Operation failure"));
  226. IPTextBox.Focus();
  227. }
  228. return false;
  229. }
  230. else
  231. {
  232. address = outAddress;
  233. }
  234. return true;
  235. }
  236. private bool? CheckServerPortTextBox(out int? addressPort, bool isSave, bool isCopy)
  237. {
  238. addressPort = null;
  239. if (!int.TryParse(ServerPortTextBox.Text, out int outaddressPort))
  240. {
  241. if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString()))
  242. {
  243. DialogResult result = MessageBox.Show(I18N.GetString("Whether to discard unconfigured servers"), I18N.GetString("Operation failure"), MessageBoxButtons.OKCancel);
  244. if (result == DialogResult.OK)
  245. return null;
  246. }
  247. else if (isChange && !isSave && !isCopy)
  248. {
  249. var result = MessageBox.Show(I18N.GetString("Illegal port number format, Cannot automatically save or discard changes"), I18N.GetString("Auto save failed"), MessageBoxButtons.OKCancel);
  250. if (result == DialogResult.Cancel)
  251. return false;
  252. else
  253. {
  254. addressPort = _modifiedConfiguration.configs[_lastSelectedIndex].server_port;
  255. return true;
  256. }
  257. }
  258. else
  259. {
  260. MessageBox.Show(I18N.GetString("Illegal port number format"), I18N.GetString("Operation failure"));
  261. ServerPortTextBox.Focus();
  262. }
  263. return false;
  264. }
  265. else
  266. {
  267. addressPort = outaddressPort;
  268. }
  269. return true;
  270. }
  271. private bool? CheckPasswordTextBox(out string password, bool isSave, bool isCopy)
  272. {
  273. password = null;
  274. string outPassword;
  275. if ((outPassword = PasswordTextBox.Text).IsNullOrWhiteSpace())
  276. {
  277. if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString()))
  278. {
  279. DialogResult result = MessageBox.Show(I18N.GetString("Whether to discard unconfigured servers"), I18N.GetString("Operation failure"), MessageBoxButtons.OKCancel);
  280. if (result == DialogResult.OK)
  281. return null;
  282. }
  283. else if (isChange && !isSave && !isCopy)
  284. {
  285. var result = MessageBox.Show(I18N.GetString("Password can not be blank, Cannot automatically save or discard changes"), I18N.GetString("Auto save failed"), MessageBoxButtons.OKCancel);
  286. if (result == DialogResult.Cancel)
  287. return false;
  288. else
  289. {
  290. password = _modifiedConfiguration.configs[_lastSelectedIndex].password;
  291. return true;
  292. }
  293. }
  294. else
  295. {
  296. MessageBox.Show(I18N.GetString("Password can not be blank"), I18N.GetString("Operation failure"));
  297. PasswordTextBox.Focus();
  298. }
  299. return false;
  300. }
  301. else
  302. {
  303. password = outPassword;
  304. }
  305. return true;
  306. }
  307. private bool? CheckTimeoutTextBox(out int? timeout, bool isSave, bool isCopy)
  308. {
  309. timeout = null;
  310. if (!int.TryParse(TimeoutTextBox.Text, out int outTimeout))
  311. {
  312. if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString()))
  313. {
  314. DialogResult result = MessageBox.Show(I18N.GetString("Whether to discard unconfigured servers"), I18N.GetString("Operation failure"), MessageBoxButtons.OKCancel);
  315. if (result == DialogResult.OK)
  316. return null;
  317. }
  318. else if (isChange && !isSave && !isCopy)
  319. {
  320. var result = MessageBox.Show(I18N.GetString("Illegal timeout format, Cannot automatically save or discard changes"), I18N.GetString("Auto save failed"), MessageBoxButtons.OKCancel);
  321. if (result == DialogResult.Cancel)
  322. return false;
  323. else
  324. {
  325. timeout = _modifiedConfiguration.configs[_lastSelectedIndex].timeout;
  326. return true;
  327. }
  328. }
  329. else
  330. {
  331. MessageBox.Show(I18N.GetString("Illegal timeout format"), I18N.GetString("Operation failure"));
  332. TimeoutTextBox.Focus();
  333. }
  334. return false;
  335. }
  336. else
  337. {
  338. timeout = outTimeout;
  339. }
  340. return true;
  341. }
  342. #endregion
  343. private void LoadSelectedServerDetails()
  344. {
  345. if (ServersListBox.SelectedIndex >= 0 && ServersListBox.SelectedIndex < _modifiedConfiguration.configs.Count)
  346. {
  347. Server server = _modifiedConfiguration.configs[ServersListBox.SelectedIndex];
  348. SetServerDetailsToUI(server);
  349. }
  350. }
  351. private void SetServerDetailsToUI(Server server)
  352. {
  353. IPTextBox.Text = server.server;
  354. ServerPortTextBox.Text = server.server_port.ToString();
  355. PasswordTextBox.Text = server.password;
  356. EncryptionSelect.SelectedItem = EncryptionMethod.GetMethod(server.method ?? Server.DefaultMethod);
  357. PluginTextBox.Text = server.plugin;
  358. PluginOptionsTextBox.Text = server.plugin_opts;
  359. PluginArgumentsTextBox.Text = server.plugin_args;
  360. bool showPluginArgInput = !string.IsNullOrEmpty(server.plugin_args);
  361. NeedPluginArgCheckBox.Checked = showPluginArgInput;
  362. ShowHidePluginArgInput(showPluginArgInput);
  363. RemarksTextBox.Text = server.remarks;
  364. TimeoutTextBox.Text = server.timeout.ToString();
  365. isChange = false;
  366. }
  367. private void ShowHidePluginArgInput(bool show)
  368. {
  369. PluginArgumentsTextBox.Visible = show;
  370. PluginArgumentsLabel.Visible = show;
  371. }
  372. private void LoadServerNameListToUI(Configuration configuration)
  373. {
  374. ServersListBox.Items.Clear();
  375. foreach (Server server in configuration.configs)
  376. {
  377. ServersListBox.Items.Add(server.ToString());
  378. }
  379. }
  380. private void LoadCurrentConfiguration()
  381. {
  382. _modifiedConfiguration = controller.GetConfigurationCopy();
  383. LoadServerNameListToUI(_modifiedConfiguration);
  384. _lastSelectedIndex = _modifiedConfiguration.index;
  385. if (_lastSelectedIndex < 0 || _lastSelectedIndex >= ServersListBox.Items.Count)
  386. {
  387. _lastSelectedIndex = 0;
  388. }
  389. ServersListBox.SelectedIndex = _lastSelectedIndex;
  390. UpdateButtons();
  391. LoadSelectedServerDetails();
  392. ProxyPortTextBox.Text = _modifiedConfiguration.localPort.ToString();
  393. PortableModeCheckBox.Checked = _modifiedConfiguration.portableMode;
  394. ApplyButton.Enabled = false;
  395. }
  396. private bool SaveValidConfiguration()
  397. {
  398. if (!ValidateAndSaveSelectedServerDetails(isSave: true))
  399. {
  400. return false;
  401. }
  402. int localPort = int.Parse(ProxyPortTextBox.Text);
  403. Configuration.CheckLocalPort(localPort);
  404. _modifiedConfiguration.localPort = localPort;
  405. _modifiedConfiguration.portableMode = PortableModeCheckBox.Checked;
  406. controller.SaveServers(_modifiedConfiguration.configs, _modifiedConfiguration.localPort, _modifiedConfiguration.portableMode);
  407. // SelectedIndex remains valid
  408. // We handled this in event handlers, e.g. Add/DeleteButton, SelectedIndexChanged
  409. // and move operations
  410. controller.SelectServerIndex(ServersListBox.SelectedIndex);
  411. return true;
  412. }
  413. private void ConfigForm_KeyDown(object sender, KeyEventArgs e)
  414. {
  415. // Sometimes the users may hit enter key by mistake, and the form will close without saving entries.
  416. if (e.KeyCode == Keys.Enter)
  417. {
  418. SaveValidConfiguration();
  419. }
  420. }
  421. private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e)
  422. {
  423. if (!ServersListBox.CanSelect)
  424. {
  425. return;
  426. }
  427. if (_lastSelectedIndex == ServersListBox.SelectedIndex)
  428. {
  429. // we are moving back to oldSelectedIndex or doing a force move
  430. return;
  431. }
  432. if (!ValidateAndSaveSelectedServerDetails())
  433. {
  434. // why this won't cause stack overflow?
  435. ServersListBox.SelectedIndex = _lastSelectedIndex;
  436. return;
  437. }
  438. if (_lastSelectedIndex >= 0 && _lastSelectedIndex < _modifiedConfiguration.configs.Count)
  439. {
  440. ServersListBox.Items[_lastSelectedIndex] = _modifiedConfiguration.configs[_lastSelectedIndex].ToString();
  441. }
  442. UpdateButtons();
  443. LoadSelectedServerDetails();
  444. _lastSelectedIndex = ServersListBox.SelectedIndex;
  445. }
  446. private void AddButton_Click(object sender, EventArgs e)
  447. {
  448. if (ValidateAndSaveSelectedServerDetails(isSave: true))
  449. {
  450. Configuration.AddDefaultServerOrServer(_modifiedConfiguration);
  451. LoadServerNameListToUI(_modifiedConfiguration);
  452. _lastSelectedIndex = (ServersListBox.SelectedIndex = _modifiedConfiguration.configs.Count - 1);
  453. }
  454. }
  455. private void DuplicateButton_Click(object sender, EventArgs e)
  456. {
  457. if (ValidateAndSaveSelectedServerDetails(isCopy: true))
  458. {
  459. Server currServer = _modifiedConfiguration.configs[_lastSelectedIndex];
  460. Configuration.AddDefaultServerOrServer(_modifiedConfiguration, currServer, _lastSelectedIndex + 1);
  461. LoadServerNameListToUI(_modifiedConfiguration);
  462. _lastSelectedIndex = (ServersListBox.SelectedIndex = (_lastSelectedIndex + 1));
  463. }
  464. }
  465. private void DeleteButton_Click(object sender, EventArgs e)
  466. {
  467. _modifiedConfiguration.configs.RemoveAt(_lastSelectedIndex);
  468. if (_modifiedConfiguration.configs.Count == 0)
  469. {
  470. Configuration.AddDefaultServerOrServer(_modifiedConfiguration);
  471. }
  472. LoadServerNameListToUI(_modifiedConfiguration);
  473. ServersListBox.SelectedIndexChanged -= ServersListBox_SelectedIndexChanged;
  474. _lastSelectedIndex = (ServersListBox.SelectedIndex = (_lastSelectedIndex >= _modifiedConfiguration.configs.Count ? (_modifiedConfiguration.configs.Count - 1) : _lastSelectedIndex));
  475. ServersListBox.SelectedIndexChanged += ServersListBox_SelectedIndexChanged;
  476. LoadSelectedServerDetails();
  477. UpdateButtons();
  478. }
  479. private void UpdateButtons()
  480. {
  481. DeleteButton.Enabled = (ServersListBox.Items.Count > 0);
  482. MoveUpButton.Enabled = (ServersListBox.SelectedIndex > 0);
  483. MoveDownButton.Enabled = (ServersListBox.SelectedIndex < ServersListBox.Items.Count - 1);
  484. }
  485. private void MoveUpButton_Click(object sender, EventArgs e)
  486. {
  487. if (ServersListBox.SelectedIndex > 0)
  488. {
  489. MoveConfigItem(-1); // -1 means move backward
  490. }
  491. }
  492. private void MoveDownButton_Click(object sender, EventArgs e)
  493. {
  494. if (ServersListBox.SelectedIndex < ServersListBox.Items.Count - 1)
  495. {
  496. MoveConfigItem(+1); // +1 means move forward
  497. }
  498. }
  499. private void MoveConfigItem(int step)
  500. {
  501. var server = _modifiedConfiguration.configs[_lastSelectedIndex];
  502. var newIndex = _lastSelectedIndex + step;
  503. _modifiedConfiguration.configs.RemoveAt(_lastSelectedIndex);
  504. _modifiedConfiguration.configs.Insert(newIndex, server);
  505. ServersListBox.BeginUpdate();
  506. LoadServerNameListToUI(_modifiedConfiguration);
  507. _lastSelectedIndex = newIndex;
  508. ServersListBox.SelectedIndex = newIndex;
  509. ServersListBox.EndUpdate();
  510. UpdateButtons();
  511. }
  512. private void OKButton_Click(object sender, EventArgs e)
  513. {
  514. if (SaveValidConfiguration())
  515. {
  516. Close();
  517. }
  518. }
  519. private void CancelButton_Click(object sender, EventArgs e)
  520. {
  521. Close();
  522. }
  523. private void ApplyButton_Click(object sender, EventArgs e)
  524. {
  525. SaveValidConfiguration();
  526. }
  527. private void ConfigForm_Shown(object sender, EventArgs e)
  528. {
  529. IPTextBox.Focus();
  530. }
  531. private void ConfigForm_FormClosed(object sender, FormClosedEventArgs e)
  532. {
  533. controller.ConfigChanged -= Controller_ConfigChanged;
  534. }
  535. private void ShowPasswdCheckBox_CheckedChanged(object sender, EventArgs e)
  536. {
  537. PasswordTextBox.UseSystemPasswordChar = !ShowPasswdCheckBox.Checked;
  538. }
  539. private void UsePluginArgCheckBox_CheckedChanged(object sender, EventArgs e)
  540. {
  541. ShowHidePluginArgInput(NeedPluginArgCheckBox.Checked);
  542. }
  543. }
  544. }