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 16 kB

13 years ago
11 years ago
13 years ago
11 years ago
13 years ago
11 years ago
13 years ago
11 years ago
11 years ago
13 years ago
13 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
13 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4. using Shadowsocks.Controller;
  5. using Shadowsocks.Model;
  6. using Shadowsocks.Properties;
  7. namespace Shadowsocks.View
  8. {
  9. public partial class ConfigForm : Form
  10. {
  11. private ShadowsocksController controller;
  12. // this is a copy of configuration that we are working on
  13. private Configuration _modifiedConfiguration;
  14. private int _lastSelectedIndex = -1;
  15. public ConfigForm(ShadowsocksController controller)
  16. {
  17. this.Font = SystemFonts.MessageBoxFont;
  18. InitializeComponent();
  19. // a dirty hack
  20. this.ServersListBox.Dock = DockStyle.Fill;
  21. this.tableLayoutPanel5.Dock = DockStyle.Fill;
  22. this.PerformLayout();
  23. UpdateTexts();
  24. SetupValueChangedListeners();
  25. this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
  26. this.controller = controller;
  27. controller.ConfigChanged += controller_ConfigChanged;
  28. LoadCurrentConfiguration();
  29. }
  30. private void UpdateTexts()
  31. {
  32. AddButton.Text = I18N.GetString("&Add");
  33. DeleteButton.Text = I18N.GetString("&Delete");
  34. DuplicateButton.Text = I18N.GetString("Dupli&cate");
  35. IPLabel.Text = I18N.GetString("Server Addr");
  36. ServerPortLabel.Text = I18N.GetString("Server Port");
  37. PasswordLabel.Text = I18N.GetString("Password");
  38. ShowPasswdCheckBox.Text = I18N.GetString("Show Password");
  39. EncryptionLabel.Text = I18N.GetString("Encryption");
  40. PluginLabel.Text = I18N.GetString("Plugin Program");
  41. PluginOptionsLabel.Text = I18N.GetString("Plugin Options");
  42. PluginArgumentsLabel.Text = I18N.GetString("Plugin Arguments");
  43. NeedPluginArgCheckBox.Text = I18N.GetString("Need Plugin Argument");
  44. ProxyPortLabel.Text = I18N.GetString("Proxy Port");
  45. PortableModeCheckBox.Text = I18N.GetString("Portable Mode");
  46. toolTip1.SetToolTip(this.PortableModeCheckBox, I18N.GetString("Restart required"));
  47. RemarksLabel.Text = I18N.GetString("Remarks");
  48. TimeoutLabel.Text = I18N.GetString("Timeout(Sec)");
  49. ServerGroupBox.Text = I18N.GetString("Server");
  50. OKButton.Text = I18N.GetString("OK");
  51. MyCancelButton.Text = I18N.GetString("Cancel");
  52. ApplyButton.Text = I18N.GetString("Apply");
  53. MoveUpButton.Text = I18N.GetString("Move &Up");
  54. MoveDownButton.Text = I18N.GetString("Move D&own");
  55. this.Text = I18N.GetString("Edit Servers");
  56. }
  57. private void SetupValueChangedListeners()
  58. {
  59. IPTextBox.TextChanged += ConfigValueChanged;
  60. ProxyPortTextBox.TextChanged += ConfigValueChanged;
  61. PasswordTextBox.TextChanged += ConfigValueChanged;
  62. EncryptionSelect.SelectedIndexChanged += ConfigValueChanged;
  63. PluginTextBox.TextChanged += ConfigValueChanged;
  64. PluginArgumentsTextBox.TextChanged += ConfigValueChanged;
  65. PluginOptionsTextBox.TextChanged += ConfigValueChanged;
  66. RemarksTextBox.TextChanged += ConfigValueChanged;
  67. TimeoutTextBox.TextChanged += ConfigValueChanged;
  68. PortableModeCheckBox.CheckedChanged += ConfigValueChanged;
  69. ServerPortTextBox.TextChanged += ConfigValueChanged;
  70. }
  71. private void controller_ConfigChanged(object sender, EventArgs e)
  72. {
  73. LoadCurrentConfiguration();
  74. }
  75. private void ConfigValueChanged(object sender, EventArgs e)
  76. {
  77. ApplyButton.Enabled = true;
  78. }
  79. private bool ValidateAndSaveSelectedServerDetails()
  80. {
  81. try
  82. {
  83. if (_lastSelectedIndex == -1 || _lastSelectedIndex >= _modifiedConfiguration.configs.Count)
  84. {
  85. return true;
  86. }
  87. Server server = GetServerDetailsFromUI();
  88. if (server == null)
  89. {
  90. return false;
  91. }
  92. Configuration.CheckServer(server);
  93. _modifiedConfiguration.configs[_lastSelectedIndex] = server;
  94. return true;
  95. }
  96. catch (Exception ex)
  97. {
  98. MessageBox.Show(ex.Message);
  99. }
  100. return false;
  101. }
  102. private Server GetServerDetailsFromUI()
  103. {
  104. Server server = new Server();
  105. if (Uri.CheckHostName(server.server = IPTextBox.Text.Trim()) == UriHostNameType.Unknown)
  106. {
  107. MessageBox.Show(I18N.GetString("Invalid server address"));
  108. IPTextBox.Focus();
  109. return null;
  110. }
  111. if (!int.TryParse(ServerPortTextBox.Text, out server.server_port))
  112. {
  113. MessageBox.Show(I18N.GetString("Illegal port number format"));
  114. ServerPortTextBox.Focus();
  115. return null;
  116. }
  117. server.password = PasswordTextBox.Text;
  118. server.method = EncryptionSelect.Text;
  119. server.plugin = PluginTextBox.Text;
  120. server.plugin_opts = PluginOptionsTextBox.Text;
  121. server.plugin_args = PluginArgumentsTextBox.Text;
  122. server.remarks = RemarksTextBox.Text;
  123. if (!int.TryParse(TimeoutTextBox.Text, out server.timeout))
  124. {
  125. MessageBox.Show(I18N.GetString("Illegal timeout format"));
  126. TimeoutTextBox.Focus();
  127. return null;
  128. }
  129. return server;
  130. }
  131. private void LoadSelectedServerDetails()
  132. {
  133. if (ServersListBox.SelectedIndex >= 0 && ServersListBox.SelectedIndex < _modifiedConfiguration.configs.Count)
  134. {
  135. Server server = _modifiedConfiguration.configs[ServersListBox.SelectedIndex];
  136. SetServerDetailsToUI(server);
  137. }
  138. }
  139. private void SetServerDetailsToUI(Server server)
  140. {
  141. IPTextBox.Text = server.server;
  142. ServerPortTextBox.Text = server.server_port.ToString();
  143. PasswordTextBox.Text = server.password;
  144. EncryptionSelect.Text = server.method ?? "aes-256-cfb";
  145. PluginTextBox.Text = server.plugin;
  146. PluginOptionsTextBox.Text = server.plugin_opts;
  147. PluginArgumentsTextBox.Text = server.plugin_args;
  148. bool showPluginArgInput = !string.IsNullOrEmpty(server.plugin_args);
  149. NeedPluginArgCheckBox.Checked = showPluginArgInput;
  150. ShowHidePluginArgInput(showPluginArgInput);
  151. RemarksTextBox.Text = server.remarks;
  152. TimeoutTextBox.Text = server.timeout.ToString();
  153. }
  154. private void ShowHidePluginArgInput(bool show)
  155. {
  156. PluginArgumentsTextBox.Visible = show;
  157. PluginArgumentsLabel.Visible = show;
  158. }
  159. private void LoadServerNameListToUI(Configuration configuration)
  160. {
  161. ServersListBox.Items.Clear();
  162. foreach (Server server in configuration.configs)
  163. {
  164. ServersListBox.Items.Add(server.FriendlyName());
  165. }
  166. }
  167. private void LoadCurrentConfiguration()
  168. {
  169. _modifiedConfiguration = controller.GetConfigurationCopy();
  170. LoadServerNameListToUI(_modifiedConfiguration);
  171. _lastSelectedIndex = _modifiedConfiguration.index;
  172. if (_lastSelectedIndex < 0 || _lastSelectedIndex >= ServersListBox.Items.Count)
  173. {
  174. _lastSelectedIndex = 0;
  175. }
  176. ServersListBox.SelectedIndex = _lastSelectedIndex;
  177. UpdateButtons();
  178. LoadSelectedServerDetails();
  179. ProxyPortTextBox.Text = _modifiedConfiguration.localPort.ToString();
  180. PortableModeCheckBox.Checked = _modifiedConfiguration.portableMode;
  181. ApplyButton.Enabled = false;
  182. }
  183. private bool SaveValidConfiguration()
  184. {
  185. if (!ValidateAndSaveSelectedServerDetails())
  186. {
  187. return false;
  188. }
  189. if (_modifiedConfiguration.configs.Count == 0)
  190. {
  191. MessageBox.Show(I18N.GetString("Please add at least one server"));
  192. return false;
  193. }
  194. int localPort = int.Parse(ProxyPortTextBox.Text);
  195. Configuration.CheckLocalPort(localPort);
  196. _modifiedConfiguration.localPort = localPort;
  197. _modifiedConfiguration.portableMode = PortableModeCheckBox.Checked;
  198. controller.SaveServers(_modifiedConfiguration.configs, _modifiedConfiguration.localPort, _modifiedConfiguration.portableMode);
  199. // SelectedIndex remains valid
  200. // We handled this in event handlers, e.g. Add/DeleteButton, SelectedIndexChanged
  201. // and move operations
  202. controller.SelectServerIndex(ServersListBox.SelectedIndex);
  203. return true;
  204. }
  205. private void ConfigForm_KeyDown(object sender, KeyEventArgs e)
  206. {
  207. // Sometimes the users may hit enter key by mistake, and the form will close without saving entries.
  208. if (e.KeyCode == Keys.Enter)
  209. {
  210. SaveValidConfiguration();
  211. }
  212. }
  213. private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e)
  214. {
  215. if (!ServersListBox.CanSelect)
  216. {
  217. return;
  218. }
  219. if (_lastSelectedIndex == ServersListBox.SelectedIndex)
  220. {
  221. // we are moving back to oldSelectedIndex or doing a force move
  222. return;
  223. }
  224. if (!ValidateAndSaveSelectedServerDetails())
  225. {
  226. // why this won't cause stack overflow?
  227. ServersListBox.SelectedIndex = _lastSelectedIndex;
  228. return;
  229. }
  230. if (_lastSelectedIndex >= 0 && _lastSelectedIndex < _modifiedConfiguration.configs.Count)
  231. {
  232. ServersListBox.Items[_lastSelectedIndex] = _modifiedConfiguration.configs[_lastSelectedIndex].FriendlyName();
  233. }
  234. UpdateButtons();
  235. LoadSelectedServerDetails();
  236. _lastSelectedIndex = ServersListBox.SelectedIndex;
  237. }
  238. private void AddButton_Click(object sender, EventArgs e)
  239. {
  240. if (!ValidateAndSaveSelectedServerDetails())
  241. {
  242. return;
  243. }
  244. Configuration.AddDefaultServerOrServer(_modifiedConfiguration);
  245. LoadServerNameListToUI(_modifiedConfiguration);
  246. ServersListBox.SelectedIndex = _modifiedConfiguration.configs.Count - 1;
  247. _lastSelectedIndex = ServersListBox.SelectedIndex;
  248. }
  249. private void DuplicateButton_Click(object sender, EventArgs e)
  250. {
  251. if (_lastSelectedIndex == -1 || _lastSelectedIndex > _modifiedConfiguration.configs.Count
  252. || !ValidateAndSaveSelectedServerDetails())
  253. {
  254. return;
  255. }
  256. Server currServer = _modifiedConfiguration.configs[_lastSelectedIndex];
  257. var currIndex = _modifiedConfiguration.configs.IndexOf(currServer);
  258. _modifiedConfiguration.configs.Insert(currIndex + 1, currServer);
  259. LoadServerNameListToUI(_modifiedConfiguration);
  260. ServersListBox.SelectedIndex = currIndex + 1;
  261. _lastSelectedIndex = ServersListBox.SelectedIndex;
  262. }
  263. private void DeleteButton_Click(object sender, EventArgs e)
  264. {
  265. _lastSelectedIndex = ServersListBox.SelectedIndex;
  266. if (_lastSelectedIndex >= 0 && _lastSelectedIndex < _modifiedConfiguration.configs.Count)
  267. {
  268. _modifiedConfiguration.configs.RemoveAt(_lastSelectedIndex);
  269. }
  270. if (_modifiedConfiguration.configs.Count == 0)
  271. {
  272. Configuration.AddDefaultServerOrServer(_modifiedConfiguration);
  273. }
  274. if (_lastSelectedIndex >= _modifiedConfiguration.configs.Count)
  275. {
  276. // can be -1
  277. _lastSelectedIndex = _modifiedConfiguration.configs.Count - 1;
  278. }
  279. ServersListBox.SelectedIndex = _lastSelectedIndex;
  280. LoadServerNameListToUI(_modifiedConfiguration);
  281. ServersListBox.SelectedIndex = _lastSelectedIndex;
  282. LoadSelectedServerDetails();
  283. UpdateButtons();
  284. }
  285. private void OKButton_Click(object sender, EventArgs e)
  286. {
  287. if (SaveValidConfiguration())
  288. {
  289. this.Close();
  290. }
  291. }
  292. private void CancelButton_Click(object sender, EventArgs e)
  293. {
  294. this.Close();
  295. }
  296. private void ApplyButton_Click(object sender, EventArgs e)
  297. {
  298. SaveValidConfiguration();
  299. }
  300. private void ConfigForm_Shown(object sender, EventArgs e)
  301. {
  302. IPTextBox.Focus();
  303. }
  304. private void ConfigForm_FormClosed(object sender, FormClosedEventArgs e)
  305. {
  306. controller.ConfigChanged -= controller_ConfigChanged;
  307. }
  308. private void MoveConfigItem(int step)
  309. {
  310. int index = ServersListBox.SelectedIndex;
  311. Server server = _modifiedConfiguration.configs[index];
  312. object item = ServersListBox.Items[index];
  313. _modifiedConfiguration.configs.Remove(server);
  314. _modifiedConfiguration.configs.Insert(index + step, server);
  315. _modifiedConfiguration.index += step;
  316. ServersListBox.BeginUpdate();
  317. ServersListBox.Enabled = false;
  318. _lastSelectedIndex = index + step;
  319. ServersListBox.Items.Remove(item);
  320. ServersListBox.Items.Insert(index + step, item);
  321. ServersListBox.Enabled = true;
  322. ServersListBox.SelectedIndex = index + step;
  323. ServersListBox.EndUpdate();
  324. UpdateButtons();
  325. }
  326. private void UpdateButtons()
  327. {
  328. DeleteButton.Enabled = (ServersListBox.Items.Count > 0);
  329. MoveUpButton.Enabled = (ServersListBox.SelectedIndex > 0);
  330. MoveDownButton.Enabled = (ServersListBox.SelectedIndex < ServersListBox.Items.Count - 1);
  331. }
  332. private void MoveUpButton_Click(object sender, EventArgs e)
  333. {
  334. if (!ValidateAndSaveSelectedServerDetails())
  335. {
  336. return;
  337. }
  338. if (ServersListBox.SelectedIndex > 0)
  339. {
  340. MoveConfigItem(-1); // -1 means move backward
  341. }
  342. }
  343. private void MoveDownButton_Click(object sender, EventArgs e)
  344. {
  345. if (!ValidateAndSaveSelectedServerDetails())
  346. {
  347. return;
  348. }
  349. if (ServersListBox.SelectedIndex < ServersListBox.Items.Count - 1)
  350. {
  351. MoveConfigItem(+1); // +1 means move forward
  352. }
  353. }
  354. private void ShowPasswdCheckBox_CheckedChanged(object sender, EventArgs e)
  355. {
  356. this.PasswordTextBox.UseSystemPasswordChar = !this.ShowPasswdCheckBox.Checked;
  357. }
  358. private void UsePluginArgCheckBox_CheckedChanged(object sender, EventArgs e)
  359. {
  360. ShowHidePluginArgInput(this.NeedPluginArgCheckBox.Checked);
  361. }
  362. }
  363. }