diff --git a/Netch/Forms/AboutForm.cs b/Netch/Forms/AboutForm.cs index 2a5c59b0..abf260df 100644 --- a/Netch/Forms/AboutForm.cs +++ b/Netch/Forms/AboutForm.cs @@ -14,9 +14,7 @@ namespace Netch.Forms private void AboutForm_Load(object sender, EventArgs e) { - Text = i18N.Translate(Text); - ChannelLabel.Text = i18N.Translate(ChannelLabel.Text); - SponsorGroupBox.Text = i18N.Translate(SponsorGroupBox.Text); + i18N.TranslateForm(this); } private void NetchPictureBox_Click(object sender, EventArgs e) diff --git a/Netch/Forms/GlobalBypassIPForm.cs b/Netch/Forms/GlobalBypassIPForm.cs index 2f66e972..a75e450f 100644 --- a/Netch/Forms/GlobalBypassIPForm.cs +++ b/Netch/Forms/GlobalBypassIPForm.cs @@ -14,10 +14,7 @@ namespace Netch.Forms private void GlobalBypassIPForm_Load(object sender, EventArgs e) { - Text = i18N.Translate(Text); - AddButton.Text = i18N.Translate(AddButton.Text); - DeleteButton.Text = i18N.Translate(DeleteButton.Text); - ControlButton.Text = i18N.Translate(ControlButton.Text); + i18N.TranslateForm(this); IPListBox.Items.AddRange(Global.Settings.BypassIPs.ToArray()); diff --git a/Netch/Forms/MainForm.Server_Mode.cs b/Netch/Forms/MainForm.Server_Mode.cs index 88939a66..ce180bd1 100644 --- a/Netch/Forms/MainForm.Server_Mode.cs +++ b/Netch/Forms/MainForm.Server_Mode.cs @@ -166,6 +166,7 @@ namespace Netch.Forms Size = new Size(259, 22), Text = i18N.TranslateFormat("Add [{0}] Server", fullName), }; + _mainFormText.Add(control.Name, new[] {"Add [{0}] Server", fullName}); control.Click += AddServerToolStripMenuItem_Click; ServerToolStripMenuItem.DropDownItems.Add(control); } diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index 51b17ae6..c1293927 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -174,47 +177,82 @@ namespace Netch.Forms Show(); } + private readonly Dictionary _mainFormText = new Dictionary(); + private bool _textRecorded; + private void InitText() { - ServerToolStripMenuItem.Text = i18N.Translate("Server"); - ImportServersFromClipboardToolStripMenuItem.Text = i18N.Translate("Import Servers From Clipboard"); - ModeToolStripMenuItem.Text = i18N.Translate("Mode"); - HelpToolStripMenuItem.Text = i18N.Translate("Help"); - CreateProcessModeToolStripMenuItem.Text = i18N.Translate("Create Process Mode"); - SubscribeToolStripMenuItem.Text = i18N.Translate("Subscribe"); - ManageSubscribeLinksToolStripMenuItem.Text = i18N.Translate("Manage Subscribe Links"); - UpdateServersFromSubscribeLinksToolStripMenuItem.Text = i18N.Translate("Update Servers From Subscribe Links"); - OptionsToolStripMenuItem.Text = i18N.Translate("Options"); - ReloadModesToolStripMenuItem.Text = i18N.Translate("Reload Modes"); - UninstallServiceToolStripMenuItem.Text = i18N.Translate("Uninstall NF Service"); - CleanDNSCacheToolStripMenuItem.Text = i18N.Translate("Clean DNS Cache"); - UpdateACLToolStripMenuItem.Text = i18N.Translate("Update ACL"); - updateACLWithProxyToolStripMenuItem.Text = i18N.Translate("Update ACL with proxy"); - reinstallTapDriverToolStripMenuItem.Text = i18N.Translate("Reinstall TUN/TAP driver"); - CheckForUpdatesToolStripMenuItem.Text = i18N.Translate("Check for updates"); - OpenDirectoryToolStripMenuItem.Text = i18N.Translate("Open Directory"); - AboutToolStripButton.Text = i18N.Translate("About"); - fAQToolStripMenuItem.Text = i18N.Translate("FAQ"); - NewVersionLabel.Text = i18N.Translate("New version available"); - // VersionLabel.Text = i18N.Translate("xxx"); - exitToolStripMenuItem.Text = i18N.Translate("Exit"); - ConfigurationGroupBox.Text = i18N.Translate("Configuration"); - ProfileLabel.Text = i18N.Translate("Profile"); - ModeLabel.Text = i18N.Translate("Mode"); - ServerLabel.Text = i18N.Translate("Server"); - // UsedBandwidthLabel.Text = i18N.Translate("Used: 0 KB"); - // DownloadSpeedLabel.Text = i18N.Translate("↓: 0 KB/s"); - // UploadSpeedLabel.Text = i18N.Translate("↑: 0 KB/s"); - NotifyIcon.Text = i18N.Translate("Netch"); - ShowMainFormToolStripButton.Text = i18N.Translate("Show"); - ExitToolStripButton.Text = i18N.Translate("Exit"); - SettingsButton.Text = i18N.Translate("Settings"); - ProfileGroupBox.Text = i18N.Translate("Profiles"); - // 加载翻译 + #region Record English + + if (!_textRecorded) + { + void RecordText(Component component) + { + try + { + switch (component) + { + case TextBoxBase _: + case ListControl _: + break; + case Control c: + _mainFormText.Add(c.Name, c.Text); + break; + case ToolStripItem c: + _mainFormText.Add(c.Name, c.Text); + break; + } + } + catch (ArgumentException) + { + // ignored + } + } + + Utils.Utils.ComponentIterator(this, RecordText); + Utils.Utils.ComponentIterator(NotifyMenu, RecordText); + _textRecorded = true; + } + + #endregion + + #region Translate + + void TranslateText(Component component) + { + switch (component) + { + case TextBoxBase _: + case ListControl _: + break; + case Control c: + + c.Text = ControlText(c.Name); + break; + case ToolStripItem c: + c.Text = ControlText(c.Name); + break; + } + + string ControlText(string name) + { + var value = _mainFormText[name]; + if (value.Equals(string.Empty)) return string.Empty; + + if (value is object[] values) + return i18N.TranslateFormat(values.First() as string, values.Skip(1).ToArray()); + else + return i18N.Translate(value); + } + } + + Utils.Utils.ComponentIterator(this, TranslateText); + Utils.Utils.ComponentIterator(NotifyMenu, TranslateText); + + #endregion UsedBandwidthLabel.Text = $@"{i18N.Translate("Used", ": ")}0 KB"; State = State; - VersionLabel.Text = UpdateChecker.Version; } @@ -275,10 +313,8 @@ namespace Netch.Forms } Hide(); - var server = Global.Settings.Server[ServerComboBox.SelectedIndex]; Servers.GetUtilByTypeName(server.Type).Edit(server); - InitServer(); Configuration.Save(); Show(); @@ -288,7 +324,6 @@ namespace Netch.Forms { Enabled = false; StatusText(i18N.Translate("Testing")); - try { await Task.Run(TestServer); @@ -382,12 +417,9 @@ namespace Netch.Forms } var index = ServerComboBox.SelectedIndex; - Global.Settings.Server.Remove(ServerComboBox.SelectedItem as Server); InitServer(); - Configuration.Save(); - if (ServerComboBox.Items.Count > 0) { ServerComboBox.SelectedIndex = index != 0 ? index - 1 : index; diff --git a/Netch/Forms/Mode/Process.cs b/Netch/Forms/Mode/Process.cs index 5234d6c3..66d6f7d8 100644 --- a/Netch/Forms/Mode/Process.cs +++ b/Netch/Forms/Mode/Process.cs @@ -110,15 +110,8 @@ namespace Netch.Forms.Mode public void ModeForm_Load(object sender, EventArgs e) { - Text = i18N.Translate(Text); - ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text); - RemarkLabel.Text = i18N.Translate(RemarkLabel.Text); - FilenameLabel.Text = i18N.Translate(FilenameLabel.Text); - UseCustomFilenameBox.Text = i18N.Translate(UseCustomFilenameBox.Text); - AddButton.Text = i18N.Translate(AddButton.Text); - ScanButton.Text = i18N.Translate(ScanButton.Text); - ControlButton.Text = i18N.Translate(ControlButton.Text); - DeleteToolStripMenuItem.Text = i18N.Translate(DeleteToolStripMenuItem.Text); + i18N.TranslateForm(this); + i18N.Translate(contextMenuStrip); } /// diff --git a/Netch/Forms/SettingForm.cs b/Netch/Forms/SettingForm.cs index 7a22e79a..c117e643 100644 --- a/Netch/Forms/SettingForm.cs +++ b/Netch/Forms/SettingForm.cs @@ -79,35 +79,7 @@ namespace Netch.Forms private void InitText() { - Text = i18N.Translate(Text); - - PortGroupBox.Text = i18N.Translate(PortGroupBox.Text); - AllowDevicesCheckBox.Text = i18N.Translate(AllowDevicesCheckBox.Text); - TUNTAPAddressLabel.Text = i18N.Translate(TUNTAPAddressLabel.Text); - TUNTAPNetmaskLabel.Text = i18N.Translate(TUNTAPNetmaskLabel.Text); - TUNTAPGatewayLabel.Text = i18N.Translate(TUNTAPGatewayLabel.Text); - UseCustomDNSCheckBox.Text = i18N.Translate(UseCustomDNSCheckBox.Text); - ProxyDNSCheckBox.Text = i18N.Translate(ProxyDNSCheckBox.Text); - UseFakeDNSCheckBox.Text = i18N.Translate(UseFakeDNSCheckBox.Text); - GlobalBypassIPsButton.Text = i18N.Translate(GlobalBypassIPsButton.Text); - ControlButton.Text = i18N.Translate(ControlButton.Text); - BootShadowsocksFromDLLCheckBox.Text = i18N.Translate(BootShadowsocksFromDLLCheckBox.Text); - ModifySystemDNSCheckBox.Text = i18N.Translate(ModifySystemDNSCheckBox.Text); - CheckBetaUpdateCheckBox.Text = i18N.Translate(CheckBetaUpdateCheckBox.Text); - BehaviorGroupBox.Text = i18N.Translate(BehaviorGroupBox.Text); - ExitWhenClosedCheckBox.Text = i18N.Translate(ExitWhenClosedCheckBox.Text); - StopWhenExitedCheckBox.Text = i18N.Translate(StopWhenExitedCheckBox.Text); - StartWhenOpenedCheckBox.Text = i18N.Translate(StartWhenOpenedCheckBox.Text); - MinimizeWhenStartedCheckBox.Text = i18N.Translate(MinimizeWhenStartedCheckBox.Text); - RunAtStartupCheckBox.Text = i18N.Translate(RunAtStartupCheckBox.Text); - UpdateSubscribeatWhenOpenedCheckBox.Text = i18N.Translate(UpdateSubscribeatWhenOpenedCheckBox.Text); - CheckUpdateWhenOpenedCheckBox.Text = i18N.Translate(CheckUpdateWhenOpenedCheckBox.Text); - ProfileCountLabel.Text = i18N.Translate(ProfileCountLabel.Text); - TcpingAtStartedCheckBox.Text = i18N.Translate(TcpingAtStartedCheckBox.Text); - DetectionIntervalLabel.Text = i18N.Translate(DetectionIntervalLabel.Text); - STUNServerLabel.Text = i18N.Translate(STUNServerLabel.Text); - AclLabel.Text = i18N.Translate(AclLabel.Text); - LanguageLabel.Text = i18N.Translate(LanguageLabel.Text); + i18N.TranslateForm(this); } private void InitSTUN() diff --git a/Netch/Forms/SubscribeForm.cs b/Netch/Forms/SubscribeForm.cs index 35a921f2..ae41f96b 100644 --- a/Netch/Forms/SubscribeForm.cs +++ b/Netch/Forms/SubscribeForm.cs @@ -32,16 +32,8 @@ namespace Netch.Forms private void SubscribeForm_Load(object sender, EventArgs e) { - Text = i18N.Translate(Text); - RemarkColumnHeader.Text = i18N.Translate(RemarkColumnHeader.Text); - LinkColumnHeader.Text = i18N.Translate(LinkColumnHeader.Text); - UseSelectedServerCheckBox.Text = i18N.Translate(UseSelectedServerCheckBox.Text); - DeleteToolStripMenuItem.Text = i18N.Translate(DeleteToolStripMenuItem.Text); - CopyLinkToolStripMenuItem.Text = i18N.Translate(CopyLinkToolStripMenuItem.Text); - RemarkLabel.Text = i18N.Translate(RemarkLabel.Text); - LinkLabel.Text = i18N.Translate(LinkLabel.Text); - ClearButton.Text = i18N.Translate(ClearButton.Text); - AddButton.Text = i18N.Translate(AddButton.Text); + i18N.TranslateForm(this); + i18N.TranslateForm(pContextMenuStrip); ResetEditingGroup(); diff --git a/Netch/Resources/zh-CN b/Netch/Resources/zh-CN index 00127ba7..2514d6e4 100644 --- a/Netch/Resources/zh-CN +++ b/Netch/Resources/zh-CN @@ -34,11 +34,6 @@ "Import Servers From Clipboard": "从剪贴板导入服务器", "Import servers error!": "未找到可导入的链接!", "Add [{0}] Server": "添加 [{0}] 服务器", - "Add [Socks5] Server": "添加 [Socks5] 服务器", - "Add [Shadowsocks] Server": "添加 [Shadowsocks] 服务器", - "Add [ShadowsocksR] Server": "添加 [ShadowsocksR] 服务器", - "Add [VMess] Server": "添加 [VMess] 服务器", - "Add [Trojan] Server": "添加 [Trojan] 服务器", "Netch is now minimized to the notification bar, double click this icon to restore.": "Netch 已最小化至通知栏,双击此图标恢复窗口。", "New version available": "发现新版本", "Already latest version": "已经是最新版本", diff --git a/Netch/ServerEx/Shadowsocks/Form/ShadowsocksForm.cs b/Netch/ServerEx/Shadowsocks/Form/ShadowsocksForm.cs index d32ee87e..06c50bfb 100644 --- a/Netch/ServerEx/Shadowsocks/Form/ShadowsocksForm.cs +++ b/Netch/ServerEx/Shadowsocks/Form/ShadowsocksForm.cs @@ -17,21 +17,10 @@ namespace Netch.ServerEx.Shadowsocks.Form private void Shadowsocks_Load(object sender, EventArgs e) { - #region InitText - - ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text); - RemarkLabel.Text = i18N.Translate(RemarkLabel.Text); - AddressLabel.Text = i18N.Translate(AddressLabel.Text); - PasswordLabel.Text = i18N.Translate(PasswordLabel.Text); - EncryptMethodLabel.Text = i18N.Translate(EncryptMethodLabel.Text); - PluginLabel.Text = i18N.Translate(PluginLabel.Text); - PluginOptionsLabel.Text = i18N.Translate(PluginOptionsLabel.Text); - ControlButton.Text = i18N.Translate(ControlButton.Text); + i18N.TranslateForm(this); EncryptMethodComboBox.Items.AddRange(SSGlobal.EncryptMethods.ToArray()); - - #endregion - + RemarkTextBox.Text = _server.Remark; AddressTextBox.Text = _server.Hostname; PortTextBox.Text = _server.Port.ToString(); diff --git a/Netch/ServerEx/ShadowsocksR/Form/ShadowsocksRForm.cs b/Netch/ServerEx/ShadowsocksR/Form/ShadowsocksRForm.cs index bcf623a0..c79c6332 100644 --- a/Netch/ServerEx/ShadowsocksR/Form/ShadowsocksRForm.cs +++ b/Netch/ServerEx/ShadowsocksR/Form/ShadowsocksRForm.cs @@ -17,26 +17,12 @@ namespace Netch.ServerEx.ShadowsocksR.Form private void ShadowsocksR_Load(object sender, EventArgs e) { - #region InitText - - ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text); - RemarkLabel.Text = i18N.Translate(RemarkLabel.Text); - AddressLabel.Text = i18N.Translate(AddressLabel.Text); - PasswordLabel.Text = i18N.Translate(PasswordLabel.Text); - EncryptMethodLabel.Text = i18N.Translate(EncryptMethodLabel.Text); - ProtocolLabel.Text = i18N.Translate(ProtocolLabel.Text); - ProtocolParamLabel.Text = i18N.Translate(ProtocolParamLabel.Text); - OBFSLabel.Text = i18N.Translate(OBFSLabel.Text); - OBFSParamLabel.Text = i18N.Translate(OBFSParamLabel.Text); - ControlButton.Text = i18N.Translate(ControlButton.Text); + i18N.TranslateForm(this); EncryptMethodComboBox.Items.AddRange(SSRGlobal.EncryptMethods.ToArray()); - ProtocolComboBox.Items.AddRange(SSRGlobal.Protocols.ToArray()); OBFSComboBox.Items.AddRange(SSRGlobal.OBFSs.ToArray()); - #endregion - RemarkTextBox.Text = _server.Remark; AddressTextBox.Text = _server.Hostname; PortTextBox.Text = _server.Port.ToString(); diff --git a/Netch/ServerEx/Socks5/Form/Socks5Form.cs b/Netch/ServerEx/Socks5/Form/Socks5Form.cs index f01548e8..d9943c8b 100644 --- a/Netch/ServerEx/Socks5/Form/Socks5Form.cs +++ b/Netch/ServerEx/Socks5/Form/Socks5Form.cs @@ -16,16 +16,7 @@ namespace Netch.ServerEx.Socks5.Form private void Socks5_Load(object sender, EventArgs e) { - #region InitText - - ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text); - RemarkLabel.Text = i18N.Translate(RemarkLabel.Text); - AddressLabel.Text = i18N.Translate(AddressLabel.Text); - UsernameLabel.Text = i18N.Translate(UsernameLabel.Text); - PasswordLabel.Text = i18N.Translate(PasswordLabel.Text); - ControlButton.Text = i18N.Translate(ControlButton.Text); - - #endregion + i18N.TranslateForm(this); RemarkTextBox.Text = _server.Remark; AddressTextBox.Text = _server.Hostname; diff --git a/Netch/ServerEx/Trojan/Form/TrojanForm.cs b/Netch/ServerEx/Trojan/Form/TrojanForm.cs index f3d2489c..b9021318 100644 --- a/Netch/ServerEx/Trojan/Form/TrojanForm.cs +++ b/Netch/ServerEx/Trojan/Form/TrojanForm.cs @@ -18,11 +18,7 @@ namespace Netch.ServerEx.Trojan.Form private void TrojanForm_Load(object sender, EventArgs e) { - ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text); - RemarkLabel.Text = i18N.Translate(RemarkLabel.Text); - AddressLabel.Text = i18N.Translate(AddressLabel.Text); - PasswordLabel.Text = i18N.Translate(PasswordLabel.Text); - ControlButton.Text = i18N.Translate(ControlButton.Text); + i18N.TranslateForm(this); RemarkTextBox.Text = _server.Remark; AddressTextBox.Text = _server.Hostname; diff --git a/Netch/ServerEx/VMess/Form/VMessForm.cs b/Netch/ServerEx/VMess/Form/VMessForm.cs index a28ed9ef..d1ff8fd6 100644 --- a/Netch/ServerEx/VMess/Form/VMessForm.cs +++ b/Netch/ServerEx/VMess/Form/VMessForm.cs @@ -23,30 +23,13 @@ namespace Netch.ServerEx.VMess.Form private void VMess_Load(object sender, EventArgs e) { - #region InitText - - ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text); - RemarkLabel.Text = i18N.Translate(RemarkLabel.Text); - AddressLabel.Text = i18N.Translate(AddressLabel.Text); - UserIDLabel.Text = i18N.Translate(UserIDLabel.Text); - AlterIDLabel.Text = i18N.Translate(AlterIDLabel.Text); - EncryptMethodLabel.Text = i18N.Translate(EncryptMethodLabel.Text); - TransferProtocolLabel.Text = i18N.Translate(TransferProtocolLabel.Text); - FakeTypeLabel.Text = i18N.Translate(FakeTypeLabel.Text); - HostLabel.Text = i18N.Translate(HostLabel.Text); - PathLabel.Text = i18N.Translate(PathLabel.Text); - QUICSecurityLabel.Text = i18N.Translate(QUICSecurityLabel.Text); - QUICSecretLabel.Text = i18N.Translate(QUICSecretLabel.Text); - TLSSecureCheckBox.Text = i18N.Translate(TLSSecureCheckBox.Text); - UseMuxCheckBox.Text = i18N.Translate(UseMuxCheckBox.Text); - ControlButton.Text = i18N.Translate(ControlButton.Text); + i18N.TranslateForm(this); EncryptMethodComboBox.Items.AddRange(VMessGlobal.EncryptMethods.ToArray()); TransferProtocolComboBox.Items.AddRange(VMessGlobal.TransferProtocols.ToArray()); FakeTypeComboBox.Items.AddRange(VMessGlobal.FakeTypes.ToArray()); QUICSecurityComboBox.Items.AddRange(VMessGlobal.QUIC.ToArray()); - #endregion RemarkTextBox.Text = _server.Remark; AddressTextBox.Text = _server.Hostname; diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Utils.cs index 38e678e8..a6a1e94b 100644 --- a/Netch/Utils/Utils.cs +++ b/Netch/Utils/Utils.cs @@ -205,5 +205,46 @@ namespace Netch.Utils } } } + + public static void ComponentIterator(Component component, Action func) + { + func.Invoke(component); + switch (component) + { + case ToolStripMenuItem toolStripMenuItem: + // Iterator Menu strip sub item + foreach (var item in toolStripMenuItem.DropDownItems.Cast()) + { + ComponentIterator(item, func); + } + + break; + case MenuStrip menuStrip: + // Menu Strip + foreach (var item in menuStrip.Items.Cast()) + { + ComponentIterator(item, func); + } + + break; + case ContextMenuStrip contextMenuStrip: + foreach (var item in contextMenuStrip.Items.Cast()) + { + ComponentIterator(item, func); + } + + break; + case Control control: + foreach (var c in control.Controls.Cast()) + { + ComponentIterator(c, func); + } + + if (control.ContextMenuStrip != null) + ComponentIterator(control.ContextMenuStrip, func); + + break; + } + } } } \ No newline at end of file diff --git a/Netch/Utils/i18N.cs b/Netch/Utils/i18N.cs index e96eebf0..03a25be9 100644 --- a/Netch/Utils/i18N.cs +++ b/Netch/Utils/i18N.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Text; +using System.Windows.Forms; using Netch.Properties; using Newtonsoft.Json; @@ -104,5 +105,24 @@ namespace Netch.Utils translateFile.AddRange(Directory.GetFiles("i18n", "*").Select(fileName => fileName.Substring(5))); return translateFile; } + + public static void TranslateForm(Control c) + { + Utils.ComponentIterator(c, component => + { + switch (component) + { + case TextBoxBase _: + case ListControl _: + break; + case Control c: + c.Text = Translate(c.Text); + break; + case ToolStripItem c: + c.Text = Translate(c.Text); + break; + } + }); + } } } \ No newline at end of file