using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Diagnostics; using Microsoft.Win32; using Shadowsocks.Controller; using Shadowsocks.Model; using Shadowsocks.Properties; namespace Shadowsocks.View { public partial class ConfigForm : Form { private ShadowsocksController controller; // this is a copy of configuration that we are working on private Configuration _modifiedConfiguration; private int _oldSelectedIndex = -1; private ContextMenuStrip ServersListBoxContextMenu = null; public ConfigForm(ShadowsocksController controller) { this.Font = System.Drawing.SystemFonts.MessageBoxFont; InitializeComponent(); // a dirty hack this.ServersListBox.Dock = System.Windows.Forms.DockStyle.Fill; this.PerformLayout(); UpdateTexts(); this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); this.controller = controller; controller.ConfigChanged += controller_ConfigChanged; LoadCurrentConfiguration(); } private void ServersListBoxContextMenu_Opening(object sender, CancelEventArgs e) { //clear the menu and add custom items string contextItemText = I18N.GetString("Select"); ServersListBoxContextMenu.Items.Clear(); ToolStripItem item = new ToolStripMenuItem(); item.Name = string.Format("{0}", ServersListBox.SelectedIndex.ToString()); item.Text = string.Format("{0} - {1}", contextItemText, ServersListBox.SelectedItem.ToString()); ServersListBoxContextMenu.Items.Add(item); ServersListBoxContextMenu.ItemClicked += new ToolStripItemClickedEventHandler(ServersListBoxContextMenu_ItemClicked); } void ServersListBoxContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { ToolStripItem item = e.ClickedItem; controller.SelectServerIndex(int.Parse(item.Name)); } private void ServersListBox_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { //select the item under the mouse pointer ServersListBox.SelectedIndex = ServersListBox.IndexFromPoint(e.Location); if (ServersListBox.SelectedIndex != -1) { ServersListBoxContextMenu.Show(); } } } private void UpdateTexts() { AddButton.Text = I18N.GetString("&Add"); DeleteButton.Text = I18N.GetString("&Delete"); IPLabel.Text = I18N.GetString("Server IP"); ServerPortLabel.Text = I18N.GetString("Server Port"); PasswordLabel.Text = I18N.GetString("Password"); EncryptionLabel.Text = I18N.GetString("Encryption"); ProxyPortLabel.Text = I18N.GetString("Proxy Port"); RemarksLabel.Text = I18N.GetString("Remarks"); ServerGroupBox.Text = I18N.GetString("Server"); OKButton.Text = I18N.GetString("OK"); MyCancelButton.Text = I18N.GetString("Cancel"); URIButton.Text = I18N.GetString("URI Parse"); this.Text = I18N.GetString("Edit Servers"); } private void controller_ConfigChanged(object sender, EventArgs e) { LoadCurrentConfiguration(); } private void ShowWindow() { this.Opacity = 1; this.Show(); IPTextBox.Focus(); } private bool SaveOldSelectedServer() { try { if (_oldSelectedIndex == -1 || _oldSelectedIndex >= _modifiedConfiguration.configs.Count) { return true; } Server server = new Server { server = IPTextBox.Text, server_port = int.Parse(ServerPortTextBox.Text), password = PasswordTextBox.Text, local_port = int.Parse(ProxyPortTextBox.Text), method = EncryptionSelect.Text, remarks = RemarksTextBox.Text }; Configuration.CheckServer(server); _modifiedConfiguration.configs[_oldSelectedIndex] = server; return true; } catch (FormatException) { MessageBox.Show(I18N.GetString("Illegal port number format")); } catch (Exception ex) { MessageBox.Show(ex.Message); } return false; } private void LoadSelectedServer() { if (ServersListBox.SelectedIndex >= 0 && ServersListBox.SelectedIndex < _modifiedConfiguration.configs.Count) { Server server = _modifiedConfiguration.configs[ServersListBox.SelectedIndex]; IPTextBox.Text = server.server; ServerPortTextBox.Text = server.server_port.ToString(); PasswordTextBox.Text = server.password; ProxyPortTextBox.Text = server.local_port.ToString(); EncryptionSelect.Text = server.method ?? "aes-256-cfb"; RemarksTextBox.Text = server.remarks; ServerGroupBox.Visible = true; //IPTextBox.Focus(); } else { ServerGroupBox.Visible = false; } } private void LoadConfiguration(Configuration configuration) { ServersListBox.Items.Clear(); foreach (Server server in _modifiedConfiguration.configs) { ServersListBox.Items.Add(server.FriendlyName()); } } private void LoadCurrentConfiguration() { _modifiedConfiguration = controller.GetConfiguration(); LoadConfiguration(_modifiedConfiguration); _oldSelectedIndex = _modifiedConfiguration.index; ServersListBox.SelectedIndex = _modifiedConfiguration.index; LoadSelectedServer(); } private void ConfigForm_Load(object sender, EventArgs e) { ServersListBoxContextMenu = new ContextMenuStrip(); ServersListBoxContextMenu.Opening += new CancelEventHandler(ServersListBoxContextMenu_Opening); ServersListBox.ContextMenuStrip = ServersListBoxContextMenu; } private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e) { if (_oldSelectedIndex == ServersListBox.SelectedIndex) { // we are moving back to oldSelectedIndex or doing a force move return; } if (!SaveOldSelectedServer()) { // why this won't cause stack overflow? ServersListBox.SelectedIndex = _oldSelectedIndex; return; } LoadSelectedServer(); _oldSelectedIndex = ServersListBox.SelectedIndex; } private void AddButton_Click(object sender, EventArgs e) { if (!SaveOldSelectedServer()) { return; } Server server = Configuration.GetDefaultServer(); _modifiedConfiguration.configs.Add(server); LoadConfiguration(_modifiedConfiguration); ServersListBox.SelectedIndex = _modifiedConfiguration.configs.Count - 1; _oldSelectedIndex = ServersListBox.SelectedIndex; } private void DeleteButton_Click(object sender, EventArgs e) { _oldSelectedIndex = ServersListBox.SelectedIndex; if (_oldSelectedIndex >= 0 && _oldSelectedIndex < _modifiedConfiguration.configs.Count) { _modifiedConfiguration.configs.RemoveAt(_oldSelectedIndex); } if (_oldSelectedIndex >= _modifiedConfiguration.configs.Count) { // can be -1 _oldSelectedIndex = _modifiedConfiguration.configs.Count - 1; } ServersListBox.SelectedIndex = _oldSelectedIndex; LoadConfiguration(_modifiedConfiguration); ServersListBox.SelectedIndex = _oldSelectedIndex; LoadSelectedServer(); } private void OKButton_Click(object sender, EventArgs e) { if (!SaveOldSelectedServer()) { return; } if (_modifiedConfiguration.configs.Count == 0) { MessageBox.Show(I18N.GetString("Please add at least one server")); return; } controller.SaveServers(_modifiedConfiguration.configs); //this.Close(); } private void CancelButton_Click(object sender, EventArgs e) { this.Close(); } private void ConfigForm_Shown(object sender, EventArgs e) { IPTextBox.Focus(); } private void ConfigForm_FormClosed(object sender, FormClosedEventArgs e) { controller.ConfigChanged -= controller_ConfigChanged; } private void URIButton_Click(object sender, EventArgs e) { URIParseForm uriParseForm = new URIParseForm(); uriParseForm.ShowDialog(this); if(uriParseForm.Parsed) { if (!SaveOldSelectedServer()) { return; } _modifiedConfiguration.configs.Add(uriParseForm.server); LoadConfiguration(_modifiedConfiguration); ServersListBox.SelectedIndex = _modifiedConfiguration.configs.Count - 1; _oldSelectedIndex = ServersListBox.SelectedIndex; } } } }