- Infrastructure: use one HttpClient instance throughout the lifecycle - Version update: rewrite the update service and add update prompt window - Server sharing: add copy link button - Dependencies: add ReactiveUI.Events.WPF, ReactiveUI.Fody, ReactiveUI.Validation, WPFLocalizeExtension, MdXamltags/4.3.0.0
| @@ -35,8 +35,6 @@ namespace Shadowsocks.Controller | |||
| private static readonly string DATABASE_PATH = Utils.GetTempPath("dlc.dat"); | |||
| private static HttpClientHandler httpClientHandler; | |||
| private static HttpClient httpClient; | |||
| private static readonly string GEOSITE_URL = "https://github.com/v2fly/domain-list-community/raw/release/dlc.dat"; | |||
| private static readonly string GEOSITE_SHA256SUM_URL = "https://github.com/v2fly/domain-list-community/raw/release/dlc.dat.sha256sum"; | |||
| private static byte[] geositeDB; | |||
| @@ -82,7 +80,8 @@ namespace Shadowsocks.Controller | |||
| SHA256 mySHA256 = SHA256.Create(); | |||
| var config = Program.MainController.GetCurrentConfiguration(); | |||
| bool blacklist = config.geositePreferDirect; | |||
| var httpClient = Program.MainController.GetHttpClient(); | |||
| if (!string.IsNullOrWhiteSpace(config.geositeUrl)) | |||
| { | |||
| logger.Info("Found custom Geosite URL in config file"); | |||
| @@ -90,22 +89,6 @@ namespace Shadowsocks.Controller | |||
| } | |||
| logger.Info($"Checking Geosite from {geositeUrl}"); | |||
| // use System.Net.Http.HttpClient to download GeoSite db. | |||
| // NASTY workaround: new HttpClient every update | |||
| // because we can't change proxy on existing socketsHttpHandler instance | |||
| httpClientHandler = new HttpClientHandler(); | |||
| httpClient = new HttpClient(httpClientHandler); | |||
| if (!string.IsNullOrWhiteSpace(config.userAgentString)) | |||
| httpClient.DefaultRequestHeaders.Add("User-Agent", config.userAgentString); | |||
| if (config.enabled) | |||
| { | |||
| httpClientHandler.Proxy = new WebProxy( | |||
| config.isIPv6Enabled | |||
| ? $"[{IPAddress.IPv6Loopback}]" | |||
| : IPAddress.Loopback.ToString(), | |||
| config.localPort); | |||
| } | |||
| try | |||
| { | |||
| // download checksum first | |||
| @@ -154,19 +137,6 @@ namespace Shadowsocks.Controller | |||
| { | |||
| Error?.Invoke(null, new ErrorEventArgs(ex)); | |||
| } | |||
| finally | |||
| { | |||
| if (httpClientHandler != null) | |||
| { | |||
| httpClientHandler.Dispose(); | |||
| httpClientHandler = null; | |||
| } | |||
| if (httpClient != null) | |||
| { | |||
| httpClient.Dispose(); | |||
| httpClient = null; | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| @@ -11,28 +11,15 @@ namespace Shadowsocks.Controller.Service | |||
| { | |||
| public class OnlineConfigResolver | |||
| { | |||
| public static async Task<List<Server>> GetOnline(string url, string userAgentString, IWebProxy proxy = null) | |||
| public static async Task<List<Server>> GetOnline(string url) | |||
| { | |||
| var httpClientHandler = new HttpClientHandler() | |||
| { | |||
| Proxy = proxy | |||
| }; | |||
| var httpClient = new HttpClient(httpClientHandler) | |||
| { | |||
| Timeout = TimeSpan.FromSeconds(15) | |||
| }; | |||
| if (!string.IsNullOrWhiteSpace(userAgentString)) | |||
| httpClient.DefaultRequestHeaders.Add("User-Agent", userAgentString); | |||
| var httpClient = Program.MainController.GetHttpClient(); | |||
| string server_json = await httpClient.GetStringAsync(url); | |||
| var servers = server_json.GetServers(); | |||
| foreach (var server in servers) | |||
| { | |||
| server.group = url; | |||
| } | |||
| return servers.ToList(); | |||
| } | |||
| } | |||
| @@ -191,7 +191,7 @@ namespace Shadowsocks.Controller | |||
| public DateTime lastActivity; | |||
| private readonly ShadowsocksController _controller; | |||
| private readonly ProxyConfig _config; | |||
| private readonly ForwardProxyConfig _config; | |||
| private readonly Socket _connection; | |||
| private IEncryptor _encryptor; | |||
| @@ -665,10 +665,10 @@ namespace Shadowsocks.Controller | |||
| { | |||
| switch (_config.proxyType) | |||
| { | |||
| case ProxyConfig.PROXY_SOCKS5: | |||
| case ForwardProxyConfig.PROXY_SOCKS5: | |||
| remote = new Socks5Proxy(); | |||
| break; | |||
| case ProxyConfig.PROXY_HTTP: | |||
| case ForwardProxyConfig.PROXY_HTTP: | |||
| remote = new HttpProxy(); | |||
| break; | |||
| default: | |||
| @@ -1,254 +1,174 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.IO; | |||
| using System.Net; | |||
| using System.Net.Http; | |||
| using System.Text.RegularExpressions; | |||
| using System.Threading.Tasks; | |||
| using System.Windows; | |||
| using Newtonsoft.Json.Linq; | |||
| using NLog; | |||
| using Shadowsocks.Localization; | |||
| using Shadowsocks.Model; | |||
| using Shadowsocks.Util; | |||
| using Shadowsocks.Views; | |||
| namespace Shadowsocks.Controller | |||
| { | |||
| public class UpdateChecker | |||
| { | |||
| private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
| private readonly Logger logger; | |||
| private readonly HttpClient httpClient; | |||
| // https://developer.github.com/v3/repos/releases/ | |||
| private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases"; | |||
| private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36"; | |||
| private Configuration config; | |||
| public bool NewVersionFound; | |||
| public string LatestVersionNumber; | |||
| public string LatestVersionSuffix; | |||
| public string LatestVersionName; | |||
| public string LatestVersionURL; | |||
| public string LatestVersionLocalName; | |||
| public event EventHandler CheckUpdateCompleted; | |||
| private Configuration _config; | |||
| private Window versionUpdatePromptWindow; | |||
| private JToken _releaseObject; | |||
| public const string Version = "4.2.1.0"; | |||
| private class CheckUpdateTimer : System.Timers.Timer | |||
| { | |||
| public Configuration config; | |||
| public string NewReleaseVersion { get; private set; } | |||
| public string NewReleaseZipFilename { get; private set; } | |||
| public CheckUpdateTimer(int p) : base(p) | |||
| { | |||
| } | |||
| } | |||
| public event EventHandler CheckUpdateCompleted; | |||
| public void CheckUpdate(Configuration config, int delay) | |||
| { | |||
| CheckUpdateTimer timer = new CheckUpdateTimer(delay); | |||
| timer.AutoReset = false; | |||
| timer.Elapsed += Timer_Elapsed; | |||
| timer.config = config; | |||
| timer.Enabled = true; | |||
| } | |||
| public const string Version = "4.2.1.0"; | |||
| private readonly Version _version; | |||
| private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) | |||
| public UpdateChecker() | |||
| { | |||
| CheckUpdateTimer timer = (CheckUpdateTimer)sender; | |||
| Configuration config = timer.config; | |||
| timer.Elapsed -= Timer_Elapsed; | |||
| timer.Enabled = false; | |||
| timer.Dispose(); | |||
| CheckUpdate(config); | |||
| logger = LogManager.GetCurrentClassLogger(); | |||
| httpClient = Program.MainController.GetHttpClient(); | |||
| _version = new Version(Version); | |||
| _config = Program.MainController.GetCurrentConfiguration(); | |||
| } | |||
| public void CheckUpdate(Configuration config) | |||
| /// <summary> | |||
| /// Checks for updates and asks the user if updates are found. | |||
| /// </summary> | |||
| /// <param name="millisecondsDelay">A delay in milliseconds before checking.</param> | |||
| /// <returns></returns> | |||
| public async Task CheckForVersionUpdate(int millisecondsDelay = 0) | |||
| { | |||
| this.config = config; | |||
| // delay | |||
| logger.Info($"Waiting for {millisecondsDelay}ms before checking for version update."); | |||
| await Task.Delay(millisecondsDelay); | |||
| // start | |||
| logger.Info($"Checking for version update."); | |||
| try | |||
| { | |||
| logger.Info("Checking updates..."); | |||
| WebClient http = CreateWebClient(); | |||
| http.DownloadStringCompleted += http_DownloadStringCompleted; | |||
| http.DownloadStringAsync(new Uri(UpdateURL)); | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| logger.LogUsefulException(ex); | |||
| } | |||
| } | |||
| private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) | |||
| { | |||
| try | |||
| { | |||
| string response = e.Result; | |||
| JArray result = JArray.Parse(response); | |||
| List<Asset> asserts = new List<Asset>(); | |||
| if (result != null) | |||
| // list releases via API | |||
| var releasesListJsonString = await httpClient.GetStringAsync(UpdateURL); | |||
| // parse | |||
| var releasesJArray = JArray.Parse(releasesListJsonString); | |||
| foreach (var releaseObject in releasesJArray) | |||
| { | |||
| foreach (JObject release in result) | |||
| var releaseTagName = (string)releaseObject["tag_name"]; | |||
| var releaseVersion = new Version(releaseTagName); | |||
| if (releaseTagName == _config.skippedUpdateVersion) // finished checking | |||
| break; | |||
| if (releaseVersion.CompareTo(_version) > 0 && | |||
| (!(bool)releaseObject["prerelease"] || _config.checkPreRelease && (bool)releaseObject["prerelease"])) // selected | |||
| { | |||
| var isPreRelease = (bool)release["prerelease"]; | |||
| if (isPreRelease && !config.checkPreRelease) | |||
| { | |||
| continue; | |||
| } | |||
| foreach (JObject asset in (JArray)release["assets"]) | |||
| { | |||
| Asset ass = Asset.ParseAsset(asset); | |||
| if (ass != null) | |||
| { | |||
| ass.prerelease = isPreRelease; | |||
| if (ass.IsNewVersion(Version, config.checkPreRelease)) | |||
| { | |||
| asserts.Add(ass); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| if (asserts.Count != 0) | |||
| { | |||
| SortByVersions(asserts); | |||
| Asset asset = asserts[asserts.Count - 1]; | |||
| NewVersionFound = true; | |||
| LatestVersionURL = asset.browser_download_url; | |||
| LatestVersionNumber = asset.version; | |||
| LatestVersionName = asset.name; | |||
| LatestVersionSuffix = asset.suffix == null ? "" : $"-{asset.suffix}"; | |||
| startDownload(); | |||
| } | |||
| else | |||
| { | |||
| logger.Info("No update is available"); | |||
| if (CheckUpdateCompleted != null) | |||
| { | |||
| CheckUpdateCompleted(this, new EventArgs()); | |||
| logger.Info($"Found new version {releaseTagName}."); | |||
| _releaseObject = releaseObject; | |||
| NewReleaseVersion = releaseTagName; | |||
| AskToUpdate(releaseObject); | |||
| return; | |||
| } | |||
| } | |||
| logger.Info($"No new versions found."); | |||
| CheckUpdateCompleted?.Invoke(this, new EventArgs()); | |||
| } | |||
| catch (Exception ex) | |||
| catch (Exception e) | |||
| { | |||
| logger.LogUsefulException(ex); | |||
| logger.LogUsefulException(e); | |||
| } | |||
| } | |||
| private void startDownload() | |||
| /// <summary> | |||
| /// Opens a window to show the update's information. | |||
| /// </summary> | |||
| /// <param name="releaseObject">The update release object.</param> | |||
| private void AskToUpdate(JToken releaseObject) | |||
| { | |||
| try | |||
| if (versionUpdatePromptWindow == null) | |||
| { | |||
| LatestVersionLocalName = Utils.GetTempPath(LatestVersionName); | |||
| WebClient http = CreateWebClient(); | |||
| http.DownloadFileCompleted += Http_DownloadFileCompleted; | |||
| http.DownloadFileAsync(new Uri(LatestVersionURL), LatestVersionLocalName); | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| logger.LogUsefulException(ex); | |||
| versionUpdatePromptWindow = new Window() | |||
| { | |||
| Title = LocalizationProvider.GetLocalizedValue<string>("VersionUpdate"), | |||
| Height = 480, | |||
| Width = 640, | |||
| MinHeight = 480, | |||
| MinWidth = 640, | |||
| Content = new VersionUpdatePromptView(releaseObject) | |||
| }; | |||
| versionUpdatePromptWindow.Closed += VersionUpdatePromptWindow_Closed; | |||
| versionUpdatePromptWindow.Show(); | |||
| } | |||
| versionUpdatePromptWindow.Activate(); | |||
| } | |||
| private void Http_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) | |||
| private void VersionUpdatePromptWindow_Closed(object sender, EventArgs e) | |||
| { | |||
| versionUpdatePromptWindow = null; | |||
| } | |||
| /// <summary> | |||
| /// Downloads the selected update and notifies the user. | |||
| /// </summary> | |||
| /// <returns></returns> | |||
| public async Task DoUpdate() | |||
| { | |||
| try | |||
| { | |||
| if (e.Error != null) | |||
| var assets = (JArray)_releaseObject["assets"]; | |||
| // download all assets | |||
| foreach (JObject asset in assets) | |||
| { | |||
| logger.LogUsefulException(e.Error); | |||
| return; | |||
| } | |||
| logger.Info($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}"); | |||
| if (CheckUpdateCompleted != null) | |||
| { | |||
| CheckUpdateCompleted(this, new EventArgs()); | |||
| var filename = (string)asset["name"]; | |||
| var browser_download_url = (string)asset["browser_download_url"]; | |||
| var response = await httpClient.GetAsync(browser_download_url); | |||
| using (var downloadedFileStream = File.Create(Utils.GetTempPath(filename))) | |||
| await response.Content.CopyToAsync(downloadedFileStream); | |||
| logger.Info($"Downloaded {filename}."); | |||
| // store .zip filename | |||
| if (filename.EndsWith(".zip")) | |||
| NewReleaseZipFilename = filename; | |||
| } | |||
| logger.Info("Finished downloading."); | |||
| // notify user | |||
| CloseVersionUpdatePromptWindow(); | |||
| Process.Start("explorer.exe", $"/select, \"{Utils.GetTempPath(NewReleaseZipFilename)}\""); | |||
| } | |||
| catch (Exception ex) | |||
| catch (Exception e) | |||
| { | |||
| logger.LogUsefulException(ex); | |||
| logger.LogUsefulException(e); | |||
| } | |||
| } | |||
| private WebClient CreateWebClient() | |||
| /// <summary> | |||
| /// Saves the skipped update version. | |||
| /// </summary> | |||
| public void SkipUpdate() | |||
| { | |||
| WebClient http = new WebClient(); | |||
| http.Headers.Add("User-Agent", UserAgent); | |||
| http.Proxy = new WebProxy(config.LocalHost, config.localPort); | |||
| return http; | |||
| var version = (string)_releaseObject["tag_name"] ?? ""; | |||
| _config.skippedUpdateVersion = version; | |||
| Program.MainController.SaveSkippedUpdateVerion(version); | |||
| logger.Info($"The update {version} has been skipped and will be ignored next time."); | |||
| CloseVersionUpdatePromptWindow(); | |||
| } | |||
| private void SortByVersions(List<Asset> asserts) | |||
| /// <summary> | |||
| /// Closes the update prompt window. | |||
| /// </summary> | |||
| public void CloseVersionUpdatePromptWindow() | |||
| { | |||
| asserts.Sort(); | |||
| } | |||
| public class Asset : IComparable<Asset> | |||
| { | |||
| public bool prerelease; | |||
| public string name; | |||
| public string version; | |||
| public string browser_download_url; | |||
| public string suffix; | |||
| public static Asset ParseAsset(JObject assertJObject) | |||
| { | |||
| var name = (string)assertJObject["name"]; | |||
| Match match = Regex.Match(name, @"^Shadowsocks-(?<version>\d+(?:\.\d+)*)(?:|-(?<suffix>.+))\.\w+$", | |||
| RegexOptions.IgnoreCase); | |||
| if (match.Success) | |||
| { | |||
| string version = match.Groups["version"].Value; | |||
| var asset = new Asset | |||
| { | |||
| browser_download_url = (string)assertJObject["browser_download_url"], | |||
| name = name, | |||
| version = version | |||
| }; | |||
| if (match.Groups["suffix"].Success) | |||
| { | |||
| asset.suffix = match.Groups["suffix"].Value; | |||
| } | |||
| return asset; | |||
| } | |||
| return null; | |||
| } | |||
| public bool IsNewVersion(string currentVersion, bool checkPreRelease) | |||
| { | |||
| if (prerelease && !checkPreRelease) | |||
| { | |||
| return false; | |||
| } | |||
| if (version == null) | |||
| { | |||
| return false; | |||
| } | |||
| var cmp = CompareVersion(version, currentVersion); | |||
| return cmp > 0; | |||
| } | |||
| public static int CompareVersion(string l, string r) | |||
| { | |||
| var ls = l.Split('.'); | |||
| var rs = r.Split('.'); | |||
| for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++) | |||
| { | |||
| int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0; | |||
| int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0; | |||
| if (lp != rp) | |||
| { | |||
| return lp - rp; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| public int CompareTo(Asset other) | |||
| if (versionUpdatePromptWindow != null) | |||
| { | |||
| return CompareVersion(version, other.version); | |||
| versionUpdatePromptWindow.Close(); | |||
| versionUpdatePromptWindow = null; | |||
| } | |||
| } | |||
| } | |||
| @@ -4,6 +4,7 @@ using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Net; | |||
| using System.Net.Http; | |||
| using System.Net.Sockets; | |||
| using System.Text; | |||
| using System.Threading; | |||
| @@ -20,7 +21,8 @@ namespace Shadowsocks.Controller | |||
| { | |||
| public class ShadowsocksController | |||
| { | |||
| private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
| private readonly Logger logger; | |||
| private readonly HttpClient httpClient; | |||
| // controller: | |||
| // handle user actions | |||
| @@ -91,6 +93,8 @@ namespace Shadowsocks.Controller | |||
| public ShadowsocksController() | |||
| { | |||
| logger = LogManager.GetCurrentClassLogger(); | |||
| httpClient = new HttpClient(); | |||
| _config = Configuration.Load(); | |||
| Configuration.Process(ref _config); | |||
| StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); | |||
| @@ -168,6 +172,19 @@ namespace Shadowsocks.Controller | |||
| NLogConfig.LoadConfiguration(); | |||
| // set User-Agent for httpClient | |||
| try | |||
| { | |||
| if (!string.IsNullOrWhiteSpace(_config.userAgentString)) | |||
| httpClient.DefaultRequestHeaders.Add("User-Agent", _config.userAgentString); | |||
| } | |||
| catch | |||
| { | |||
| // reset userAgent to default and reapply | |||
| Configuration.ResetUserAgent(_config); | |||
| httpClient.DefaultRequestHeaders.Add("User-Agent", _config.userAgentString); | |||
| } | |||
| StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); | |||
| privoxyRunner = privoxyRunner ?? new PrivoxyRunner(); | |||
| @@ -250,6 +267,7 @@ namespace Shadowsocks.Controller | |||
| Errored?.Invoke(this, new ErrorEventArgs(e)); | |||
| } | |||
| public HttpClient GetHttpClient() => httpClient; | |||
| public Server GetCurrentServer() => _config.GetCurrentServer(); | |||
| public Configuration GetCurrentConfiguration() => _config; | |||
| @@ -310,7 +328,7 @@ namespace Shadowsocks.Controller | |||
| EnableGlobalChanged?.Invoke(this, new EventArgs()); | |||
| } | |||
| public void SaveProxy(ProxyConfig proxyConfig) | |||
| public void SaveProxy(ForwardProxyConfig proxyConfig) | |||
| { | |||
| _config.proxy = proxyConfig; | |||
| SaveConfig(_config); | |||
| @@ -478,6 +496,12 @@ namespace Shadowsocks.Controller | |||
| ConfigChanged?.Invoke(this, new EventArgs()); | |||
| } | |||
| public void SaveSkippedUpdateVerion(string version) | |||
| { | |||
| _config.skippedUpdateVersion = version; | |||
| Configuration.Save(_config); | |||
| } | |||
| public void SaveLogViewerConfig(LogViewerConfig newConfig) | |||
| { | |||
| _config.logViewer = newConfig; | |||
| @@ -497,7 +521,7 @@ namespace Shadowsocks.Controller | |||
| #endregion | |||
| #region Statistic | |||
| #region Statistics | |||
| public void SelectStrategy(string strategyID) | |||
| { | |||
| @@ -672,7 +696,7 @@ namespace Shadowsocks.Controller | |||
| public async Task<int> UpdateOnlineConfigInternal(string url) | |||
| { | |||
| var onlineServer = await OnlineConfigResolver.GetOnline(url, _config.userAgentString, _config.WebProxy); | |||
| var onlineServer = await OnlineConfigResolver.GetOnline(url); | |||
| _config.configs = Configuration.SortByOnlineConfig( | |||
| _config.configs | |||
| .Where(c => c.group != url) | |||
| @@ -699,10 +723,10 @@ namespace Shadowsocks.Controller | |||
| return true; | |||
| } | |||
| public async Task<int> UpdateAllOnlineConfig() | |||
| public async Task<List<string>> UpdateAllOnlineConfig() | |||
| { | |||
| var selected = GetCurrentServer(); | |||
| int failCount = 0; | |||
| var failedUrls = new List<string>(); | |||
| foreach (var url in _config.onlineConfigSource) | |||
| { | |||
| try | |||
| @@ -712,18 +736,18 @@ namespace Shadowsocks.Controller | |||
| catch (Exception e) | |||
| { | |||
| logger.LogUsefulException(e); | |||
| failCount++; | |||
| failedUrls.Add(url); | |||
| } | |||
| } | |||
| _config.index = _config.configs.IndexOf(selected); | |||
| SaveConfig(_config); | |||
| return failCount; | |||
| return failedUrls; | |||
| } | |||
| public void SaveOnlineConfigSource(IEnumerable<string> vs) | |||
| public void SaveOnlineConfigSource(List<string> sources) | |||
| { | |||
| _config.onlineConfigSource = vs.ToList(); | |||
| _config.onlineConfigSource = sources; | |||
| SaveConfig(_config); | |||
| } | |||
| @@ -81,13 +81,6 @@ Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O),아래로 (&O),Desc | |||
| deprecated,Устаревшее,不推荐,不推薦,非推奨,더 이상 사용되지 않음,Obsolète | |||
| "Encryption method {0} not exist, will replace with {1}",,加密方法{0}不存在,将使用{1}代替,,暗号化方式{0}が存在しません,{1}に置換します,{0} 암호화 방식이 존재하지 않으므로 {1}로 대체될 것입니다.,"Méthode de chiffrement {0} n'existe pas, sera remplacée par {1}" | |||
| ,,,,,, | |||
| # Online Config Form,,,,,, | |||
| ,,,,,, | |||
| Online config,,在线配置,線上配置,,, | |||
| Online config URL,,在线配置链接,線上配置鏈接,,, | |||
| &Update,,更新,更新,,, | |||
| U&pdate All,,全部更新,全部更新,,, | |||
| ,,,,,, | |||
| #Statistics Config,,,,,, | |||
| ,,,,,, | |||
| Enable Statistics,Включить сбор статистики,启用统计,,統計を有効にする,통계 활성화,Activer statistiques | |||
| @@ -118,18 +111,6 @@ Chart Mode,График,图表模式,,図表モード,차트 모드,Mode graphiq | |||
| 24h,24ч,24小时,,24時間,24시간,24h | |||
| all,За все время,全部,,すべて,전체,tout | |||
| ,,,,,, | |||
| # Proxy Form,,,,,, | |||
| ,,,,,, | |||
| Edit Proxy,Редактирование прокси,代理设置,編輯 Proxy,プロキシの編集,프록시 수정,Modifier le proxy | |||
| Use Proxy,Использовать прокси,使用代理,使用 Proxy,プロキシを使用する,프록시 사용,Utiliser un proxy | |||
| Proxy Type,Тип прокси,代理类型,Proxy 類型,プロキシタイプ,프록시 종류,Type de proxy | |||
| Proxy Addr,Адрес прокси,代理地址,Proxy 位址,プロキシアドレス,프록시 주소,Adresse de proxy | |||
| Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート,프록시 포트,Port de proxy | |||
| "If server has a plugin, proxy will not be used","Если сервер использует плагины, прокси НЕ будет использоваться",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは使用されません,서버에 플러그인이 설치 되어 있는 경우 프록시를 사용할 수 없습니다.,"Si le serveur a un plugin, le proxy ne sera pas utilisé" | |||
| Use Auth,Требуется авторизация,使用认证,使用認證,認証を使用する,서버 인증 사용,Utiliser l'authentification | |||
| User Name,Пользователь,用户名,認證用戶,ユーザ名,사용자 이름,Nom d'utilisateur | |||
| Auth Pwd,Пароль,认证密码,認證口令,パスワード,비밀번호,Mot de passe d'authentification | |||
| ,,,,,, | |||
| # Log Form,,,,,, | |||
| ,,,,,, | |||
| &File,Файл,文件(&F),檔案 (&F),ファイル (&F),파일 (&F),Fichier | |||
| @@ -155,17 +136,6 @@ Edit Online PAC URL,Изменение URL удаленного PAC,编辑在线 | |||
| Edit Online PAC URL...,Редактировать URL удаленного PAC…,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集...,온라인 프록시 자동 구성 URL 수정…,Modifier l'URL du PAC en ligne ... | |||
| Please input PAC Url,Введите URL адрес для PAC-файла,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい,프록시 자동 구성 URL을 입력하세요,Veuillez saisir l'URL PAC | |||
| ,,,,,, | |||
| # HotkeySettings Form,,,,,, | |||
| ,,,,,, | |||
| Switch system proxy,ВКЛ/ВЫКЛ системный прокси-сервер,切换系统代理状态,切換系統 Proxy 狀態,システム プロキシの状態を切り替える,시스템 프록시 전환,Changer l'état de proxy système | |||
| Switch system proxy mode,Переключение режима прокси-сервера,切换系统代理模式,切換系統 Proxy 模式,プロキシモードを切り替える,시스템 프록시 모드 전환,Changer le mode de proxy système | |||
| Allow Clients from LAN,Общий доступ к подключению,切换局域网共享,切換區域網路共用,LAN からのアクセスの許可を切り替える,LAN으로부터 클라이언트 허용,Autoriser les clients du LAN | |||
| Show Logs...,Просмотр журналов,显示日志,顯示記錄檔,ログの表示,로그 보기…,Afficher les journaux | |||
| Switch to previous server,Переключить на пред. сервер,切换上个服务器,切換上一個伺服器,前のサーバーに切り替える,이전 서버로 전환,Passer au serveur précédent | |||
| Switch to next server,Переключить на след. сервер,切换下个服务器,切換下一個伺服器,次のサーバーに切り替える,다음 서버로 전환,Passer au serveur suivant | |||
| Reg All,Применить все,注册全部快捷键,註冊所有快速鍵,全部登録する,모두 등록,Enregistrer tout | |||
| Reg Hotkeys At Startup,Применять при запуске программы,启动时注册快捷键,啟動時註冊快速鍵,起動時にホットキーを登録する,시스템 시작 시 단축키 등록,Enregistrer tout au démarrage | |||
| ,,,,,, | |||
| # Messages,,,,,, | |||
| ,,,,,, | |||
| Shadowsocks Error: {0},Ошибка Shadowsocks: {0},Shadowsocks 错误: {0},Shadowsocks 錯誤: {0},Shadowsocks エラー: {0},Shadowsocks 오류: {0},Erreur shadowsocks: {0} | |||
| @@ -178,9 +148,7 @@ Server IP can not be blank,IP-адрес сервера не может быть | |||
| Password can not be blank,Пароль не может быть пустым,密码不能为空,密碼不能為空,パスワードが指定されていません。,비밀번호는 비어있으면 안됩니다.,Le mot de passe ne peut pas être vide | |||
| Port out of range,Порт выходит за допустимый диапазон,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。,올바른 포트 범위가 아닙니다.,Port hors de portée | |||
| Port can't be 8123,Адрес порта 8123 не может быть использован,端口不能为 8123,連接埠號碼不能為 8123,8123 番以外のポート番号を指定して下さい。,8123번 포트는 사용할 수 없습니다.,Le port ne peut pas être 8123 | |||
| Shadowsocks {0} Update Found,Обнаружена новая версия Shadowsocks: {0},Shadowsocks {0} 更新,Shadowsocks {0} 更新,Shadowsocks バージョン {0} は利用できます。,Shadowsocks {0} 업데이트가 있습니다.,Shadowsocks {0} Mise à jour trouvée | |||
| No update is available,Обновлений не обнаружено,没有可用的更新,沒有可用的更新,お使いのバージョンは最新です。,사용 가능한 업데이트가 없습니다.,Aucune mise à jour n'est disponible | |||
| Click here to update,Нажмите сюда для обновления,点击这里升级,點按此處升級,クリックしてアップデートします。,여기를 클릭하여 업데이트,Cliquez ici pour mettre à jour | |||
| Shadowsocks is here,Shadowsocks находится здесь,Shadowsocks 在这里,Shadowsocks 在這裡,Shadowsocks はここです。,Shadowsocks는 여기에 있습니다,Veuillez trouver Shadowsocks ici | |||
| You can turn on/off Shadowsocks in the context menu,Вы можете управлять Shadowsocks из контекстного меню,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。,프로그램 메뉴에서 Shadowsocks를 끄고 켤 수 있습니다.,Vous pouvez activer / désactiver Shadowsocks dans le menu contextuel | |||
| System Proxy Enabled,Системный прокси включен,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。,시스템 프록시가 활성화되었습니다.,Proxy système activé | |||
| @@ -219,5 +187,3 @@ Whether to discard unconfigured servers,Внесенные изменения б | |||
| ,,,,タイムアウト値のフォーマットが無効なため、オートセーブできません。変更を破棄しますか,, | |||
| "Error occured when process proxy setting, do you want reset current setting and retry?",Произошла ошибка при обработке настроек. Хотите сбросить текущие настройки и попробовать снова?,处理代理设置时发生错误,是否重置当前代理设置并重试?,,プロキシ設定の処理にエラーが発生しました、現在のプロキシ設定をリセットし、再試行してもいいですか,프록시 설정을 처리하는데에 오류가 발생했습니다. 현재 설정을 폐기하고 다시 시도하시겠습니까?,Une erreur s'est produite lors du processus de configuration du proxy. Voulez-vous réinitialiser le paramètre actuel et réessayer? | |||
| "Unrecoverable proxy setting error occured, see log for detail","Произошла серьезная ошибка, подробности можно узнать в журналах",发生不可恢复的代理设置错误,查看日志以取得详情,,プロキシ設定に回復不能なエラーが発生しました、ログで詳細をご確認ください,복구 불가능한 프록시 설정 오류가 발생했습니다. 자세한 정보는 로그를 참조하세요.,"Une erreur de paramètre de proxy irrécupérable s'est produite, consultez le journal pour plus de détails" | |||
| Auth user can not be blank,Пользователь не может быть пустым,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。,인증 정보의 사용자 이름은 비어있을 수 없습니다.,L'utilisateur d'authentification ne peut pas être vide | |||
| Auth pwd can not be blank,Пароль не может быть пустым,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。,인증 정보의 비밀번호는 비어있을 수 없습니다.,Le mot de passe d'authentification ne peut pas être vide | |||
| @@ -2,4 +2,5 @@ | |||
| <Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> | |||
| <Caseless StringComparison="Ordinal" /> | |||
| <Costura /> | |||
| <ReactiveUI /> | |||
| </Weavers> | |||
| @@ -4,6 +4,7 @@ | |||
| <xs:element name="Weavers"> | |||
| <xs:complexType> | |||
| <xs:all> | |||
| <xs:element name="ReactiveUI" minOccurs="0" maxOccurs="1" type="xs:anyType" /> | |||
| <xs:element name="Costura" minOccurs="0" maxOccurs="1"> | |||
| <xs:complexType> | |||
| <xs:all> | |||
| @@ -0,0 +1,13 @@ | |||
| using System.Reflection; | |||
| using WPFLocalizeExtension.Extensions; | |||
| namespace Shadowsocks.Localization | |||
| { | |||
| public static class LocalizationProvider | |||
| { | |||
| public static T GetLocalizedValue<T>(string key) | |||
| { | |||
| return LocExtension.GetLocalizedValue<T>(Assembly.GetCallingAssembly().GetName().Name + ":Strings:" + key); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,432 @@ | |||
| //------------------------------------------------------------------------------ | |||
| // <auto-generated> | |||
| // This code was generated by a tool. | |||
| // Runtime Version:4.0.30319.42000 | |||
| // | |||
| // Changes to this file may cause incorrect behavior and will be lost if | |||
| // the code is regenerated. | |||
| // </auto-generated> | |||
| //------------------------------------------------------------------------------ | |||
| namespace Shadowsocks.Localization { | |||
| using System; | |||
| /// <summary> | |||
| /// A strongly-typed resource class, for looking up localized strings, etc. | |||
| /// </summary> | |||
| // This class was auto-generated by the StronglyTypedResourceBuilder | |||
| // class via a tool like ResGen or Visual Studio. | |||
| // To add or remove a member, edit your .ResX file then rerun ResGen | |||
| // with the /str option, or rebuild your VS project. | |||
| [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] | |||
| [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] | |||
| [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | |||
| internal class Strings { | |||
| private static global::System.Resources.ResourceManager resourceMan; | |||
| private static global::System.Globalization.CultureInfo resourceCulture; | |||
| [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] | |||
| internal Strings() { | |||
| } | |||
| /// <summary> | |||
| /// Returns the cached ResourceManager instance used by this class. | |||
| /// </summary> | |||
| [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |||
| internal static global::System.Resources.ResourceManager ResourceManager { | |||
| get { | |||
| if (object.ReferenceEquals(resourceMan, null)) { | |||
| global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Shadowsocks.Localization.Strings", typeof(Strings).Assembly); | |||
| resourceMan = temp; | |||
| } | |||
| return resourceMan; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Overrides the current thread's CurrentUICulture property for all | |||
| /// resource lookups using this strongly typed resource class. | |||
| /// </summary> | |||
| [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |||
| internal static global::System.Globalization.CultureInfo Culture { | |||
| get { | |||
| return resourceCulture; | |||
| } | |||
| set { | |||
| resourceCulture = value; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Add. | |||
| /// </summary> | |||
| internal static string addButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("addButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Address. | |||
| /// </summary> | |||
| internal static string Address { | |||
| get { | |||
| return ResourceManager.GetString("Address", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Allow clients from LAN. | |||
| /// </summary> | |||
| internal static string AllowClientsFromLAN { | |||
| get { | |||
| return ResourceManager.GetString("AllowClientsFromLAN", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Cancel. | |||
| /// </summary> | |||
| internal static string cancelButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("cancelButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Copy. | |||
| /// </summary> | |||
| internal static string Copy { | |||
| get { | |||
| return ResourceManager.GetString("Copy", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Copy link. | |||
| /// </summary> | |||
| internal static string copyLinkButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("copyLinkButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Credentials (optional). | |||
| /// </summary> | |||
| internal static string CredentialsOptional { | |||
| get { | |||
| return ResourceManager.GetString("CredentialsOptional", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Details. | |||
| /// </summary> | |||
| internal static string Details { | |||
| get { | |||
| return ResourceManager.GetString("Details", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Forward Proxy. | |||
| /// </summary> | |||
| internal static string ForwardProxy { | |||
| get { | |||
| return ResourceManager.GetString("ForwardProxy", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Hotkeys. | |||
| /// </summary> | |||
| internal static string Hotkeys { | |||
| get { | |||
| return ResourceManager.GetString("Hotkeys", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to HTTP. | |||
| /// </summary> | |||
| internal static string HTTP { | |||
| get { | |||
| return ResourceManager.GetString("HTTP", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to No proxy. | |||
| /// </summary> | |||
| internal static string NoProxy { | |||
| get { | |||
| return ResourceManager.GetString("NoProxy", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Not now. | |||
| /// </summary> | |||
| internal static string notNowButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("notNowButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _OK. | |||
| /// </summary> | |||
| internal static string okButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("okButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Online Configuration Delivery. | |||
| /// </summary> | |||
| internal static string OnlineConfigDelivery { | |||
| get { | |||
| return ResourceManager.GetString("OnlineConfigDelivery", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Open logs window. | |||
| /// </summary> | |||
| internal static string OpenLogsWindow { | |||
| get { | |||
| return ResourceManager.GetString("OpenLogsWindow", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Password. | |||
| /// </summary> | |||
| internal static string Password { | |||
| get { | |||
| return ResourceManager.GetString("Password", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Port. | |||
| /// </summary> | |||
| internal static string Port { | |||
| get { | |||
| return ResourceManager.GetString("Port", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Register all. | |||
| /// </summary> | |||
| internal static string registerAllButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("registerAllButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Register hotkeys at startup. | |||
| /// </summary> | |||
| internal static string RegisterHotkeysAtStartup { | |||
| get { | |||
| return ResourceManager.GetString("RegisterHotkeysAtStartup", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Remove. | |||
| /// </summary> | |||
| internal static string removeButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("removeButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Save. | |||
| /// </summary> | |||
| internal static string saveButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("saveButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Server Sharing. | |||
| /// </summary> | |||
| internal static string ServerSharing { | |||
| get { | |||
| return ResourceManager.GetString("ServerSharing", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to The following sources failed to update:\n\n. | |||
| /// </summary> | |||
| internal static string sip008UpdateAllFailure { | |||
| get { | |||
| return ResourceManager.GetString("sip008UpdateAllFailure", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Successfully updated all sources!. | |||
| /// </summary> | |||
| internal static string sip008UpdateAllSuccess { | |||
| get { | |||
| return ResourceManager.GetString("sip008UpdateAllSuccess", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Update failed. See the logs for more information.. | |||
| /// </summary> | |||
| internal static string sip008UpdateFailure { | |||
| get { | |||
| return ResourceManager.GetString("sip008UpdateFailure", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Successfully updated the selected source!. | |||
| /// </summary> | |||
| internal static string sip008UpdateSuccess { | |||
| get { | |||
| return ResourceManager.GetString("sip008UpdateSuccess", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Skip version. | |||
| /// </summary> | |||
| internal static string skipVersionButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("skipVersionButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to SOCKS5. | |||
| /// </summary> | |||
| internal static string SOCKS5 { | |||
| get { | |||
| return ResourceManager.GetString("SOCKS5", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Switch to next server. | |||
| /// </summary> | |||
| internal static string SwitchToNextServer { | |||
| get { | |||
| return ResourceManager.GetString("SwitchToNextServer", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Switch to previous server. | |||
| /// </summary> | |||
| internal static string SwitchToPreviousServer { | |||
| get { | |||
| return ResourceManager.GetString("SwitchToPreviousServer", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Timeout. | |||
| /// </summary> | |||
| internal static string Timeout { | |||
| get { | |||
| return ResourceManager.GetString("Timeout", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Toggle proxy mode. | |||
| /// </summary> | |||
| internal static string ToggleProxyMode { | |||
| get { | |||
| return ResourceManager.GetString("ToggleProxyMode", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Toggle system proxy. | |||
| /// </summary> | |||
| internal static string ToggleSystemProxy { | |||
| get { | |||
| return ResourceManager.GetString("ToggleSystemProxy", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Type. | |||
| /// </summary> | |||
| internal static string Type { | |||
| get { | |||
| return ResourceManager.GetString("Type", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Update all. | |||
| /// </summary> | |||
| internal static string updateAllButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("updateAllButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to _Update. | |||
| /// </summary> | |||
| internal static string updateButton_Content { | |||
| get { | |||
| return ResourceManager.GetString("updateButton_Content", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Please read the release notes carefully. Then decide whether to update.. | |||
| /// </summary> | |||
| internal static string updatePromptBody { | |||
| get { | |||
| return ResourceManager.GetString("updatePromptBody", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to An update is available.. | |||
| /// </summary> | |||
| internal static string updatePromptTitle { | |||
| get { | |||
| return ResourceManager.GetString("updatePromptTitle", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to Username. | |||
| /// </summary> | |||
| internal static string Username { | |||
| get { | |||
| return ResourceManager.GetString("Username", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Looks up a localized string similar to VersionUpdate. | |||
| /// </summary> | |||
| internal static string VersionUpdate { | |||
| get { | |||
| return ResourceManager.GetString("VersionUpdate", resourceCulture); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,120 +1,183 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <data name="Password" xml:space="preserve"> | |||
| <value>Mot de passe</value> | |||
| </data> | |||
| <data name="Port" xml:space="preserve"> | |||
| <value>Port</value> | |||
| </data> | |||
| <data name="Type" xml:space="preserve"> | |||
| <value>Type</value> | |||
| </data> | |||
| <data name="Address" xml:space="preserve"> | |||
| <value>adresse</value> | |||
| </data> | |||
| <data name="Timeout" xml:space="preserve"> | |||
| <value>Délai d'attente</value> | |||
| </data> | |||
| <data name="cancelButton_Content" xml:space="preserve"> | |||
| <value>Annuler</value> | |||
| </data> | |||
| <data name="okButton_Content" xml:space="preserve"> | |||
| <value>OK</value> | |||
| </data> | |||
| <data name="ToggleSystemProxy" xml:space="preserve"> | |||
| <value>Changer l'état de proxy système</value> | |||
| </data> | |||
| <data name="ToggleProxyMode" xml:space="preserve"> | |||
| <value>Changer le mode de proxy système</value> | |||
| </data> | |||
| <data name="AllowClientsFromLAN" xml:space="preserve"> | |||
| <value>Autoriser les clients du LAN</value> | |||
| </data> | |||
| <data name="OpenLogsWindow" xml:space="preserve"> | |||
| <value>Afficher les journaux</value> | |||
| </data> | |||
| <data name="SwitchToPreviousServer" xml:space="preserve"> | |||
| <value>Passer au serveur précédent</value> | |||
| </data> | |||
| <data name="SwitchToNextServer" xml:space="preserve"> | |||
| <value>Passer au serveur suivant</value> | |||
| </data> | |||
| <data name="RegisterHotkeysAtStartup" xml:space="preserve"> | |||
| <value>Enregistrer tout</value> | |||
| </data> | |||
| <data name="registerAllButton_Content" xml:space="preserve"> | |||
| <value>Enregistrer tout au démarrage</value> | |||
| </data> | |||
| <data name="addButton_Content" xml:space="preserve"> | |||
| <value>Ajouter</value> | |||
| </data> | |||
| <data name="skipVersionButton_Content" xml:space="preserve"> | |||
| <value>sauter la version</value> | |||
| </data> | |||
| <data name="copyLinkButton_Content" xml:space="preserve"> | |||
| <value>Copier le lien</value> | |||
| </data> | |||
| <data name="removeButton_Content" xml:space="preserve"> | |||
| <value>retirer</value> | |||
| </data> | |||
| <data name="updateButton_Content" xml:space="preserve"> | |||
| <value>mise à jour</value> | |||
| </data> | |||
| <data name="Copy" xml:space="preserve"> | |||
| <value>copie</value> | |||
| </data> | |||
| </root> | |||
| @@ -1,183 +1,180 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <metadata name="flowLayoutPanel1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>False</value> | |||
| </metadata> | |||
| <metadata name="flowLayoutPanel1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="tableLayoutPanel1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="RegHotkeysAtStartupLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="SwitchSystemProxyLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="SwitchProxyModeLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="SwitchAllowLanLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="ShowLogsLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="ServerMoveUpLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="ServerMoveDownLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="SwitchSystemProxyTextBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="SwitchProxyModeTextBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="SwitchAllowLanTextBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="ShowLogsTextBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="ServerMoveUpTextBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="ServerMoveDownTextBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="RegHotkeysAtStartupCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="btnOK.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="btnCancel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="btnRegisterAll.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |||
| <value>True</value> | |||
| </metadata> | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <data name="Password" xml:space="preserve"> | |||
| <value>パスワード</value> | |||
| </data> | |||
| <data name="Type" xml:space="preserve"> | |||
| <value>タイプ</value> | |||
| </data> | |||
| <data name="Address" xml:space="preserve"> | |||
| <value>アドレス</value> | |||
| </data> | |||
| <data name="Port" xml:space="preserve"> | |||
| <value>ポート</value> | |||
| </data> | |||
| <data name="Timeout" xml:space="preserve"> | |||
| <value>タイムアウト</value> | |||
| </data> | |||
| <data name="cancelButton_Content" xml:space="preserve"> | |||
| <value>キャンセル</value> | |||
| </data> | |||
| <data name="okButton_Content" xml:space="preserve"> | |||
| <value>OK</value> | |||
| </data> | |||
| <data name="ToggleSystemProxy" xml:space="preserve"> | |||
| <value>システム プロキシの状態を切り替える</value> | |||
| </data> | |||
| <data name="ToggleProxyMode" xml:space="preserve"> | |||
| <value>プロキシモードを切り替える</value> | |||
| </data> | |||
| <data name="AllowClientsFromLAN" xml:space="preserve"> | |||
| <value>LAN からのアクセスの許可を切り替える</value> | |||
| </data> | |||
| <data name="OpenLogsWindow" xml:space="preserve"> | |||
| <value>ログの表示</value> | |||
| </data> | |||
| <data name="SwitchToPreviousServer" xml:space="preserve"> | |||
| <value>前のサーバーに切り替える</value> | |||
| </data> | |||
| <data name="SwitchToNextServer" xml:space="preserve"> | |||
| <value>次のサーバーに切り替える</value> | |||
| </data> | |||
| <data name="RegisterHotkeysAtStartup" xml:space="preserve"> | |||
| <value>全部登録する</value> | |||
| </data> | |||
| <data name="registerAllButton_Content" xml:space="preserve"> | |||
| <value>起動時にホットキーを登録する</value> | |||
| </data> | |||
| <data name="addButton_Content" xml:space="preserve"> | |||
| <value>新規</value> | |||
| </data> | |||
| <data name="skipVersionButton_Content" xml:space="preserve"> | |||
| <value>バージョンをスキップ</value> | |||
| </data> | |||
| <data name="copyLinkButton_Content" xml:space="preserve"> | |||
| <value>リンクをコピーする</value> | |||
| </data> | |||
| <data name="updateButton_Content" xml:space="preserve"> | |||
| <value>更新</value> | |||
| </data> | |||
| <data name="Copy" xml:space="preserve"> | |||
| <value>コピー</value> | |||
| </data> | |||
| </root> | |||
| @@ -117,4 +117,64 @@ | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <data name="Password" xml:space="preserve"> | |||
| <value>비밀번호</value> | |||
| </data> | |||
| <data name="Type" xml:space="preserve"> | |||
| <value>유형</value> | |||
| </data> | |||
| <data name="Address" xml:space="preserve"> | |||
| <value>주소</value> | |||
| </data> | |||
| <data name="Port" xml:space="preserve"> | |||
| <value>포트</value> | |||
| </data> | |||
| <data name="Timeout" xml:space="preserve"> | |||
| <value>시간 초과</value> | |||
| </data> | |||
| <data name="cancelButton_Content" xml:space="preserve"> | |||
| <value>취소</value> | |||
| </data> | |||
| <data name="okButton_Content" xml:space="preserve"> | |||
| <value>확인</value> | |||
| </data> | |||
| <data name="ToggleSystemProxy" xml:space="preserve"> | |||
| <value>시스템 프록시 전환</value> | |||
| </data> | |||
| <data name="ToggleProxyMode" xml:space="preserve"> | |||
| <value>시스템 프록시 모드 전환</value> | |||
| </data> | |||
| <data name="AllowClientsFromLAN" xml:space="preserve"> | |||
| <value>LAN으로부터 클라이언트 허용</value> | |||
| </data> | |||
| <data name="OpenLogsWindow" xml:space="preserve"> | |||
| <value>로그 보기…</value> | |||
| </data> | |||
| <data name="SwitchToPreviousServer" xml:space="preserve"> | |||
| <value>이전 서버로 전환</value> | |||
| </data> | |||
| <data name="SwitchToNextServer" xml:space="preserve"> | |||
| <value>다음 서버로 전환</value> | |||
| </data> | |||
| <data name="RegisterHotkeysAtStartup" xml:space="preserve"> | |||
| <value>모두 등록</value> | |||
| </data> | |||
| <data name="registerAllButton_Content" xml:space="preserve"> | |||
| <value>시스템 시작 시 단축키 등록</value> | |||
| </data> | |||
| <data name="addButton_Content" xml:space="preserve"> | |||
| <value>추가</value> | |||
| </data> | |||
| <data name="skipVersionButton_Content" xml:space="preserve"> | |||
| <value>버전 건너 뛰기</value> | |||
| </data> | |||
| <data name="copyLinkButton_Content" xml:space="preserve"> | |||
| <value>링크 복사</value> | |||
| </data> | |||
| <data name="updateButton_Content" xml:space="preserve"> | |||
| <value>새롭게 함</value> | |||
| </data> | |||
| <data name="Copy" xml:space="preserve"> | |||
| <value>부</value> | |||
| </data> | |||
| </root> | |||
| @@ -0,0 +1,243 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <data name="Type" xml:space="preserve"> | |||
| <value>Type</value> | |||
| </data> | |||
| <data name="NoProxy" xml:space="preserve"> | |||
| <value>No proxy</value> | |||
| </data> | |||
| <data name="SOCKS5" xml:space="preserve"> | |||
| <value>SOCKS5</value> | |||
| </data> | |||
| <data name="HTTP" xml:space="preserve"> | |||
| <value>HTTP</value> | |||
| </data> | |||
| <data name="Details" xml:space="preserve"> | |||
| <value>Details</value> | |||
| </data> | |||
| <data name="Address" xml:space="preserve"> | |||
| <value>Address</value> | |||
| </data> | |||
| <data name="Port" xml:space="preserve"> | |||
| <value>Port</value> | |||
| </data> | |||
| <data name="Timeout" xml:space="preserve"> | |||
| <value>Timeout</value> | |||
| </data> | |||
| <data name="CredentialsOptional" xml:space="preserve"> | |||
| <value>Credentials (optional)</value> | |||
| </data> | |||
| <data name="Username" xml:space="preserve"> | |||
| <value>Username</value> | |||
| </data> | |||
| <data name="Password" xml:space="preserve"> | |||
| <value>Password</value> | |||
| </data> | |||
| <data name="saveButton_Content" xml:space="preserve"> | |||
| <value>_Save</value> | |||
| </data> | |||
| <data name="cancelButton_Content" xml:space="preserve"> | |||
| <value>_Cancel</value> | |||
| </data> | |||
| <data name="okButton_Content" xml:space="preserve"> | |||
| <value>_OK</value> | |||
| </data> | |||
| <data name="ToggleSystemProxy" xml:space="preserve"> | |||
| <value>Toggle system proxy</value> | |||
| </data> | |||
| <data name="ToggleProxyMode" xml:space="preserve"> | |||
| <value>Toggle proxy mode</value> | |||
| </data> | |||
| <data name="AllowClientsFromLAN" xml:space="preserve"> | |||
| <value>Allow clients from LAN</value> | |||
| </data> | |||
| <data name="OpenLogsWindow" xml:space="preserve"> | |||
| <value>Open logs window</value> | |||
| </data> | |||
| <data name="SwitchToPreviousServer" xml:space="preserve"> | |||
| <value>Switch to previous server</value> | |||
| </data> | |||
| <data name="SwitchToNextServer" xml:space="preserve"> | |||
| <value>Switch to next server</value> | |||
| </data> | |||
| <data name="RegisterHotkeysAtStartup" xml:space="preserve"> | |||
| <value>Register hotkeys at startup</value> | |||
| </data> | |||
| <data name="registerAllButton_Content" xml:space="preserve"> | |||
| <value>_Register all</value> | |||
| </data> | |||
| <data name="updateButton_Content" xml:space="preserve"> | |||
| <value>_Update</value> | |||
| </data> | |||
| <data name="updateAllButton_Content" xml:space="preserve"> | |||
| <value>Update all</value> | |||
| </data> | |||
| <data name="copyLinkButton_Content" xml:space="preserve"> | |||
| <value>_Copy link</value> | |||
| </data> | |||
| <data name="removeButton_Content" xml:space="preserve"> | |||
| <value>Remove</value> | |||
| </data> | |||
| <data name="addButton_Content" xml:space="preserve"> | |||
| <value>_Add</value> | |||
| </data> | |||
| <data name="updatePromptTitle" xml:space="preserve"> | |||
| <value>An update is available.</value> | |||
| </data> | |||
| <data name="updatePromptBody" xml:space="preserve"> | |||
| <value>Please read the release notes carefully. Then decide whether to update.</value> | |||
| </data> | |||
| <data name="skipVersionButton_Content" xml:space="preserve"> | |||
| <value>_Skip version</value> | |||
| </data> | |||
| <data name="notNowButton_Content" xml:space="preserve"> | |||
| <value>_Not now</value> | |||
| </data> | |||
| <data name="Copy" xml:space="preserve"> | |||
| <value>_Copy</value> | |||
| </data> | |||
| <data name="ForwardProxy" xml:space="preserve"> | |||
| <value>Forward Proxy</value> | |||
| </data> | |||
| <data name="ServerSharing" xml:space="preserve"> | |||
| <value>Server Sharing</value> | |||
| </data> | |||
| <data name="Hotkeys" xml:space="preserve"> | |||
| <value>Hotkeys</value> | |||
| </data> | |||
| <data name="OnlineConfigDelivery" xml:space="preserve"> | |||
| <value>Online Configuration Delivery</value> | |||
| </data> | |||
| <data name="VersionUpdate" xml:space="preserve"> | |||
| <value>VersionUpdate</value> | |||
| </data> | |||
| <data name="sip008UpdateSuccess" xml:space="preserve"> | |||
| <value>Successfully updated the selected source!</value> | |||
| </data> | |||
| <data name="sip008UpdateFailure" xml:space="preserve"> | |||
| <value>Update failed. See the logs for more information.</value> | |||
| </data> | |||
| <data name="sip008UpdateAllSuccess" xml:space="preserve"> | |||
| <value>Successfully updated all sources!</value> | |||
| </data> | |||
| <data name="sip008UpdateAllFailure" xml:space="preserve"> | |||
| <value>The following sources failed to update:\n\n</value> | |||
| </data> | |||
| </root> | |||
| @@ -0,0 +1,183 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <data name="Password" xml:space="preserve"> | |||
| <value>Пароль</value> | |||
| </data> | |||
| <data name="Type" xml:space="preserve"> | |||
| <value>тип</value> | |||
| </data> | |||
| <data name="Address" xml:space="preserve"> | |||
| <value>адрес</value> | |||
| </data> | |||
| <data name="Port" xml:space="preserve"> | |||
| <value>порт</value> | |||
| </data> | |||
| <data name="Timeout" xml:space="preserve"> | |||
| <value>Таймаут</value> | |||
| </data> | |||
| <data name="cancelButton_Content" xml:space="preserve"> | |||
| <value>Отмена</value> | |||
| </data> | |||
| <data name="okButton_Content" xml:space="preserve"> | |||
| <value>ОК</value> | |||
| </data> | |||
| <data name="ToggleSystemProxy" xml:space="preserve"> | |||
| <value>ВКЛ/ВЫКЛ системный прокси-сервер</value> | |||
| </data> | |||
| <data name="ToggleProxyMode" xml:space="preserve"> | |||
| <value>Переключение режима прокси-сервера</value> | |||
| </data> | |||
| <data name="AllowClientsFromLAN" xml:space="preserve"> | |||
| <value>Общий доступ к подключению</value> | |||
| </data> | |||
| <data name="OpenLogsWindow" xml:space="preserve"> | |||
| <value>Просмотр журналов</value> | |||
| </data> | |||
| <data name="SwitchToPreviousServer" xml:space="preserve"> | |||
| <value>Переключить на пред. сервер</value> | |||
| </data> | |||
| <data name="SwitchToNextServer" xml:space="preserve"> | |||
| <value>Переключить на след. сервер</value> | |||
| </data> | |||
| <data name="RegisterHotkeysAtStartup" xml:space="preserve"> | |||
| <value>Применить все</value> | |||
| </data> | |||
| <data name="registerAllButton_Content" xml:space="preserve"> | |||
| <value>Применять при запуске программы</value> | |||
| </data> | |||
| <data name="addButton_Content" xml:space="preserve"> | |||
| <value>Добавить</value> | |||
| </data> | |||
| <data name="skipVersionButton_Content" xml:space="preserve"> | |||
| <value>пропустить версию</value> | |||
| </data> | |||
| <data name="copyLinkButton_Content" xml:space="preserve"> | |||
| <value>копировать ссылку</value> | |||
| </data> | |||
| <data name="removeButton_Content" xml:space="preserve"> | |||
| <value>Удалить</value> | |||
| </data> | |||
| <data name="updateButton_Content" xml:space="preserve"> | |||
| <value>Обновить</value> | |||
| </data> | |||
| <data name="Copy" xml:space="preserve"> | |||
| <value>копировать</value> | |||
| </data> | |||
| </root> | |||
| @@ -0,0 +1,237 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <data name="NoProxy" xml:space="preserve"> | |||
| <value>不使用代理</value> | |||
| </data> | |||
| <data name="Type" xml:space="preserve"> | |||
| <value>类型</value> | |||
| </data> | |||
| <data name="CredentialsOptional" xml:space="preserve"> | |||
| <value>认证 (可选)</value> | |||
| </data> | |||
| <data name="Details" xml:space="preserve"> | |||
| <value>详细设置</value> | |||
| </data> | |||
| <data name="Address" xml:space="preserve"> | |||
| <value>地址</value> | |||
| </data> | |||
| <data name="saveButton_Content" xml:space="preserve"> | |||
| <value>保存</value> | |||
| </data> | |||
| <data name="cancelButton_Content" xml:space="preserve"> | |||
| <value>取消</value> | |||
| </data> | |||
| <data name="Username" xml:space="preserve"> | |||
| <value>用户名</value> | |||
| </data> | |||
| <data name="Password" xml:space="preserve"> | |||
| <value>密码</value> | |||
| </data> | |||
| <data name="Port" xml:space="preserve"> | |||
| <value>端口</value> | |||
| </data> | |||
| <data name="Timeout" xml:space="preserve"> | |||
| <value>超时</value> | |||
| </data> | |||
| <data name="okButton_Content" xml:space="preserve"> | |||
| <value>确定</value> | |||
| </data> | |||
| <data name="registerAllButton_Content" xml:space="preserve"> | |||
| <value>全部注册</value> | |||
| </data> | |||
| <data name="ToggleSystemProxy" xml:space="preserve"> | |||
| <value>切换系统代理</value> | |||
| </data> | |||
| <data name="ToggleProxyMode" xml:space="preserve"> | |||
| <value>切换代理模式</value> | |||
| </data> | |||
| <data name="AllowClientsFromLAN" xml:space="preserve"> | |||
| <value>允许内网客户端连接</value> | |||
| </data> | |||
| <data name="OpenLogsWindow" xml:space="preserve"> | |||
| <value>打开日志窗口</value> | |||
| </data> | |||
| <data name="SwitchToPreviousServer" xml:space="preserve"> | |||
| <value>切换到上一个服务器</value> | |||
| </data> | |||
| <data name="SwitchToNextServer" xml:space="preserve"> | |||
| <value>切换到下一个服务器</value> | |||
| </data> | |||
| <data name="RegisterHotkeysAtStartup" xml:space="preserve"> | |||
| <value>启动时注册快捷键</value> | |||
| </data> | |||
| <data name="updateButton_Content" xml:space="preserve"> | |||
| <value>更新</value> | |||
| </data> | |||
| <data name="updateAllButton_Content" xml:space="preserve"> | |||
| <value>全部更新</value> | |||
| </data> | |||
| <data name="copyLinkButton_Content" xml:space="preserve"> | |||
| <value>复制链接</value> | |||
| </data> | |||
| <data name="removeButton_Content" xml:space="preserve"> | |||
| <value>移除</value> | |||
| </data> | |||
| <data name="addButton_Content" xml:space="preserve"> | |||
| <value>添加</value> | |||
| </data> | |||
| <data name="skipVersionButton_Content" xml:space="preserve"> | |||
| <value>跳过版本</value> | |||
| </data> | |||
| <data name="notNowButton_Content" xml:space="preserve"> | |||
| <value>暂不更新</value> | |||
| </data> | |||
| <data name="updatePromptTitle" xml:space="preserve"> | |||
| <value>发现可用更新</value> | |||
| </data> | |||
| <data name="updatePromptBody" xml:space="preserve"> | |||
| <value>请仔细阅读发布信息,然后决定是否更新。</value> | |||
| </data> | |||
| <data name="Copy" xml:space="preserve"> | |||
| <value>复制</value> | |||
| </data> | |||
| <data name="ForwardProxy" xml:space="preserve"> | |||
| <value>前置代理</value> | |||
| </data> | |||
| <data name="OnlineConfigDelivery" xml:space="preserve"> | |||
| <value>在线配置下发</value> | |||
| </data> | |||
| <data name="Hotkeys" xml:space="preserve"> | |||
| <value>热键</value> | |||
| </data> | |||
| <data name="ServerSharing" xml:space="preserve"> | |||
| <value>服务器分享</value> | |||
| </data> | |||
| <data name="VersionUpdate" xml:space="preserve"> | |||
| <value>版本更新</value> | |||
| </data> | |||
| <data name="sip008UpdateSuccess" xml:space="preserve"> | |||
| <value>成功更新选定来源!</value> | |||
| </data> | |||
| <data name="sip008UpdateFailure" xml:space="preserve"> | |||
| <value>更新失败,请查看日志获取更多信息。</value> | |||
| </data> | |||
| <data name="sip008UpdateAllSuccess" xml:space="preserve"> | |||
| <value>成功更新所有来源!</value> | |||
| </data> | |||
| <data name="sip008UpdateAllFailure" xml:space="preserve"> | |||
| <value>下列来源更新失败:\n\n</value> | |||
| </data> | |||
| </root> | |||
| @@ -0,0 +1,189 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <data name="Password" xml:space="preserve"> | |||
| <value>密碼</value> | |||
| </data> | |||
| <data name="Port" xml:space="preserve"> | |||
| <value>Port</value> | |||
| </data> | |||
| <data name="Type" xml:space="preserve"> | |||
| <value>類型</value> | |||
| </data> | |||
| <data name="Address" xml:space="preserve"> | |||
| <value>位址</value> | |||
| </data> | |||
| <data name="Timeout" xml:space="preserve"> | |||
| <value>逾時</value> | |||
| </data> | |||
| <data name="cancelButton_Content" xml:space="preserve"> | |||
| <value>取消</value> | |||
| </data> | |||
| <data name="okButton_Content" xml:space="preserve"> | |||
| <value>確定</value> | |||
| </data> | |||
| <data name="ToggleSystemProxy" xml:space="preserve"> | |||
| <value>切換系統 Proxy 狀態</value> | |||
| </data> | |||
| <data name="ToggleProxyMode" xml:space="preserve"> | |||
| <value>切換系統 Proxy 模式</value> | |||
| </data> | |||
| <data name="AllowClientsFromLAN" xml:space="preserve"> | |||
| <value>切換區域網路共用</value> | |||
| </data> | |||
| <data name="OpenLogsWindow" xml:space="preserve"> | |||
| <value>顯示記錄檔</value> | |||
| </data> | |||
| <data name="SwitchToPreviousServer" xml:space="preserve"> | |||
| <value>切換上一個伺服器</value> | |||
| </data> | |||
| <data name="SwitchToNextServer" xml:space="preserve"> | |||
| <value>切換下一個伺服器</value> | |||
| </data> | |||
| <data name="RegisterHotkeysAtStartup" xml:space="preserve"> | |||
| <value>註冊所有快速鍵</value> | |||
| </data> | |||
| <data name="registerAllButton_Content" xml:space="preserve"> | |||
| <value>啟動時註冊快速鍵</value> | |||
| </data> | |||
| <data name="updateButton_Content" xml:space="preserve"> | |||
| <value>更新</value> | |||
| </data> | |||
| <data name="updateAllButton_Content" xml:space="preserve"> | |||
| <value>全部更新</value> | |||
| </data> | |||
| <data name="addButton_Content" xml:space="preserve"> | |||
| <value>新增</value> | |||
| </data> | |||
| <data name="skipVersionButton_Content" xml:space="preserve"> | |||
| <value>跳過版本</value> | |||
| </data> | |||
| <data name="notNowButton_Content" xml:space="preserve"> | |||
| <value>暫不更新</value> | |||
| </data> | |||
| <data name="updatePromptTitle" xml:space="preserve"> | |||
| <value>發現可用更新</value> | |||
| </data> | |||
| <data name="copyLinkButton_Content" xml:space="preserve"> | |||
| <value>複製鏈接</value> | |||
| </data> | |||
| <data name="Copy" xml:space="preserve"> | |||
| <value>複製</value> | |||
| </data> | |||
| </root> | |||
| @@ -40,6 +40,7 @@ namespace Shadowsocks.Model | |||
| public bool availabilityStatistics; | |||
| public bool autoCheckUpdate; | |||
| public bool checkPreRelease; | |||
| public string skippedUpdateVersion; // skip the update with this version number | |||
| public bool isVerboseLogging; | |||
| // hidden options | |||
| @@ -53,7 +54,7 @@ namespace Shadowsocks.Model | |||
| //public NLogConfig.LogLevel logLevel; | |||
| public LogViewerConfig logViewer; | |||
| public ProxyConfig proxy; | |||
| public ForwardProxyConfig proxy; | |||
| public HotkeyConfig hotkey; | |||
| [JsonIgnore] | |||
| @@ -78,6 +79,7 @@ namespace Shadowsocks.Model | |||
| availabilityStatistics = false; | |||
| autoCheckUpdate = false; | |||
| checkPreRelease = false; | |||
| skippedUpdateVersion = ""; | |||
| isVerboseLogging = false; | |||
| // hidden options | |||
| @@ -97,7 +99,7 @@ namespace Shadowsocks.Model | |||
| userAgent = "ShadowsocksWindows/$version"; | |||
| logViewer = new LogViewerConfig(); | |||
| proxy = new ProxyConfig(); | |||
| proxy = new ForwardProxyConfig(); | |||
| hotkey = new HotkeyConfig(); | |||
| firstRunOnNewVersion = false; | |||
| @@ -193,7 +195,9 @@ namespace Shadowsocks.Model | |||
| ResetGeositeProxiedGroup(ref config.geositeProxiedGroups); | |||
| // Mark the first run of a new version. | |||
| if (UpdateChecker.Asset.CompareVersion(UpdateChecker.Version, config.version ?? "0") > 0) | |||
| var appVersion = new Version(UpdateChecker.Version); | |||
| var configVersion = new Version(config.version); | |||
| if (appVersion.CompareTo(configVersion) > 0) | |||
| { | |||
| config.firstRunOnNewVersion = true; | |||
| } | |||
| @@ -316,6 +320,12 @@ namespace Shadowsocks.Model | |||
| geositeProxiedGroups.Add("geolocation-!cn"); | |||
| } | |||
| public static void ResetUserAgent(Configuration config) | |||
| { | |||
| config.userAgent = "ShadowsocksWindows/$version"; | |||
| config.userAgentString = config.userAgent.Replace("$version", config.version); | |||
| } | |||
| public static Server AddDefaultServerOrServer(Configuration config, Server server = null, int? index = null) | |||
| { | |||
| if (config?.configs != null) | |||
| @@ -368,17 +378,5 @@ namespace Shadowsocks.Model | |||
| throw new ArgumentException( | |||
| I18N.GetString("Timeout is invalid, it should not exceed {0}", maxTimeout)); | |||
| } | |||
| public static void CheckProxyAuthUser(string user) | |||
| { | |||
| if (string.IsNullOrEmpty(user)) | |||
| throw new ArgumentException(I18N.GetString("Auth user can not be blank")); | |||
| } | |||
| public static void CheckProxyAuthPwd(string pwd) | |||
| { | |||
| if (string.IsNullOrEmpty(pwd)) | |||
| throw new ArgumentException(I18N.GetString("Auth pwd can not be blank")); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,43 +1,43 @@ | |||
| using System; | |||
| namespace Shadowsocks.Model | |||
| { | |||
| [Serializable] | |||
| public class ProxyConfig | |||
| { | |||
| public const int PROXY_SOCKS5 = 0; | |||
| public const int PROXY_HTTP = 1; | |||
| public const int MaxProxyTimeoutSec = 10; | |||
| private const int DefaultProxyTimeoutSec = 3; | |||
| public bool useProxy; | |||
| public int proxyType; | |||
| public string proxyServer; | |||
| public int proxyPort; | |||
| public int proxyTimeout; | |||
| public bool useAuth; | |||
| public string authUser; | |||
| public string authPwd; | |||
| public ProxyConfig() | |||
| { | |||
| useProxy = false; | |||
| proxyType = PROXY_SOCKS5; | |||
| proxyServer = ""; | |||
| proxyPort = 0; | |||
| proxyTimeout = DefaultProxyTimeoutSec; | |||
| useAuth = false; | |||
| authUser = ""; | |||
| authPwd = ""; | |||
| } | |||
| public void CheckConfig() | |||
| { | |||
| if (proxyType < PROXY_SOCKS5 || proxyType > PROXY_HTTP) | |||
| { | |||
| proxyType = PROXY_SOCKS5; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| using System; | |||
| namespace Shadowsocks.Model | |||
| { | |||
| [Serializable] | |||
| public class ForwardProxyConfig | |||
| { | |||
| public const int PROXY_SOCKS5 = 0; | |||
| public const int PROXY_HTTP = 1; | |||
| public const int MaxProxyTimeoutSec = 10; | |||
| private const int DefaultProxyTimeoutSec = 3; | |||
| public bool useProxy; | |||
| public int proxyType; | |||
| public string proxyServer; | |||
| public int proxyPort; | |||
| public int proxyTimeout; | |||
| public bool useAuth; | |||
| public string authUser; | |||
| public string authPwd; | |||
| public ForwardProxyConfig() | |||
| { | |||
| useProxy = false; | |||
| proxyType = PROXY_SOCKS5; | |||
| proxyServer = ""; | |||
| proxyPort = 0; | |||
| proxyTimeout = DefaultProxyTimeoutSec; | |||
| useAuth = false; | |||
| authUser = ""; | |||
| authPwd = ""; | |||
| } | |||
| public void CheckConfig() | |||
| { | |||
| if (proxyType < PROXY_SOCKS5 || proxyType > PROXY_HTTP) | |||
| { | |||
| proxyType = PROXY_SOCKS5; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -3,6 +3,7 @@ using System.Diagnostics; | |||
| using System.IO; | |||
| using System.IO.Pipes; | |||
| using System.Net; | |||
| using System.Reflection; | |||
| using System.Text; | |||
| using System.Threading; | |||
| using System.Threading.Tasks; | |||
| @@ -10,10 +11,12 @@ using System.Windows.Forms; | |||
| using CommandLine; | |||
| using Microsoft.Win32; | |||
| using NLog; | |||
| using ReactiveUI; | |||
| using Shadowsocks.Controller; | |||
| using Shadowsocks.Controller.Hotkeys; | |||
| using Shadowsocks.Util; | |||
| using Shadowsocks.View; | |||
| using Splat; | |||
| namespace Shadowsocks | |||
| { | |||
| @@ -109,6 +112,10 @@ namespace Shadowsocks | |||
| AutoStartup.RegisterForRestart(true); | |||
| #endregion | |||
| // We would use this in v5. | |||
| // Parameters would have to be dropped from views' constructors (VersionUpdatePromptView) | |||
| //Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly()); | |||
| #if DEBUG | |||
| // truncate privoxy log file while debugging | |||
| string privoxyLogFilename = Utils.GetTempPath("privoxy.log"); | |||
| @@ -1,10 +1,10 @@ | |||
| //------------------------------------------------------------------------------ | |||
| // <auto-generated> | |||
| // 此代码由工具生成。 | |||
| // 运行时版本:4.0.30319.42000 | |||
| // This code was generated by a tool. | |||
| // Runtime Version:4.0.30319.42000 | |||
| // | |||
| // 对此文件的更改可能会导致不正确的行为,并且如果 | |||
| // 重新生成代码,这些更改将会丢失。 | |||
| // Changes to this file may cause incorrect behavior and will be lost if | |||
| // the code is regenerated. | |||
| // </auto-generated> | |||
| //------------------------------------------------------------------------------ | |||
| @@ -13,16 +13,16 @@ namespace Shadowsocks.Properties { | |||
| /// <summary> | |||
| /// 一个强类型的资源类,用于查找本地化的字符串等。 | |||
| /// A strongly-typed resource class, for looking up localized strings, etc. | |||
| /// </summary> | |||
| // 此类是由 StronglyTypedResourceBuilder | |||
| // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 | |||
| // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen | |||
| // (以 /str 作为命令选项),或重新生成 VS 项目。 | |||
| // This class was auto-generated by the StronglyTypedResourceBuilder | |||
| // class via a tool like ResGen or Visual Studio. | |||
| // To add or remove a member, edit your .ResX file then rerun ResGen | |||
| // with the /str option, or rebuild your VS project. | |||
| [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] | |||
| [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] | |||
| [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | |||
| internal class Resources { | |||
| public class Resources { | |||
| private static global::System.Resources.ResourceManager resourceMan; | |||
| @@ -33,10 +33,10 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 返回此类使用的缓存的 ResourceManager 实例。 | |||
| /// Returns the cached ResourceManager instance used by this class. | |||
| /// </summary> | |||
| [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |||
| internal static global::System.Resources.ResourceManager ResourceManager { | |||
| public static global::System.Resources.ResourceManager ResourceManager { | |||
| get { | |||
| if (object.ReferenceEquals(resourceMan, null)) { | |||
| global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Shadowsocks.Properties.Resources", typeof(Resources).Assembly); | |||
| @@ -47,11 +47,11 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 重写当前线程的 CurrentUICulture 属性 | |||
| /// 重写当前线程的 CurrentUICulture 属性。 | |||
| /// Overrides the current thread's CurrentUICulture property for all | |||
| /// resource lookups using this strongly typed resource class. | |||
| /// </summary> | |||
| [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |||
| internal static global::System.Globalization.CultureInfo Culture { | |||
| public static global::System.Globalization.CultureInfo Culture { | |||
| get { | |||
| return resourceCulture; | |||
| } | |||
| @@ -61,7 +61,7 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找类似 /* eslint-disable */ | |||
| /// Looks up a localized string similar to /* eslint-disable */ | |||
| ///// Was generated by gfwlist2pac in precise mode | |||
| ///// https://github.com/clowwindy/gfwlist2pac | |||
| /// | |||
| @@ -69,25 +69,28 @@ namespace Shadowsocks.Properties { | |||
| ///// 2019-02-08: Updated to support shadowsocks-windows user rules. | |||
| /// | |||
| ///var proxy = __PROXY__; | |||
| ///var userrules = __USERRULES__; | |||
| ///var rules = __RULES__; | |||
| ///var userrules = []; | |||
| ///var rules = []; | |||
| /// | |||
| ////* | |||
| ///* This file is part of Adblock Plus <http://adblockplus.org/>, | |||
| ///* Copyright (C) 2006-2014 Eyeo GmbH | |||
| ///* | |||
| ///* Adblock Plus is free software: you can redistribute it and/or [字符串的其余部分被截断]"; 的本地化字符串。 | |||
| ///// convert to abp grammar | |||
| ///for (var i = 0; i < __RULES__.length; i++) { | |||
| /// var s = __RULES__[i]; | |||
| /// if (s.substring(0, 2) == "||") s += "^"; | |||
| /// rules.push(s); | |||
| ///} | |||
| /// | |||
| ///for (var i = 0; i < [rest of string was truncated]";. | |||
| /// </summary> | |||
| internal static string abp_js { | |||
| public static string abp_js { | |||
| get { | |||
| return ResourceManager.GetString("abp_js", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Byte[] 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Byte[]. | |||
| /// </summary> | |||
| internal static byte[] dlc_dat { | |||
| public static byte[] dlc_dat { | |||
| get { | |||
| object obj = ResourceManager.GetObject("dlc_dat", resourceCulture); | |||
| return ((byte[])(obj)); | |||
| @@ -95,7 +98,7 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找类似 en,ru-RU,zh-CN,zh-TW,ja,ko,fr | |||
| /// Looks up a localized string similar to en,ru-RU,zh-CN,zh-TW,ja,ko,fr | |||
| ///#Restart program to apply translation,,,,,, | |||
| ///#This is comment line,,,,,, | |||
| ///#Always keep language name at head of file,,,,,, | |||
| @@ -107,18 +110,18 @@ namespace Shadowsocks.Properties { | |||
| ///,,,,,, | |||
| ///#Menu,,,,,, | |||
| ///,,,,,, | |||
| ///System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ,시스템 프록시,P [字符串的其余部分被截断]"; 的本地化字符串。 | |||
| ///System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ,시스템 프록시,P [rest of string was truncated]";. | |||
| /// </summary> | |||
| internal static string i18n_csv { | |||
| public static string i18n_csv { | |||
| get { | |||
| return ResourceManager.GetString("i18n_csv", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Byte[] 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Byte[]. | |||
| /// </summary> | |||
| internal static byte[] libsscrypto_dll { | |||
| public static byte[] libsscrypto_dll { | |||
| get { | |||
| object obj = ResourceManager.GetObject("libsscrypto_dll", resourceCulture); | |||
| return ((byte[])(obj)); | |||
| @@ -126,22 +129,22 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找类似 <?xml version="1.0" encoding="utf-8" ?> | |||
| /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> | |||
| ///<!-- Warning: Configuration may reset after shadowsocks upgrade. --> | |||
| ///<!-- If you messed it up, delete this file and Shadowsocks will create a new one. --> | |||
| ///<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |||
| /// <targets> | |||
| /// <!-- This line is managed by Shadowsocks. Do not modify it unless you know what you are doing.--> | |||
| /// <target name="file" xsi:type="File" fileName="ss_win_temp\shadowsocks.log" writ [字符串的其余部分被截断]"; 的本地化字符串。 | |||
| /// <target name="file" xsi:type="File" fileName="ss_win_temp\shadowsocks.log" writ [rest of string was truncated]";. | |||
| /// </summary> | |||
| internal static string NLog_config { | |||
| public static string NLog_config { | |||
| get { | |||
| return ResourceManager.GetString("NLog_config", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 查找类似 listen-address __PRIVOXY_BIND_IP__:__PRIVOXY_BIND_PORT__ | |||
| /// Looks up a localized string similar to listen-address __PRIVOXY_BIND_IP__:__PRIVOXY_BIND_PORT__ | |||
| ///toggle 0 | |||
| ///logfile ss_privoxy.log | |||
| ///show-on-task-bar 0 | |||
| @@ -149,18 +152,18 @@ namespace Shadowsocks.Properties { | |||
| ///forward-socks5 / __SOCKS_HOST__:__SOCKS_PORT__ . | |||
| ///max-client-connections 2048 | |||
| ///hide-console | |||
| /// 的本地化字符串。 | |||
| ///. | |||
| /// </summary> | |||
| internal static string privoxy_conf { | |||
| public static string privoxy_conf { | |||
| get { | |||
| return ResourceManager.GetString("privoxy_conf", resourceCulture); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Byte[] 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Byte[]. | |||
| /// </summary> | |||
| internal static byte[] privoxy_exe { | |||
| public static byte[] privoxy_exe { | |||
| get { | |||
| object obj = ResourceManager.GetObject("privoxy_exe", resourceCulture); | |||
| return ((byte[])(obj)); | |||
| @@ -168,9 +171,9 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Drawing.Bitmap. | |||
| /// </summary> | |||
| internal static System.Drawing.Bitmap ss32Fill { | |||
| public static System.Drawing.Bitmap ss32Fill { | |||
| get { | |||
| object obj = ResourceManager.GetObject("ss32Fill", resourceCulture); | |||
| return ((System.Drawing.Bitmap)(obj)); | |||
| @@ -178,9 +181,9 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Drawing.Bitmap. | |||
| /// </summary> | |||
| internal static System.Drawing.Bitmap ss32In { | |||
| public static System.Drawing.Bitmap ss32In { | |||
| get { | |||
| object obj = ResourceManager.GetObject("ss32In", resourceCulture); | |||
| return ((System.Drawing.Bitmap)(obj)); | |||
| @@ -188,9 +191,9 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Drawing.Bitmap. | |||
| /// </summary> | |||
| internal static System.Drawing.Bitmap ss32Out { | |||
| public static System.Drawing.Bitmap ss32Out { | |||
| get { | |||
| object obj = ResourceManager.GetObject("ss32Out", resourceCulture); | |||
| return ((System.Drawing.Bitmap)(obj)); | |||
| @@ -198,9 +201,9 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Drawing.Bitmap. | |||
| /// </summary> | |||
| internal static System.Drawing.Bitmap ss32Outline { | |||
| public static System.Drawing.Bitmap ss32Outline { | |||
| get { | |||
| object obj = ResourceManager.GetObject("ss32Outline", resourceCulture); | |||
| return ((System.Drawing.Bitmap)(obj)); | |||
| @@ -208,9 +211,9 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Drawing.Bitmap. | |||
| /// </summary> | |||
| internal static System.Drawing.Bitmap ssw128 { | |||
| public static System.Drawing.Bitmap ssw128 { | |||
| get { | |||
| object obj = ResourceManager.GetObject("ssw128", resourceCulture); | |||
| return ((System.Drawing.Bitmap)(obj)); | |||
| @@ -218,9 +221,9 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Byte[] 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Byte[]. | |||
| /// </summary> | |||
| internal static byte[] sysproxy_exe { | |||
| public static byte[] sysproxy_exe { | |||
| get { | |||
| object obj = ResourceManager.GetObject("sysproxy_exe", resourceCulture); | |||
| return ((byte[])(obj)); | |||
| @@ -228,9 +231,9 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找 System.Byte[] 类型的本地化资源。 | |||
| /// Looks up a localized resource of type System.Byte[]. | |||
| /// </summary> | |||
| internal static byte[] sysproxy64_exe { | |||
| public static byte[] sysproxy64_exe { | |||
| get { | |||
| object obj = ResourceManager.GetObject("sysproxy64_exe", resourceCulture); | |||
| return ((byte[])(obj)); | |||
| @@ -238,11 +241,11 @@ namespace Shadowsocks.Properties { | |||
| } | |||
| /// <summary> | |||
| /// 查找类似 ! Put user rules line by line in this file. | |||
| /// Looks up a localized string similar to ! Put user rules line by line in this file. | |||
| ///! See https://adblockplus.org/en/filter-cheatsheet | |||
| /// 的本地化字符串。 | |||
| ///. | |||
| /// </summary> | |||
| internal static string user_rule { | |||
| public static string user_rule { | |||
| get { | |||
| return ResourceManager.GetString("user_rule", resourceCulture); | |||
| } | |||
| @@ -1,190 +0,0 @@ | |||
| using Shadowsocks.Controller; | |||
| using Shadowsocks.Model; | |||
| using Shadowsocks.Properties; | |||
| using System; | |||
| using System.Drawing; | |||
| using System.Text; | |||
| using System.Windows.Forms; | |||
| using static Shadowsocks.Controller.HotkeyReg; | |||
| namespace Shadowsocks.View | |||
| { | |||
| public partial class HotkeySettingsForm : Form | |||
| { | |||
| private readonly ShadowsocksController _controller; | |||
| // this is a copy of hotkey configuration that we are working on | |||
| private HotkeyConfig _modifiedHotkeyConfig; | |||
| public HotkeySettingsForm(ShadowsocksController controller) | |||
| { | |||
| InitializeComponent(); | |||
| UpdateTexts(); | |||
| Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | |||
| _controller = controller; | |||
| _controller.ConfigChanged += controller_ConfigChanged; | |||
| LoadCurrentConfiguration(); | |||
| } | |||
| private void UpdateTexts() | |||
| { | |||
| I18N.TranslateForm(this); | |||
| } | |||
| private void controller_ConfigChanged(object sender, EventArgs e) | |||
| { | |||
| LoadCurrentConfiguration(); | |||
| } | |||
| private void LoadCurrentConfiguration() | |||
| { | |||
| _modifiedHotkeyConfig = _controller.GetCurrentConfiguration().hotkey; | |||
| SetConfigToUI(_modifiedHotkeyConfig); | |||
| } | |||
| private void SetConfigToUI(HotkeyConfig config) | |||
| { | |||
| SwitchSystemProxyTextBox.Text = config.SwitchSystemProxy; | |||
| SwitchProxyModeTextBox.Text = config.SwitchSystemProxyMode; | |||
| SwitchAllowLanTextBox.Text = config.SwitchAllowLan; | |||
| ShowLogsTextBox.Text = config.ShowLogs; | |||
| ServerMoveUpTextBox.Text = config.ServerMoveUp; | |||
| ServerMoveDownTextBox.Text = config.ServerMoveDown; | |||
| RegHotkeysAtStartupCheckBox.Checked = config.RegHotkeysAtStartup; | |||
| } | |||
| private void SaveConfig() | |||
| { | |||
| _controller.SaveHotkeyConfig(_modifiedHotkeyConfig); | |||
| } | |||
| private HotkeyConfig GetConfigFromUI() | |||
| { | |||
| return new HotkeyConfig | |||
| { | |||
| SwitchSystemProxy = SwitchSystemProxyTextBox.Text, | |||
| SwitchSystemProxyMode = SwitchProxyModeTextBox.Text, | |||
| SwitchAllowLan = SwitchAllowLanTextBox.Text, | |||
| ShowLogs = ShowLogsTextBox.Text, | |||
| ServerMoveUp = ServerMoveUpTextBox.Text, | |||
| ServerMoveDown = ServerMoveDownTextBox.Text, | |||
| RegHotkeysAtStartup = RegHotkeysAtStartupCheckBox.Checked | |||
| }; | |||
| } | |||
| /// <summary> | |||
| /// Capture hotkey - Press key | |||
| /// </summary> | |||
| private void HotkeyDown(object sender, KeyEventArgs e) | |||
| { | |||
| StringBuilder sb = new StringBuilder(); | |||
| //Combination key only | |||
| if (e.Modifiers != 0) | |||
| { | |||
| // XXX: Hotkey parsing depends on the sequence, more specifically, ModifierKeysConverter. | |||
| // Windows key is reserved by operating system, we deny this key. | |||
| if (e.Control) | |||
| { | |||
| sb.Append("Ctrl+"); | |||
| } | |||
| if (e.Alt) | |||
| { | |||
| sb.Append("Alt+"); | |||
| } | |||
| if (e.Shift) | |||
| { | |||
| sb.Append("Shift+"); | |||
| } | |||
| Keys keyvalue = (Keys)e.KeyValue; | |||
| if ((keyvalue >= Keys.PageUp && keyvalue <= Keys.Down) || | |||
| (keyvalue >= Keys.A && keyvalue <= Keys.Z) || | |||
| (keyvalue >= Keys.F1 && keyvalue <= Keys.F12)) | |||
| { | |||
| sb.Append(e.KeyCode); | |||
| } | |||
| else if (keyvalue >= Keys.D0 && keyvalue <= Keys.D9) | |||
| { | |||
| sb.Append('D').Append((char)e.KeyValue); | |||
| } | |||
| else if (keyvalue >= Keys.NumPad0 && keyvalue <= Keys.NumPad9) | |||
| { | |||
| sb.Append("NumPad").Append((char)(e.KeyValue - 48)); | |||
| } | |||
| } | |||
| ((TextBox)sender).Text = sb.ToString(); | |||
| } | |||
| /// <summary> | |||
| /// Capture hotkey - Release key | |||
| /// </summary> | |||
| private void HotkeyUp(object sender, KeyEventArgs e) | |||
| { | |||
| var tb = (TextBox)sender; | |||
| var content = tb.Text.TrimEnd(); | |||
| if (content.Length >= 1 && content[content.Length - 1] == '+') | |||
| { | |||
| tb.Text = ""; | |||
| } | |||
| } | |||
| private void CancelButton_Click(object sender, EventArgs e) | |||
| { | |||
| this.Close(); | |||
| } | |||
| private void OKButton_Click(object sender, EventArgs e) | |||
| { | |||
| _modifiedHotkeyConfig = GetConfigFromUI(); | |||
| // try to register, notify to change settings if failed | |||
| if (!RegisterAllHotkeys(_modifiedHotkeyConfig)) | |||
| { | |||
| MessageBox.Show(I18N.GetString("Register hotkey failed")); | |||
| } | |||
| // All check passed, saving | |||
| SaveConfig(); | |||
| this.Close(); | |||
| } | |||
| private void RegisterAllButton_Click(object sender, EventArgs e) | |||
| { | |||
| _modifiedHotkeyConfig = GetConfigFromUI(); | |||
| RegisterAllHotkeys(_modifiedHotkeyConfig); | |||
| } | |||
| private bool RegisterAllHotkeys(HotkeyConfig hotkeyConfig) | |||
| { | |||
| return | |||
| RegHotkeyFromString(hotkeyConfig.SwitchSystemProxy, "SwitchSystemProxyCallback", result => HandleRegResult(hotkeyConfig.SwitchSystemProxy, SwitchSystemProxyLabel, result)) | |||
| && RegHotkeyFromString(hotkeyConfig.SwitchSystemProxyMode, "SwitchSystemProxyModeCallback", result => HandleRegResult(hotkeyConfig.SwitchSystemProxyMode, SwitchProxyModeLabel, result)) | |||
| && RegHotkeyFromString(hotkeyConfig.SwitchAllowLan, "SwitchAllowLanCallback", result => HandleRegResult(hotkeyConfig.SwitchAllowLan, SwitchAllowLanLabel, result)) | |||
| && RegHotkeyFromString(hotkeyConfig.ShowLogs, "ShowLogsCallback", result => HandleRegResult(hotkeyConfig.ShowLogs, ShowLogsLabel, result)) | |||
| && RegHotkeyFromString(hotkeyConfig.ServerMoveUp, "ServerMoveUpCallback", result => HandleRegResult(hotkeyConfig.ServerMoveUp, ServerMoveUpLabel, result)) | |||
| && RegHotkeyFromString(hotkeyConfig.ServerMoveDown, "ServerMoveDownCallback", result => HandleRegResult(hotkeyConfig.ServerMoveDown, ServerMoveDownLabel, result)); | |||
| } | |||
| private void HandleRegResult(string hotkeyStr, Label label, RegResult result) | |||
| { | |||
| switch (result) | |||
| { | |||
| case RegResult.ParseError: | |||
| MessageBox.Show(I18N.GetString("Cannot parse hotkey: {0}", hotkeyStr)); | |||
| break; | |||
| case RegResult.UnregSuccess: | |||
| label.ResetBackColor(); | |||
| break; | |||
| case RegResult.RegSuccess: | |||
| label.BackColor = Color.Green; | |||
| break; | |||
| case RegResult.RegFailure: | |||
| label.BackColor = Color.Red; | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,346 +0,0 @@ | |||
| namespace Shadowsocks.View | |||
| { | |||
| partial class HotkeySettingsForm | |||
| { | |||
| /// <summary> | |||
| /// Required designer variable. | |||
| /// </summary> | |||
| private System.ComponentModel.IContainer components = null; | |||
| /// <summary> | |||
| /// Clean up any resources being used. | |||
| /// </summary> | |||
| /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||
| protected override void Dispose(bool disposing) | |||
| { | |||
| if (disposing && (components != null)) | |||
| { | |||
| components.Dispose(); | |||
| } | |||
| base.Dispose(disposing); | |||
| } | |||
| #region Windows Form Designer generated code | |||
| /// <summary> | |||
| /// Required method for Designer support - do not modify | |||
| /// the contents of this method with the code editor. | |||
| /// </summary> | |||
| private void InitializeComponent() | |||
| { | |||
| System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; | |||
| this.btnOK = new System.Windows.Forms.Button(); | |||
| this.btnCancel = new System.Windows.Forms.Button(); | |||
| this.btnRegisterAll = new System.Windows.Forms.Button(); | |||
| this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); | |||
| this.RegHotkeysAtStartupLabel = new System.Windows.Forms.Label(); | |||
| this.SwitchSystemProxyLabel = new System.Windows.Forms.Label(); | |||
| this.SwitchProxyModeLabel = new System.Windows.Forms.Label(); | |||
| this.SwitchAllowLanLabel = new System.Windows.Forms.Label(); | |||
| this.ShowLogsLabel = new System.Windows.Forms.Label(); | |||
| this.ServerMoveUpLabel = new System.Windows.Forms.Label(); | |||
| this.ServerMoveDownLabel = new System.Windows.Forms.Label(); | |||
| this.SwitchSystemProxyTextBox = new System.Windows.Forms.TextBox(); | |||
| this.SwitchProxyModeTextBox = new System.Windows.Forms.TextBox(); | |||
| this.SwitchAllowLanTextBox = new System.Windows.Forms.TextBox(); | |||
| this.ShowLogsTextBox = new System.Windows.Forms.TextBox(); | |||
| this.ServerMoveUpTextBox = new System.Windows.Forms.TextBox(); | |||
| this.ServerMoveDownTextBox = new System.Windows.Forms.TextBox(); | |||
| this.RegHotkeysAtStartupCheckBox = new System.Windows.Forms.CheckBox(); | |||
| flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); | |||
| flowLayoutPanel1.SuspendLayout(); | |||
| this.tableLayoutPanel1.SuspendLayout(); | |||
| this.SuspendLayout(); | |||
| // | |||
| // flowLayoutPanel1 | |||
| // | |||
| this.tableLayoutPanel1.SetColumnSpan(flowLayoutPanel1, 2); | |||
| flowLayoutPanel1.Controls.Add(this.btnOK); | |||
| flowLayoutPanel1.Controls.Add(this.btnCancel); | |||
| flowLayoutPanel1.Controls.Add(this.btnRegisterAll); | |||
| flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.BottomUp; | |||
| flowLayoutPanel1.Location = new System.Drawing.Point(0, 248); | |||
| flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); | |||
| flowLayoutPanel1.Name = "flowLayoutPanel1"; | |||
| flowLayoutPanel1.Padding = new System.Windows.Forms.Padding(0, 0, 20, 0); | |||
| flowLayoutPanel1.RightToLeft = System.Windows.Forms.RightToLeft.Yes; | |||
| flowLayoutPanel1.Size = new System.Drawing.Size(594, 52); | |||
| flowLayoutPanel1.TabIndex = 6; | |||
| // | |||
| // btnOK | |||
| // | |||
| this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; | |||
| this.btnOK.Location = new System.Drawing.Point(416, 9); | |||
| this.btnOK.Margin = new System.Windows.Forms.Padding(4); | |||
| this.btnOK.Name = "btnOK"; | |||
| this.btnOK.Size = new System.Drawing.Size(154, 39); | |||
| this.btnOK.TabIndex = 0; | |||
| this.btnOK.Text = "OK"; | |||
| this.btnOK.UseVisualStyleBackColor = true; | |||
| this.btnOK.Click += new System.EventHandler(this.OKButton_Click); | |||
| // | |||
| // btnCancel | |||
| // | |||
| this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; | |||
| this.btnCancel.Location = new System.Drawing.Point(254, 9); | |||
| this.btnCancel.Margin = new System.Windows.Forms.Padding(4); | |||
| this.btnCancel.Name = "btnCancel"; | |||
| this.btnCancel.Size = new System.Drawing.Size(154, 39); | |||
| this.btnCancel.TabIndex = 1; | |||
| this.btnCancel.Text = "Cancel"; | |||
| this.btnCancel.UseVisualStyleBackColor = true; | |||
| this.btnCancel.Click += new System.EventHandler(this.CancelButton_Click); | |||
| // | |||
| // btnRegisterAll | |||
| // | |||
| this.btnRegisterAll.DialogResult = System.Windows.Forms.DialogResult.Cancel; | |||
| this.btnRegisterAll.Location = new System.Drawing.Point(92, 9); | |||
| this.btnRegisterAll.Margin = new System.Windows.Forms.Padding(4); | |||
| this.btnRegisterAll.Name = "btnRegisterAll"; | |||
| this.btnRegisterAll.Size = new System.Drawing.Size(154, 39); | |||
| this.btnRegisterAll.TabIndex = 2; | |||
| this.btnRegisterAll.Text = "Reg All"; | |||
| this.btnRegisterAll.UseVisualStyleBackColor = true; | |||
| this.btnRegisterAll.Click += new System.EventHandler(this.RegisterAllButton_Click); | |||
| // | |||
| // tableLayoutPanel1 | |||
| // | |||
| this.tableLayoutPanel1.ColumnCount = 2; | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||
| this.tableLayoutPanel1.Controls.Add(this.RegHotkeysAtStartupLabel, 0, 6); | |||
| this.tableLayoutPanel1.Controls.Add(this.SwitchSystemProxyLabel, 0, 0); | |||
| this.tableLayoutPanel1.Controls.Add(this.SwitchProxyModeLabel, 0, 1); | |||
| this.tableLayoutPanel1.Controls.Add(this.SwitchAllowLanLabel, 0, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.ShowLogsLabel, 0, 3); | |||
| this.tableLayoutPanel1.Controls.Add(this.ServerMoveUpLabel, 0, 4); | |||
| this.tableLayoutPanel1.Controls.Add(this.ServerMoveDownLabel, 0, 5); | |||
| this.tableLayoutPanel1.Controls.Add(flowLayoutPanel1, 0, 7); | |||
| this.tableLayoutPanel1.Controls.Add(this.SwitchSystemProxyTextBox, 1, 0); | |||
| this.tableLayoutPanel1.Controls.Add(this.SwitchProxyModeTextBox, 1, 1); | |||
| this.tableLayoutPanel1.Controls.Add(this.SwitchAllowLanTextBox, 1, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.ShowLogsTextBox, 1, 3); | |||
| this.tableLayoutPanel1.Controls.Add(this.ServerMoveUpTextBox, 1, 4); | |||
| this.tableLayoutPanel1.Controls.Add(this.ServerMoveDownTextBox, 1, 5); | |||
| this.tableLayoutPanel1.Controls.Add(this.RegHotkeysAtStartupCheckBox, 1, 6); | |||
| this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); | |||
| this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4); | |||
| this.tableLayoutPanel1.Name = "tableLayoutPanel1"; | |||
| this.tableLayoutPanel1.RowCount = 8; | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.7784F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.38949F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16309F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); | |||
| this.tableLayoutPanel1.Size = new System.Drawing.Size(582, 303); | |||
| this.tableLayoutPanel1.TabIndex = 0; | |||
| // | |||
| // RegHotkeysAtStartupLabel | |||
| // | |||
| this.RegHotkeysAtStartupLabel.AutoSize = true; | |||
| this.RegHotkeysAtStartupLabel.Dock = System.Windows.Forms.DockStyle.Right; | |||
| this.RegHotkeysAtStartupLabel.Location = new System.Drawing.Point(40, 213); | |||
| this.RegHotkeysAtStartupLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); | |||
| this.RegHotkeysAtStartupLabel.Name = "RegHotkeysAtStartupLabel"; | |||
| this.RegHotkeysAtStartupLabel.Size = new System.Drawing.Size(199, 35); | |||
| this.RegHotkeysAtStartupLabel.TabIndex = 16; | |||
| this.RegHotkeysAtStartupLabel.Text = "Reg Hotkeys At Startup"; | |||
| this.RegHotkeysAtStartupLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
| // | |||
| // SwitchSystemProxyLabel | |||
| // | |||
| this.SwitchSystemProxyLabel.AutoSize = true; | |||
| this.SwitchSystemProxyLabel.Dock = System.Windows.Forms.DockStyle.Right; | |||
| this.SwitchSystemProxyLabel.Location = new System.Drawing.Point(63, 0); | |||
| this.SwitchSystemProxyLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); | |||
| this.SwitchSystemProxyLabel.Name = "SwitchSystemProxyLabel"; | |||
| this.SwitchSystemProxyLabel.Size = new System.Drawing.Size(176, 35); | |||
| this.SwitchSystemProxyLabel.TabIndex = 0; | |||
| this.SwitchSystemProxyLabel.Text = "Switch system proxy"; | |||
| this.SwitchSystemProxyLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
| // | |||
| // SwitchProxyModeLabel | |||
| // | |||
| this.SwitchProxyModeLabel.AutoSize = true; | |||
| this.SwitchProxyModeLabel.Dock = System.Windows.Forms.DockStyle.Right; | |||
| this.SwitchProxyModeLabel.Location = new System.Drawing.Point(10, 35); | |||
| this.SwitchProxyModeLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); | |||
| this.SwitchProxyModeLabel.Name = "SwitchProxyModeLabel"; | |||
| this.SwitchProxyModeLabel.Size = new System.Drawing.Size(229, 35); | |||
| this.SwitchProxyModeLabel.TabIndex = 1; | |||
| this.SwitchProxyModeLabel.Text = "Switch system proxy mode"; | |||
| this.SwitchProxyModeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
| // | |||
| // SwitchAllowLanLabel | |||
| // | |||
| this.SwitchAllowLanLabel.AutoSize = true; | |||
| this.SwitchAllowLanLabel.Dock = System.Windows.Forms.DockStyle.Right; | |||
| this.SwitchAllowLanLabel.Location = new System.Drawing.Point(39, 70); | |||
| this.SwitchAllowLanLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); | |||
| this.SwitchAllowLanLabel.Name = "SwitchAllowLanLabel"; | |||
| this.SwitchAllowLanLabel.Size = new System.Drawing.Size(200, 35); | |||
| this.SwitchAllowLanLabel.TabIndex = 3; | |||
| this.SwitchAllowLanLabel.Text = "Allow Clients from LAN"; | |||
| this.SwitchAllowLanLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
| // | |||
| // ShowLogsLabel | |||
| // | |||
| this.ShowLogsLabel.AutoSize = true; | |||
| this.ShowLogsLabel.Dock = System.Windows.Forms.DockStyle.Right; | |||
| this.ShowLogsLabel.Location = new System.Drawing.Point(129, 105); | |||
| this.ShowLogsLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); | |||
| this.ShowLogsLabel.Name = "ShowLogsLabel"; | |||
| this.ShowLogsLabel.Size = new System.Drawing.Size(110, 35); | |||
| this.ShowLogsLabel.TabIndex = 4; | |||
| this.ShowLogsLabel.Text = "Show Logs..."; | |||
| this.ShowLogsLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
| // | |||
| // ServerMoveUpLabel | |||
| // | |||
| this.ServerMoveUpLabel.AutoSize = true; | |||
| this.ServerMoveUpLabel.Dock = System.Windows.Forms.DockStyle.Right; | |||
| this.ServerMoveUpLabel.Location = new System.Drawing.Point(25, 140); | |||
| this.ServerMoveUpLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); | |||
| this.ServerMoveUpLabel.Name = "ServerMoveUpLabel"; | |||
| this.ServerMoveUpLabel.Size = new System.Drawing.Size(214, 37); | |||
| this.ServerMoveUpLabel.TabIndex = 4; | |||
| this.ServerMoveUpLabel.Text = "Switch to previous server"; | |||
| this.ServerMoveUpLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
| // | |||
| // ServerMoveDownLabel | |||
| // | |||
| this.ServerMoveDownLabel.AutoSize = true; | |||
| this.ServerMoveDownLabel.Dock = System.Windows.Forms.DockStyle.Right; | |||
| this.ServerMoveDownLabel.Location = new System.Drawing.Point(60, 177); | |||
| this.ServerMoveDownLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); | |||
| this.ServerMoveDownLabel.Name = "ServerMoveDownLabel"; | |||
| this.ServerMoveDownLabel.Size = new System.Drawing.Size(179, 36); | |||
| this.ServerMoveDownLabel.TabIndex = 4; | |||
| this.ServerMoveDownLabel.Text = "Switch to next server"; | |||
| this.ServerMoveDownLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
| // | |||
| // SwitchSystemProxyTextBox | |||
| // | |||
| this.SwitchSystemProxyTextBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.SwitchSystemProxyTextBox.Location = new System.Drawing.Point(252, 3); | |||
| this.SwitchSystemProxyTextBox.Name = "SwitchSystemProxyTextBox"; | |||
| this.SwitchSystemProxyTextBox.ReadOnly = true; | |||
| this.SwitchSystemProxyTextBox.Size = new System.Drawing.Size(339, 29); | |||
| this.SwitchSystemProxyTextBox.TabIndex = 7; | |||
| this.SwitchSystemProxyTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); | |||
| this.SwitchSystemProxyTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); | |||
| // | |||
| // SwitchProxyModeTextBox | |||
| // | |||
| this.SwitchProxyModeTextBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.SwitchProxyModeTextBox.Location = new System.Drawing.Point(252, 38); | |||
| this.SwitchProxyModeTextBox.Name = "SwitchProxyModeTextBox"; | |||
| this.SwitchProxyModeTextBox.ReadOnly = true; | |||
| this.SwitchProxyModeTextBox.Size = new System.Drawing.Size(339, 29); | |||
| this.SwitchProxyModeTextBox.TabIndex = 8; | |||
| this.SwitchProxyModeTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); | |||
| this.SwitchProxyModeTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); | |||
| // | |||
| // SwitchAllowLanTextBox | |||
| // | |||
| this.SwitchAllowLanTextBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.SwitchAllowLanTextBox.Location = new System.Drawing.Point(252, 73); | |||
| this.SwitchAllowLanTextBox.Name = "SwitchAllowLanTextBox"; | |||
| this.SwitchAllowLanTextBox.ReadOnly = true; | |||
| this.SwitchAllowLanTextBox.Size = new System.Drawing.Size(339, 29); | |||
| this.SwitchAllowLanTextBox.TabIndex = 10; | |||
| this.SwitchAllowLanTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); | |||
| this.SwitchAllowLanTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); | |||
| // | |||
| // ShowLogsTextBox | |||
| // | |||
| this.ShowLogsTextBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.ShowLogsTextBox.Location = new System.Drawing.Point(252, 108); | |||
| this.ShowLogsTextBox.Name = "ShowLogsTextBox"; | |||
| this.ShowLogsTextBox.ReadOnly = true; | |||
| this.ShowLogsTextBox.Size = new System.Drawing.Size(339, 29); | |||
| this.ShowLogsTextBox.TabIndex = 11; | |||
| this.ShowLogsTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); | |||
| this.ShowLogsTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); | |||
| // | |||
| // ServerMoveUpTextBox | |||
| // | |||
| this.ServerMoveUpTextBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.ServerMoveUpTextBox.Location = new System.Drawing.Point(252, 143); | |||
| this.ServerMoveUpTextBox.Name = "ServerMoveUpTextBox"; | |||
| this.ServerMoveUpTextBox.ReadOnly = true; | |||
| this.ServerMoveUpTextBox.Size = new System.Drawing.Size(339, 29); | |||
| this.ServerMoveUpTextBox.TabIndex = 12; | |||
| this.ServerMoveUpTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); | |||
| this.ServerMoveUpTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); | |||
| // | |||
| // ServerMoveDownTextBox | |||
| // | |||
| this.ServerMoveDownTextBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.ServerMoveDownTextBox.Location = new System.Drawing.Point(252, 180); | |||
| this.ServerMoveDownTextBox.Name = "ServerMoveDownTextBox"; | |||
| this.ServerMoveDownTextBox.ReadOnly = true; | |||
| this.ServerMoveDownTextBox.Size = new System.Drawing.Size(339, 29); | |||
| this.ServerMoveDownTextBox.TabIndex = 13; | |||
| this.ServerMoveDownTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); | |||
| this.ServerMoveDownTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); | |||
| // | |||
| // RegHotkeysAtStartupCheckBox | |||
| // | |||
| this.RegHotkeysAtStartupCheckBox.AutoSize = true; | |||
| this.RegHotkeysAtStartupCheckBox.Dock = System.Windows.Forms.DockStyle.Left; | |||
| this.RegHotkeysAtStartupCheckBox.Location = new System.Drawing.Point(252, 216); | |||
| this.RegHotkeysAtStartupCheckBox.Name = "RegHotkeysAtStartupCheckBox"; | |||
| this.RegHotkeysAtStartupCheckBox.Size = new System.Drawing.Size(18, 29); | |||
| this.RegHotkeysAtStartupCheckBox.TabIndex = 17; | |||
| this.RegHotkeysAtStartupCheckBox.UseVisualStyleBackColor = true; | |||
| // | |||
| // HotkeySettingsForm | |||
| // | |||
| this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); | |||
| this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; | |||
| this.ClientSize = new System.Drawing.Size(582, 303); | |||
| this.Controls.Add(this.tableLayoutPanel1); | |||
| this.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); | |||
| this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; | |||
| this.Margin = new System.Windows.Forms.Padding(5, 6, 5, 6); | |||
| this.MaximizeBox = false; | |||
| this.MinimizeBox = false; | |||
| this.Name = "HotkeySettingsForm"; | |||
| this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; | |||
| this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | |||
| this.Text = "Edit Hotkeys..."; | |||
| flowLayoutPanel1.ResumeLayout(false); | |||
| this.tableLayoutPanel1.ResumeLayout(false); | |||
| this.tableLayoutPanel1.PerformLayout(); | |||
| this.ResumeLayout(false); | |||
| } | |||
| #endregion | |||
| private System.Windows.Forms.Label SwitchSystemProxyLabel; | |||
| private System.Windows.Forms.Label SwitchProxyModeLabel; | |||
| private System.Windows.Forms.Label SwitchAllowLanLabel; | |||
| private System.Windows.Forms.Label ShowLogsLabel; | |||
| private System.Windows.Forms.Label ServerMoveUpLabel; | |||
| private System.Windows.Forms.Label ServerMoveDownLabel; | |||
| private System.Windows.Forms.Button btnOK; | |||
| private System.Windows.Forms.Button btnCancel; | |||
| private System.Windows.Forms.TextBox ShowLogsTextBox; | |||
| private System.Windows.Forms.TextBox SwitchAllowLanTextBox; | |||
| private System.Windows.Forms.TextBox SwitchProxyModeTextBox; | |||
| private System.Windows.Forms.TextBox SwitchSystemProxyTextBox; | |||
| private System.Windows.Forms.TextBox ServerMoveUpTextBox; | |||
| private System.Windows.Forms.TextBox ServerMoveDownTextBox; | |||
| private System.Windows.Forms.Button btnRegisterAll; | |||
| private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; | |||
| private System.Windows.Forms.Label RegHotkeysAtStartupLabel; | |||
| private System.Windows.Forms.CheckBox RegHotkeysAtStartupCheckBox; | |||
| } | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| using NLog; | |||
| using Shadowsocks.Controller; | |||
| using Shadowsocks.Localization; | |||
| using Shadowsocks.Model; | |||
| using Shadowsocks.Properties; | |||
| using Shadowsocks.Util; | |||
| @@ -11,6 +12,8 @@ using System.IO; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Windows.Forms; | |||
| using System.Windows.Forms.Integration; | |||
| using System.Windows.Threading; | |||
| using ZXing; | |||
| using ZXing.Common; | |||
| using ZXing.QrCode; | |||
| @@ -19,18 +22,14 @@ namespace Shadowsocks.View | |||
| { | |||
| public class MenuViewController | |||
| { | |||
| private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
| // yes this is just a menu view controller | |||
| // when config form is closed, it moves away from RAM | |||
| // and it should just do anything related to the config form | |||
| private readonly Logger logger = LogManager.GetCurrentClassLogger(); | |||
| private ShadowsocksController controller; | |||
| private UpdateChecker updateChecker; | |||
| public UpdateChecker updateChecker; | |||
| private NotifyIcon _notifyIcon; | |||
| private Icon icon, icon_in, icon_out, icon_both, previousIcon; | |||
| private bool _isStartupChecking; | |||
| private string _urlToOpen; | |||
| private ContextMenu contextMenu1; | |||
| @@ -61,12 +60,12 @@ namespace Shadowsocks.View | |||
| private MenuItem onlineConfigItem; | |||
| private ConfigForm configForm; | |||
| private ProxyForm proxyForm; | |||
| private LogForm logForm; | |||
| private HotkeySettingsForm hotkeySettingsForm; | |||
| private OnlineConfigForm onlineConfigForm; | |||
| private System.Windows.Window serverSharingWindow; | |||
| private System.Windows.Window hotkeysWindow; | |||
| private System.Windows.Window forwardProxyWindow; | |||
| private System.Windows.Window onlineConfigWindow; | |||
| // color definition for icon color transformation | |||
| private readonly Color colorMaskBlue = Color.FromArgb(255, 25, 125, 191); | |||
| @@ -102,7 +101,7 @@ namespace Shadowsocks.View | |||
| _notifyIcon.BalloonTipClosed += _notifyIcon_BalloonTipClosed; | |||
| controller.TrafficChanged += controller_TrafficChanged; | |||
| this.updateChecker = new UpdateChecker(); | |||
| updateChecker = new UpdateChecker(); | |||
| updateChecker.CheckUpdateCompleted += updateChecker_CheckUpdateCompleted; | |||
| LoadCurrentConfiguration(); | |||
| @@ -115,8 +114,7 @@ namespace Shadowsocks.View | |||
| } | |||
| else if (config.autoCheckUpdate) | |||
| { | |||
| _isStartupChecking = true; | |||
| updateChecker.CheckUpdate(config, 3000); | |||
| Dispatcher.CurrentDispatcher.Invoke(() => updateChecker.CheckForVersionUpdate(3000)); | |||
| } | |||
| } | |||
| @@ -383,36 +381,6 @@ namespace Shadowsocks.View | |||
| } | |||
| } | |||
| private void ShowProxyForm() | |||
| { | |||
| if (proxyForm != null) | |||
| { | |||
| proxyForm.Activate(); | |||
| } | |||
| else | |||
| { | |||
| proxyForm = new ProxyForm(controller); | |||
| proxyForm.Show(); | |||
| proxyForm.Activate(); | |||
| proxyForm.FormClosed += proxyForm_FormClosed; | |||
| } | |||
| } | |||
| private void ShowHotKeySettingsForm() | |||
| { | |||
| if (hotkeySettingsForm != null) | |||
| { | |||
| hotkeySettingsForm.Activate(); | |||
| } | |||
| else | |||
| { | |||
| hotkeySettingsForm = new HotkeySettingsForm(controller); | |||
| hotkeySettingsForm.Show(); | |||
| hotkeySettingsForm.Activate(); | |||
| hotkeySettingsForm.FormClosed += hotkeySettingsForm_FormClosed; | |||
| } | |||
| } | |||
| private void ShowLogForm() | |||
| { | |||
| if (logForm != null) | |||
| @@ -428,22 +396,6 @@ namespace Shadowsocks.View | |||
| } | |||
| } | |||
| private void ShowOnlineConfigForm() | |||
| { | |||
| if (onlineConfigForm != null) | |||
| { | |||
| onlineConfigForm.Activate(); | |||
| } | |||
| else | |||
| { | |||
| onlineConfigForm = new OnlineConfigForm(controller); | |||
| onlineConfigForm.Show(); | |||
| onlineConfigForm.Activate(); | |||
| onlineConfigForm.FormClosed += onlineConfigForm_FormClosed; | |||
| } | |||
| } | |||
| void logForm_FormClosed(object sender, FormClosedEventArgs e) | |||
| { | |||
| logForm.Dispose(); | |||
| @@ -468,24 +420,6 @@ namespace Shadowsocks.View | |||
| } | |||
| } | |||
| void proxyForm_FormClosed(object sender, FormClosedEventArgs e) | |||
| { | |||
| proxyForm.Dispose(); | |||
| proxyForm = null; | |||
| } | |||
| void hotkeySettingsForm_FormClosed(object sender, FormClosedEventArgs e) | |||
| { | |||
| hotkeySettingsForm.Dispose(); | |||
| hotkeySettingsForm = null; | |||
| } | |||
| void onlineConfigForm_FormClosed(object sender, FormClosedEventArgs e) | |||
| { | |||
| onlineConfigForm.Dispose(); | |||
| onlineConfigForm = null; | |||
| } | |||
| #endregion | |||
| #region Misc | |||
| @@ -500,23 +434,10 @@ namespace Shadowsocks.View | |||
| void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | |||
| { | |||
| if (updateChecker.NewVersionFound) | |||
| { | |||
| updateChecker.NewVersionFound = false; /* Reset the flag */ | |||
| if (File.Exists(updateChecker.LatestVersionLocalName)) | |||
| { | |||
| string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\""; | |||
| Process.Start("explorer.exe", argument); | |||
| } | |||
| } | |||
| } | |||
| private void _notifyIcon_BalloonTipClosed(object sender, EventArgs e) | |||
| { | |||
| if (updateChecker.NewVersionFound) | |||
| { | |||
| updateChecker.NewVersionFound = false; /* Reset the flag */ | |||
| } | |||
| } | |||
| private void notifyIcon1_Click(object sender, MouseEventArgs e) | |||
| @@ -541,8 +462,7 @@ namespace Shadowsocks.View | |||
| Configuration config = controller.GetCurrentConfiguration(); | |||
| if (config.firstRun) | |||
| return; | |||
| _isStartupChecking = true; | |||
| updateChecker.CheckUpdate(config, 3000); | |||
| Dispatcher.CurrentDispatcher.Invoke(() => updateChecker.CheckForVersionUpdate(3000)); | |||
| } | |||
| public void ShowLogForm_HotKey() | |||
| @@ -561,19 +481,83 @@ namespace Shadowsocks.View | |||
| private void proxyItem_Click(object sender, EventArgs e) | |||
| { | |||
| ShowProxyForm(); | |||
| if (forwardProxyWindow == null) | |||
| { | |||
| forwardProxyWindow = new System.Windows.Window() | |||
| { | |||
| Title = LocalizationProvider.GetLocalizedValue<string>("ForwardProxy"), | |||
| Height = 400, | |||
| Width = 280, | |||
| MinHeight = 400, | |||
| MinWidth = 280, | |||
| Content = new ForwardProxyView() | |||
| }; | |||
| forwardProxyWindow.Closed += ForwardProxyWindow_Closed; | |||
| ElementHost.EnableModelessKeyboardInterop(forwardProxyWindow); | |||
| forwardProxyWindow.Show(); | |||
| } | |||
| forwardProxyWindow.Activate(); | |||
| } | |||
| private void ForwardProxyWindow_Closed(object sender, EventArgs e) | |||
| { | |||
| forwardProxyWindow = null; | |||
| } | |||
| public void CloseForwardProxyWindow() => forwardProxyWindow.Close(); | |||
| private void OnlineConfig_Click(object sender, EventArgs e) | |||
| { | |||
| ShowOnlineConfigForm(); | |||
| if (onlineConfigWindow == null) | |||
| { | |||
| onlineConfigWindow = new System.Windows.Window() | |||
| { | |||
| Title = LocalizationProvider.GetLocalizedValue<string>("OnlineConfigDelivery"), | |||
| Height = 510, | |||
| Width = 480, | |||
| MinHeight = 510, | |||
| MinWidth = 480, | |||
| Content = new OnlineConfigView() | |||
| }; | |||
| onlineConfigWindow.Closed += OnlineConfigWindow_Closed; | |||
| ElementHost.EnableModelessKeyboardInterop(onlineConfigWindow); | |||
| onlineConfigWindow.Show(); | |||
| } | |||
| onlineConfigWindow.Activate(); | |||
| } | |||
| private void OnlineConfigWindow_Closed(object sender, EventArgs e) | |||
| { | |||
| onlineConfigWindow = null; | |||
| } | |||
| private void hotKeyItem_Click(object sender, EventArgs e) | |||
| { | |||
| ShowHotKeySettingsForm(); | |||
| if (hotkeysWindow == null) | |||
| { | |||
| hotkeysWindow = new System.Windows.Window() | |||
| { | |||
| Title = LocalizationProvider.GetLocalizedValue<string>("Hotkeys"), | |||
| Height = 260, | |||
| Width = 320, | |||
| MinHeight = 260, | |||
| MinWidth = 320, | |||
| Content = new HotkeysView() | |||
| }; | |||
| hotkeysWindow.Closed += HotkeysWindow_Closed; | |||
| ElementHost.EnableModelessKeyboardInterop(hotkeysWindow); | |||
| hotkeysWindow.Show(); | |||
| } | |||
| hotkeysWindow.Activate(); | |||
| } | |||
| private void HotkeysWindow_Closed(object sender, EventArgs e) | |||
| { | |||
| hotkeysWindow = null; | |||
| } | |||
| public void CloseHotkeysWindow() => hotkeysWindow.Close(); | |||
| private void ShareOverLANItem_Click(object sender, EventArgs e) | |||
| { | |||
| ShareOverLANItem.Checked = !ShareOverLANItem.Checked; | |||
| @@ -750,12 +734,15 @@ namespace Shadowsocks.View | |||
| { | |||
| serverSharingWindow = new System.Windows.Window() | |||
| { | |||
| Title = "Server Sharing", | |||
| Title = LocalizationProvider.GetLocalizedValue<string>("ServerSharing"), | |||
| Height = 400, | |||
| Width = 660, | |||
| MinHeight = 400, | |||
| MinWidth = 660, | |||
| Content = new ServerSharingView() | |||
| }; | |||
| serverSharingWindow.Closed += ServerSharingWindow_Closed; | |||
| ElementHost.EnableModelessKeyboardInterop(serverSharingWindow); | |||
| serverSharingWindow.Show(); | |||
| } | |||
| serverSharingWindow.Activate(); | |||
| @@ -1017,15 +1004,10 @@ namespace Shadowsocks.View | |||
| void updateChecker_CheckUpdateCompleted(object sender, EventArgs e) | |||
| { | |||
| if (updateChecker.NewVersionFound) | |||
| { | |||
| ShowBalloonTip(I18N.GetString("Shadowsocks {0} Update Found", updateChecker.LatestVersionNumber + updateChecker.LatestVersionSuffix), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); | |||
| } | |||
| else if (!_isStartupChecking) | |||
| if (updateChecker.NewReleaseZipFilename == null) | |||
| { | |||
| ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("No update is available"), ToolTipIcon.Info, 5000); | |||
| } | |||
| _isStartupChecking = false; | |||
| } | |||
| private void UpdateUpdateMenu() | |||
| @@ -1049,9 +1031,9 @@ namespace Shadowsocks.View | |||
| UpdateUpdateMenu(); | |||
| } | |||
| private void checkUpdatesItem_Click(object sender, EventArgs e) | |||
| private async void checkUpdatesItem_Click(object sender, EventArgs e) | |||
| { | |||
| updateChecker.CheckUpdate(controller.GetCurrentConfiguration()); | |||
| await updateChecker.CheckForVersionUpdate(); | |||
| } | |||
| private void AboutItem_Click(object sender, EventArgs e) | |||
| @@ -1,218 +0,0 @@ | |||
| namespace Shadowsocks.View | |||
| { | |||
| partial class OnlineConfigForm | |||
| { | |||
| /// <summary> | |||
| /// Required designer variable. | |||
| /// </summary> | |||
| private System.ComponentModel.IContainer components = null; | |||
| /// <summary> | |||
| /// Clean up any resources being used. | |||
| /// </summary> | |||
| /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||
| protected override void Dispose(bool disposing) | |||
| { | |||
| if (disposing && (components != null)) | |||
| { | |||
| components.Dispose(); | |||
| } | |||
| base.Dispose(disposing); | |||
| } | |||
| #region Windows Form Designer generated code | |||
| /// <summary> | |||
| /// Required method for Designer support - do not modify | |||
| /// the contents of this method with the code editor. | |||
| /// </summary> | |||
| private void InitializeComponent() | |||
| { | |||
| this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); | |||
| this.UrlListBox = new System.Windows.Forms.ListBox(); | |||
| this.label1 = new System.Windows.Forms.Label(); | |||
| this.UrlTextBox = new System.Windows.Forms.TextBox(); | |||
| this.UpdateButton = new System.Windows.Forms.Button(); | |||
| this.AddButton = new System.Windows.Forms.Button(); | |||
| this.DeleteButton = new System.Windows.Forms.Button(); | |||
| this.OkButton = new System.Windows.Forms.Button(); | |||
| this.UpdateAllButton = new System.Windows.Forms.Button(); | |||
| this.CancelButton = new System.Windows.Forms.Button(); | |||
| this.tableLayoutPanel1.SuspendLayout(); | |||
| this.SuspendLayout(); | |||
| // | |||
| // tableLayoutPanel1 | |||
| // | |||
| this.tableLayoutPanel1.ColumnCount = 3; | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); | |||
| this.tableLayoutPanel1.Controls.Add(this.UrlListBox, 0, 0); | |||
| this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1); | |||
| this.tableLayoutPanel1.Controls.Add(this.UrlTextBox, 1, 1); | |||
| this.tableLayoutPanel1.Controls.Add(this.UpdateButton, 0, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.AddButton, 1, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.DeleteButton, 2, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.OkButton, 1, 3); | |||
| this.tableLayoutPanel1.Controls.Add(this.UpdateAllButton, 0, 3); | |||
| this.tableLayoutPanel1.Controls.Add(this.CancelButton, 2, 3); | |||
| this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); | |||
| this.tableLayoutPanel1.Name = "tableLayoutPanel1"; | |||
| this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3); | |||
| this.tableLayoutPanel1.RowCount = 4; | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
| this.tableLayoutPanel1.Size = new System.Drawing.Size(482, 453); | |||
| this.tableLayoutPanel1.TabIndex = 0; | |||
| // | |||
| // UrlListBox | |||
| // | |||
| this.tableLayoutPanel1.SetColumnSpan(this.UrlListBox, 3); | |||
| this.UrlListBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.UrlListBox.FormattingEnabled = true; | |||
| this.UrlListBox.ItemHeight = 15; | |||
| this.UrlListBox.Location = new System.Drawing.Point(13, 13); | |||
| this.UrlListBox.Margin = new System.Windows.Forms.Padding(10); | |||
| this.UrlListBox.Name = "UrlListBox"; | |||
| this.UrlListBox.Size = new System.Drawing.Size(456, 334); | |||
| this.UrlListBox.TabIndex = 0; | |||
| this.UrlListBox.SelectedIndexChanged += new System.EventHandler(this.UrlListBox_SelectedIndexChanged); | |||
| // | |||
| // label1 | |||
| // | |||
| this.label1.AutoSize = true; | |||
| this.label1.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.label1.Location = new System.Drawing.Point(6, 357); | |||
| this.label1.Name = "label1"; | |||
| this.label1.Size = new System.Drawing.Size(152, 31); | |||
| this.label1.TabIndex = 1; | |||
| this.label1.Text = "Online config URL"; | |||
| this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; | |||
| // | |||
| // UrlTextBox | |||
| // | |||
| this.tableLayoutPanel1.SetColumnSpan(this.UrlTextBox, 2); | |||
| this.UrlTextBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.UrlTextBox.Location = new System.Drawing.Point(164, 360); | |||
| this.UrlTextBox.Margin = new System.Windows.Forms.Padding(3, 3, 15, 3); | |||
| this.UrlTextBox.Name = "UrlTextBox"; | |||
| this.UrlTextBox.Size = new System.Drawing.Size(300, 25); | |||
| this.UrlTextBox.TabIndex = 2; | |||
| // | |||
| // UpdateButton | |||
| // | |||
| this.UpdateButton.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.UpdateButton.Location = new System.Drawing.Point(23, 391); | |||
| this.UpdateButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); | |||
| this.UpdateButton.MaximumSize = new System.Drawing.Size(0, 25); | |||
| this.UpdateButton.MinimumSize = new System.Drawing.Size(0, 25); | |||
| this.UpdateButton.Name = "UpdateButton"; | |||
| this.UpdateButton.Size = new System.Drawing.Size(118, 25); | |||
| this.UpdateButton.TabIndex = 3; | |||
| this.UpdateButton.Text = "&Update"; | |||
| this.UpdateButton.UseVisualStyleBackColor = true; | |||
| this.UpdateButton.Click += new System.EventHandler(this.UpdateButton_Click); | |||
| // | |||
| // AddButton | |||
| // | |||
| this.AddButton.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.AddButton.Location = new System.Drawing.Point(181, 391); | |||
| this.AddButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); | |||
| this.AddButton.MaximumSize = new System.Drawing.Size(0, 25); | |||
| this.AddButton.MinimumSize = new System.Drawing.Size(0, 25); | |||
| this.AddButton.Name = "AddButton"; | |||
| this.AddButton.Size = new System.Drawing.Size(118, 25); | |||
| this.AddButton.TabIndex = 4; | |||
| this.AddButton.Text = "&Add"; | |||
| this.AddButton.UseVisualStyleBackColor = true; | |||
| this.AddButton.Click += new System.EventHandler(this.AddButton_Click); | |||
| // | |||
| // DeleteButton | |||
| // | |||
| this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.DeleteButton.Location = new System.Drawing.Point(339, 391); | |||
| this.DeleteButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); | |||
| this.DeleteButton.MaximumSize = new System.Drawing.Size(0, 25); | |||
| this.DeleteButton.MinimumSize = new System.Drawing.Size(0, 25); | |||
| this.DeleteButton.Name = "DeleteButton"; | |||
| this.DeleteButton.Size = new System.Drawing.Size(120, 25); | |||
| this.DeleteButton.TabIndex = 5; | |||
| this.DeleteButton.Text = "&Delete"; | |||
| this.DeleteButton.UseVisualStyleBackColor = true; | |||
| this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); | |||
| // | |||
| // OkButton | |||
| // | |||
| this.OkButton.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.OkButton.Location = new System.Drawing.Point(181, 422); | |||
| this.OkButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); | |||
| this.OkButton.MaximumSize = new System.Drawing.Size(0, 25); | |||
| this.OkButton.MinimumSize = new System.Drawing.Size(0, 25); | |||
| this.OkButton.Name = "OkButton"; | |||
| this.OkButton.Size = new System.Drawing.Size(118, 25); | |||
| this.OkButton.TabIndex = 7; | |||
| this.OkButton.Text = "OK"; | |||
| this.OkButton.UseVisualStyleBackColor = true; | |||
| this.OkButton.Click += new System.EventHandler(this.OkButton_Click); | |||
| // | |||
| // UpdateAllButton | |||
| // | |||
| this.UpdateAllButton.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.UpdateAllButton.Location = new System.Drawing.Point(23, 422); | |||
| this.UpdateAllButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); | |||
| this.UpdateAllButton.MaximumSize = new System.Drawing.Size(0, 25); | |||
| this.UpdateAllButton.MinimumSize = new System.Drawing.Size(0, 25); | |||
| this.UpdateAllButton.Name = "UpdateAllButton"; | |||
| this.UpdateAllButton.Size = new System.Drawing.Size(118, 25); | |||
| this.UpdateAllButton.TabIndex = 6; | |||
| this.UpdateAllButton.Text = "U&pdate All"; | |||
| this.UpdateAllButton.UseVisualStyleBackColor = true; | |||
| this.UpdateAllButton.Click += new System.EventHandler(this.UpdateAllButton_Click); | |||
| // | |||
| // CancelButton | |||
| // | |||
| this.CancelButton.Dock = System.Windows.Forms.DockStyle.Fill; | |||
| this.CancelButton.Location = new System.Drawing.Point(339, 422); | |||
| this.CancelButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); | |||
| this.CancelButton.MaximumSize = new System.Drawing.Size(0, 25); | |||
| this.CancelButton.MinimumSize = new System.Drawing.Size(0, 25); | |||
| this.CancelButton.Name = "CancelButton"; | |||
| this.CancelButton.Size = new System.Drawing.Size(120, 25); | |||
| this.CancelButton.TabIndex = 8; | |||
| this.CancelButton.Text = "Cancel"; | |||
| this.CancelButton.UseVisualStyleBackColor = true; | |||
| this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); | |||
| // | |||
| // OnlineConfigForm | |||
| // | |||
| this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); | |||
| this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |||
| this.ClientSize = new System.Drawing.Size(482, 453); | |||
| this.Controls.Add(this.tableLayoutPanel1); | |||
| this.MinimizeBox = false; | |||
| this.MinimumSize = new System.Drawing.Size(400, 400); | |||
| this.Name = "OnlineConfigForm"; | |||
| this.Text = "Online config"; | |||
| this.tableLayoutPanel1.ResumeLayout(false); | |||
| this.tableLayoutPanel1.PerformLayout(); | |||
| this.ResumeLayout(false); | |||
| } | |||
| #endregion | |||
| private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; | |||
| private System.Windows.Forms.ListBox UrlListBox; | |||
| private System.Windows.Forms.Label label1; | |||
| private System.Windows.Forms.TextBox UrlTextBox; | |||
| private System.Windows.Forms.Button UpdateButton; | |||
| private System.Windows.Forms.Button AddButton; | |||
| private System.Windows.Forms.Button DeleteButton; | |||
| private System.Windows.Forms.Button OkButton; | |||
| private System.Windows.Forms.Button UpdateAllButton; | |||
| private new System.Windows.Forms.Button CancelButton; | |||
| } | |||
| } | |||
| @@ -1,153 +0,0 @@ | |||
| using System; | |||
| using System.Data; | |||
| using System.Linq; | |||
| using System.Windows.Forms; | |||
| using Shadowsocks.Controller; | |||
| using Shadowsocks.Model; | |||
| using Shadowsocks.Properties; | |||
| namespace Shadowsocks.View | |||
| { | |||
| public partial class OnlineConfigForm : Form | |||
| { | |||
| private ShadowsocksController controller; | |||
| private Configuration config; | |||
| public OnlineConfigForm(ShadowsocksController controller) | |||
| { | |||
| this.controller = controller; | |||
| InitializeComponent(); | |||
| LoadConfig(); | |||
| Icon = System.Drawing.Icon.FromHandle(Resources.ssw128.GetHicon()); | |||
| I18N.TranslateForm(this); | |||
| } | |||
| private void LoadConfig() | |||
| { | |||
| config = controller.GetCurrentConfiguration(); | |||
| var idx = UrlListBox.SelectedIndex; | |||
| UrlListBox.Items.Clear(); | |||
| foreach (var item in config.onlineConfigSource) | |||
| { | |||
| UrlListBox.Items.Add(item); | |||
| } | |||
| if (idx >= UrlListBox.Items.Count) idx = 0; | |||
| if (idx < 0 && UrlListBox.Items.Count > 0) idx = 0; | |||
| if (UrlListBox.Items.Count == 0) return; | |||
| UrlListBox.SelectedIndex = idx; | |||
| SelectItem(); | |||
| } | |||
| private void SelectItem() | |||
| { | |||
| UrlTextBox.Text = (string)UrlListBox.SelectedItem; | |||
| } | |||
| private bool ValidateUrl() | |||
| { | |||
| try | |||
| { | |||
| var scheme = new Uri(UrlTextBox.Text).Scheme; | |||
| if (scheme != "http" && scheme != "https") return false; | |||
| if (UrlListBox.Items.OfType<string>().Contains(UrlTextBox.Text)) return false; | |||
| } | |||
| catch | |||
| { | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| private void Commit() | |||
| { | |||
| if (UrlListBox.SelectedIndex < 0) return; | |||
| if ((string)UrlListBox.SelectedItem == UrlTextBox.Text) | |||
| { | |||
| LoadConfig(); | |||
| return; | |||
| } | |||
| if (ValidateUrl()) | |||
| { | |||
| UrlListBox.Items[UrlListBox.SelectedIndex] = UrlTextBox.Text; | |||
| } | |||
| controller.SaveOnlineConfigSource(UrlListBox.Items.OfType<string>().Where(s => !string.IsNullOrWhiteSpace(s)).Distinct()); | |||
| LoadConfig(); | |||
| return; | |||
| } | |||
| private void AddButton_Click(object sender, EventArgs e) | |||
| { | |||
| if (string.IsNullOrWhiteSpace(UrlTextBox.Text)) return; | |||
| UrlListBox.Items.Add(UrlTextBox.Text); | |||
| UrlListBox.SelectedIndex = UrlListBox.Items.Count - 1; | |||
| UrlTextBox.Text = ""; | |||
| Commit(); | |||
| } | |||
| private async void UpdateButton_Click(object sender, EventArgs e) | |||
| { | |||
| string old = (string)UrlListBox.SelectedItem; | |||
| // update content, also update online config | |||
| Commit(); | |||
| string current = (string)UrlListBox.SelectedItem; | |||
| if (UrlListBox.Items.Count == 0) return; | |||
| tableLayoutPanel1.Enabled = false; | |||
| bool ok = await controller.UpdateOnlineConfig(current); | |||
| if (!ok) | |||
| { | |||
| MessageBox.Show(I18N.GetString("online config failed to update")); | |||
| tableLayoutPanel1.Enabled = true; | |||
| return; | |||
| } | |||
| if (old != current) controller.RemoveOnlineConfig(old); | |||
| tableLayoutPanel1.Enabled = true; | |||
| } | |||
| private void UrlListBox_SelectedIndexChanged(object sender, EventArgs e) | |||
| { | |||
| if (!UrlListBox.CanSelect) | |||
| { | |||
| return; | |||
| } | |||
| SelectItem(); | |||
| } | |||
| private void DeleteButton_Click(object sender, EventArgs e) | |||
| { | |||
| if (UrlListBox.Items.Count == 0) return; | |||
| string url = (string)UrlListBox.SelectedItem; | |||
| if (!string.IsNullOrWhiteSpace(url)) | |||
| { | |||
| controller.RemoveOnlineConfig(url); | |||
| } | |||
| LoadConfig(); | |||
| } | |||
| private async void UpdateAllButton_Click(object sender, EventArgs e) | |||
| { | |||
| if (UrlListBox.Items.Count == 0) return; | |||
| tableLayoutPanel1.Enabled = false; | |||
| int fail = await controller.UpdateAllOnlineConfig(); | |||
| if (fail > 0) | |||
| { | |||
| MessageBox.Show(I18N.GetString("{0} online config failed to update", fail)); | |||
| } | |||
| tableLayoutPanel1.Enabled = true; | |||
| } | |||
| private void OkButton_Click(object sender, EventArgs e) | |||
| { | |||
| Commit(); | |||
| Close(); | |||
| } | |||
| private void CancelButton_Click(object sender, EventArgs e) | |||
| { | |||
| Close(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,333 +0,0 @@ | |||
| namespace Shadowsocks.View | |||
| { | |||
| partial class ProxyForm | |||
| { | |||
| /// <summary> | |||
| /// Required designer variable. | |||
| /// </summary> | |||
| private System.ComponentModel.IContainer components = null; | |||
| /// <summary> | |||
| /// Clean up any resources being used. | |||
| /// </summary> | |||
| /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||
| protected override void Dispose(bool disposing) | |||
| { | |||
| if (disposing && (components != null)) | |||
| { | |||
| components.Dispose(); | |||
| } | |||
| base.Dispose(disposing); | |||
| } | |||
| #region Windows Form Designer generated code | |||
| /// <summary> | |||
| /// Required method for Designer support - do not modify | |||
| /// the contents of this method with the code editor. | |||
| /// </summary> | |||
| private void InitializeComponent() | |||
| { | |||
| this.MyCancelButton = new System.Windows.Forms.Button(); | |||
| this.OKButton = new System.Windows.Forms.Button(); | |||
| this.UseProxyCheckBox = new System.Windows.Forms.CheckBox(); | |||
| this.ProxyAddrLabel = new System.Windows.Forms.Label(); | |||
| this.ProxyServerTextBox = new System.Windows.Forms.TextBox(); | |||
| this.ProxyPortLabel = new System.Windows.Forms.Label(); | |||
| this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); | |||
| this.ProxyTypeLabel = new System.Windows.Forms.Label(); | |||
| this.ProxyTypeComboBox = new System.Windows.Forms.ComboBox(); | |||
| this.ProxyTimeoutTextBox = new System.Windows.Forms.TextBox(); | |||
| this.ProxyTimeoutLabel = new System.Windows.Forms.Label(); | |||
| this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); | |||
| this.ProxyNotificationLabel = new System.Windows.Forms.Label(); | |||
| this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); | |||
| this.AuthUserLabel = new System.Windows.Forms.Label(); | |||
| this.AuthPwdLabel = new System.Windows.Forms.Label(); | |||
| this.UseAuthCheckBox = new System.Windows.Forms.CheckBox(); | |||
| this.AuthUserTextBox = new System.Windows.Forms.TextBox(); | |||
| this.AuthPwdTextBox = new System.Windows.Forms.TextBox(); | |||
| this.tableLayoutPanel1.SuspendLayout(); | |||
| this.flowLayoutPanel1.SuspendLayout(); | |||
| this.SuspendLayout(); | |||
| // | |||
| // MyCancelButton | |||
| // | |||
| this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; | |||
| this.MyCancelButton.Location = new System.Drawing.Point(84, 3); | |||
| this.MyCancelButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0); | |||
| this.MyCancelButton.Name = "MyCancelButton"; | |||
| this.MyCancelButton.Size = new System.Drawing.Size(75, 23); | |||
| this.MyCancelButton.TabIndex = 13; | |||
| this.MyCancelButton.Text = "Cancel"; | |||
| this.MyCancelButton.UseVisualStyleBackColor = true; | |||
| this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click); | |||
| // | |||
| // OKButton | |||
| // | |||
| this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; | |||
| this.OKButton.Location = new System.Drawing.Point(3, 3); | |||
| this.OKButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); | |||
| this.OKButton.Name = "OKButton"; | |||
| this.OKButton.Size = new System.Drawing.Size(75, 23); | |||
| this.OKButton.TabIndex = 12; | |||
| this.OKButton.Text = "OK"; | |||
| this.OKButton.UseVisualStyleBackColor = true; | |||
| this.OKButton.Click += new System.EventHandler(this.OKButton_Click); | |||
| // | |||
| // UseProxyCheckBox | |||
| // | |||
| this.UseProxyCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left; | |||
| this.UseProxyCheckBox.AutoSize = true; | |||
| this.tableLayoutPanel1.SetColumnSpan(this.UseProxyCheckBox, 2); | |||
| this.UseProxyCheckBox.Location = new System.Drawing.Point(3, 6); | |||
| this.UseProxyCheckBox.Name = "UseProxyCheckBox"; | |||
| this.UseProxyCheckBox.Size = new System.Drawing.Size(78, 16); | |||
| this.UseProxyCheckBox.TabIndex = 0; | |||
| this.UseProxyCheckBox.Text = "Use Proxy"; | |||
| this.UseProxyCheckBox.UseVisualStyleBackColor = true; | |||
| this.UseProxyCheckBox.CheckedChanged += new System.EventHandler(this.UseProxyCheckBox_CheckedChanged); | |||
| // | |||
| // ProxyAddrLabel | |||
| // | |||
| this.ProxyAddrLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyAddrLabel.AutoSize = true; | |||
| this.ProxyAddrLabel.Location = new System.Drawing.Point(3, 64); | |||
| this.ProxyAddrLabel.Name = "ProxyAddrLabel"; | |||
| this.ProxyAddrLabel.Size = new System.Drawing.Size(65, 12); | |||
| this.ProxyAddrLabel.TabIndex = 0; | |||
| this.ProxyAddrLabel.Text = "Proxy Addr"; | |||
| // | |||
| // ProxyServerTextBox | |||
| // | |||
| this.ProxyServerTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyServerTextBox.Location = new System.Drawing.Point(74, 59); | |||
| this.ProxyServerTextBox.MaxLength = 512; | |||
| this.ProxyServerTextBox.Name = "ProxyServerTextBox"; | |||
| this.ProxyServerTextBox.Size = new System.Drawing.Size(138, 21); | |||
| this.ProxyServerTextBox.TabIndex = 1; | |||
| this.ProxyServerTextBox.WordWrap = false; | |||
| // | |||
| // ProxyPortLabel | |||
| // | |||
| this.ProxyPortLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyPortLabel.AutoSize = true; | |||
| this.ProxyPortLabel.Location = new System.Drawing.Point(218, 64); | |||
| this.ProxyPortLabel.Name = "ProxyPortLabel"; | |||
| this.ProxyPortLabel.Size = new System.Drawing.Size(77, 12); | |||
| this.ProxyPortLabel.TabIndex = 2; | |||
| this.ProxyPortLabel.Text = "Proxy Port"; | |||
| // | |||
| // ProxyPortTextBox | |||
| // | |||
| this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyPortTextBox.Location = new System.Drawing.Point(301, 59); | |||
| this.ProxyPortTextBox.MaxLength = 10; | |||
| this.ProxyPortTextBox.Name = "ProxyPortTextBox"; | |||
| this.ProxyPortTextBox.Size = new System.Drawing.Size(91, 21); | |||
| this.ProxyPortTextBox.TabIndex = 3; | |||
| this.ProxyPortTextBox.WordWrap = false; | |||
| // | |||
| // ProxyTypeLabel | |||
| // | |||
| this.ProxyTypeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyTypeLabel.AutoSize = true; | |||
| this.ProxyTypeLabel.Location = new System.Drawing.Point(3, 36); | |||
| this.ProxyTypeLabel.Name = "ProxyTypeLabel"; | |||
| this.ProxyTypeLabel.Size = new System.Drawing.Size(65, 12); | |||
| this.ProxyTypeLabel.TabIndex = 1; | |||
| this.ProxyTypeLabel.Text = "Proxy Type"; | |||
| // | |||
| // ProxyTypeComboBox | |||
| // | |||
| this.ProxyTypeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; | |||
| this.ProxyTypeComboBox.FormattingEnabled = true; | |||
| this.ProxyTypeComboBox.Items.AddRange(new object[] { | |||
| "SOCKS5", | |||
| "HTTP"}); | |||
| this.ProxyTypeComboBox.Location = new System.Drawing.Point(74, 33); | |||
| this.ProxyTypeComboBox.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5); | |||
| this.ProxyTypeComboBox.Name = "ProxyTypeComboBox"; | |||
| this.ProxyTypeComboBox.Size = new System.Drawing.Size(138, 20); | |||
| this.ProxyTypeComboBox.TabIndex = 2; | |||
| this.ProxyTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.ProxyTypeComboBox_SelectedIndexChanged); | |||
| // | |||
| // ProxyTimeoutTextBox | |||
| // | |||
| this.ProxyTimeoutTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyTimeoutTextBox.Location = new System.Drawing.Point(301, 31); | |||
| this.ProxyTimeoutTextBox.Name = "ProxyTimeoutTextBox"; | |||
| this.ProxyTimeoutTextBox.Size = new System.Drawing.Size(91, 21); | |||
| this.ProxyTimeoutTextBox.TabIndex = 3; | |||
| // | |||
| // ProxyTimeoutLabel | |||
| // | |||
| this.ProxyTimeoutLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyTimeoutLabel.AutoSize = true; | |||
| this.ProxyTimeoutLabel.Location = new System.Drawing.Point(218, 36); | |||
| this.ProxyTimeoutLabel.Name = "ProxyTimeoutLabel"; | |||
| this.ProxyTimeoutLabel.Size = new System.Drawing.Size(77, 12); | |||
| this.ProxyTimeoutLabel.TabIndex = 4; | |||
| this.ProxyTimeoutLabel.Text = "Timeout(Sec)"; | |||
| // | |||
| // tableLayoutPanel1 | |||
| // | |||
| this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||
| this.tableLayoutPanel1.ColumnCount = 4; | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 60F)); | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||
| this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 40F)); | |||
| this.tableLayoutPanel1.Controls.Add(this.UseProxyCheckBox, 0, 0); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyTypeLabel, 0, 1); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyPortTextBox, 3, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyTypeComboBox, 1, 1); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyTimeoutLabel, 2, 1); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyPortLabel, 2, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyTimeoutTextBox, 3, 1); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyServerTextBox, 1, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyAddrLabel, 0, 2); | |||
| this.tableLayoutPanel1.Controls.Add(this.ProxyNotificationLabel, 0, 3); | |||
| this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 0, 6); | |||
| this.tableLayoutPanel1.Controls.Add(this.AuthUserLabel, 0, 5); | |||
| this.tableLayoutPanel1.Controls.Add(this.AuthPwdLabel, 2, 5); | |||
| this.tableLayoutPanel1.Controls.Add(this.UseAuthCheckBox, 0, 4); | |||
| this.tableLayoutPanel1.Controls.Add(this.AuthUserTextBox, 1, 5); | |||
| this.tableLayoutPanel1.Controls.Add(this.AuthPwdTextBox, 3, 5); | |||
| this.tableLayoutPanel1.Location = new System.Drawing.Point(15, 15); | |||
| this.tableLayoutPanel1.Name = "tableLayoutPanel1"; | |||
| this.tableLayoutPanel1.RowCount = 7; | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66713F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66713F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66713F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.6662F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.6662F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.6662F)); | |||
| this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
| this.tableLayoutPanel1.Size = new System.Drawing.Size(395, 204); | |||
| this.tableLayoutPanel1.TabIndex = 14; | |||
| // | |||
| // ProxyNotificationLabel | |||
| // | |||
| this.ProxyNotificationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.ProxyNotificationLabel.AutoSize = true; | |||
| this.tableLayoutPanel1.SetColumnSpan(this.ProxyNotificationLabel, 4); | |||
| this.ProxyNotificationLabel.ForeColor = System.Drawing.Color.Red; | |||
| this.ProxyNotificationLabel.Location = new System.Drawing.Point(3, 92); | |||
| this.ProxyNotificationLabel.Name = "ProxyNotificationLabel"; | |||
| this.ProxyNotificationLabel.Size = new System.Drawing.Size(389, 12); | |||
| this.ProxyNotificationLabel.TabIndex = 5; | |||
| this.ProxyNotificationLabel.Text = "If server has a plugin, proxy will not be used"; | |||
| // | |||
| // flowLayoutPanel1 | |||
| // | |||
| this.flowLayoutPanel1.AutoSize = true; | |||
| this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||
| this.tableLayoutPanel1.SetColumnSpan(this.flowLayoutPanel1, 4); | |||
| this.flowLayoutPanel1.Controls.Add(this.MyCancelButton); | |||
| this.flowLayoutPanel1.Controls.Add(this.OKButton); | |||
| this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Right; | |||
| this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; | |||
| this.flowLayoutPanel1.Location = new System.Drawing.Point(233, 171); | |||
| this.flowLayoutPanel1.Name = "flowLayoutPanel1"; | |||
| this.flowLayoutPanel1.Size = new System.Drawing.Size(159, 30); | |||
| this.flowLayoutPanel1.TabIndex = 6; | |||
| // | |||
| // AuthUserLabel | |||
| // | |||
| this.AuthUserLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.AuthUserLabel.AutoSize = true; | |||
| this.AuthUserLabel.Location = new System.Drawing.Point(3, 148); | |||
| this.AuthUserLabel.Name = "AuthUserLabel"; | |||
| this.AuthUserLabel.Size = new System.Drawing.Size(65, 12); | |||
| this.AuthUserLabel.TabIndex = 7; | |||
| this.AuthUserLabel.Text = "User Name"; | |||
| // | |||
| // AuthPwdLabel | |||
| // | |||
| this.AuthPwdLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.AuthPwdLabel.AutoSize = true; | |||
| this.AuthPwdLabel.Location = new System.Drawing.Point(218, 148); | |||
| this.AuthPwdLabel.Name = "AuthPwdLabel"; | |||
| this.AuthPwdLabel.Size = new System.Drawing.Size(77, 12); | |||
| this.AuthPwdLabel.TabIndex = 8; | |||
| this.AuthPwdLabel.Text = "Password"; | |||
| // | |||
| // UseAuthCheckBox | |||
| // | |||
| this.UseAuthCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left; | |||
| this.UseAuthCheckBox.AutoSize = true; | |||
| this.tableLayoutPanel1.SetColumnSpan(this.UseAuthCheckBox, 2); | |||
| this.UseAuthCheckBox.Location = new System.Drawing.Point(3, 118); | |||
| this.UseAuthCheckBox.Name = "UseAuthCheckBox"; | |||
| this.UseAuthCheckBox.Size = new System.Drawing.Size(72, 16); | |||
| this.UseAuthCheckBox.TabIndex = 9; | |||
| this.UseAuthCheckBox.Text = "Use Auth"; | |||
| this.UseAuthCheckBox.UseVisualStyleBackColor = true; | |||
| this.UseAuthCheckBox.CheckedChanged += new System.EventHandler(this.UseAuthCheckBox_CheckedChanged); | |||
| // | |||
| // AuthUserTextBox | |||
| // | |||
| this.AuthUserTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.AuthUserTextBox.Location = new System.Drawing.Point(74, 143); | |||
| this.AuthUserTextBox.Name = "AuthUserTextBox"; | |||
| this.AuthUserTextBox.Size = new System.Drawing.Size(138, 21); | |||
| this.AuthUserTextBox.TabIndex = 10; | |||
| // | |||
| // AuthPwdTextBox | |||
| // | |||
| this.AuthPwdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
| this.AuthPwdTextBox.Location = new System.Drawing.Point(301, 143); | |||
| this.AuthPwdTextBox.Name = "AuthPwdTextBox"; | |||
| this.AuthPwdTextBox.PasswordChar = '*'; | |||
| this.AuthPwdTextBox.Size = new System.Drawing.Size(91, 21); | |||
| this.AuthPwdTextBox.TabIndex = 11; | |||
| // | |||
| // ProxyForm | |||
| // | |||
| this.AcceptButton = this.OKButton; | |||
| this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); | |||
| this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; | |||
| this.AutoSize = true; | |||
| this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||
| this.CancelButton = this.MyCancelButton; | |||
| this.ClientSize = new System.Drawing.Size(448, 231); | |||
| this.Controls.Add(this.tableLayoutPanel1); | |||
| this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; | |||
| this.MaximizeBox = false; | |||
| this.MinimizeBox = false; | |||
| this.Name = "ProxyForm"; | |||
| this.Padding = new System.Windows.Forms.Padding(12, 12, 12, 9); | |||
| this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | |||
| this.Text = "Edit Proxy"; | |||
| this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ProxyForm_FormClosed); | |||
| this.tableLayoutPanel1.ResumeLayout(false); | |||
| this.tableLayoutPanel1.PerformLayout(); | |||
| this.flowLayoutPanel1.ResumeLayout(false); | |||
| this.ResumeLayout(false); | |||
| } | |||
| #endregion | |||
| private System.Windows.Forms.CheckBox UseProxyCheckBox; | |||
| private System.Windows.Forms.Label ProxyAddrLabel; | |||
| private System.Windows.Forms.TextBox ProxyServerTextBox; | |||
| private System.Windows.Forms.Label ProxyPortLabel; | |||
| private System.Windows.Forms.TextBox ProxyPortTextBox; | |||
| private System.Windows.Forms.Button MyCancelButton; | |||
| private System.Windows.Forms.Button OKButton; | |||
| private System.Windows.Forms.Label ProxyTypeLabel; | |||
| private System.Windows.Forms.ComboBox ProxyTypeComboBox; | |||
| private System.Windows.Forms.TextBox ProxyTimeoutTextBox; | |||
| private System.Windows.Forms.Label ProxyTimeoutLabel; | |||
| private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; | |||
| private System.Windows.Forms.Label ProxyNotificationLabel; | |||
| private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; | |||
| private System.Windows.Forms.Label AuthUserLabel; | |||
| private System.Windows.Forms.Label AuthPwdLabel; | |||
| private System.Windows.Forms.CheckBox UseAuthCheckBox; | |||
| private System.Windows.Forms.TextBox AuthUserTextBox; | |||
| private System.Windows.Forms.TextBox AuthPwdTextBox; | |||
| } | |||
| } | |||
| @@ -1,176 +0,0 @@ | |||
| using System; | |||
| using System.Drawing; | |||
| using System.Windows.Forms; | |||
| using Shadowsocks.Controller; | |||
| using Shadowsocks.Model; | |||
| using Shadowsocks.Properties; | |||
| namespace Shadowsocks.View | |||
| { | |||
| public partial class ProxyForm : Form | |||
| { | |||
| private ShadowsocksController controller; | |||
| // this is a copy of configuration that we are working on | |||
| private ProxyConfig _modifiedProxyConfig; | |||
| public ProxyForm(ShadowsocksController controller) | |||
| { | |||
| this.Font = System.Drawing.SystemFonts.MessageBoxFont; | |||
| InitializeComponent(); | |||
| UpdateTexts(); | |||
| this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | |||
| this.controller = controller; | |||
| controller.ConfigChanged += controller_ConfigChanged; | |||
| UpdateEnabled(); | |||
| LoadCurrentConfiguration(); | |||
| } | |||
| private void UpdateTexts() | |||
| { | |||
| I18N.TranslateForm(this); | |||
| } | |||
| private void controller_ConfigChanged(object sender, EventArgs e) | |||
| { | |||
| LoadCurrentConfiguration(); | |||
| } | |||
| private void LoadCurrentConfiguration() | |||
| { | |||
| _modifiedProxyConfig = controller.GetCurrentConfiguration().proxy; | |||
| UseProxyCheckBox.Checked = _modifiedProxyConfig.useProxy; | |||
| ProxyServerTextBox.Text = _modifiedProxyConfig.proxyServer; | |||
| ProxyPortTextBox.Text = _modifiedProxyConfig.proxyPort.ToString(); | |||
| ProxyTimeoutTextBox.Text = _modifiedProxyConfig.proxyTimeout.ToString(); | |||
| ProxyTypeComboBox.SelectedIndex = _modifiedProxyConfig.proxyType; | |||
| UseAuthCheckBox.Checked = _modifiedProxyConfig.useAuth; | |||
| AuthUserTextBox.Text = _modifiedProxyConfig.authUser; | |||
| AuthPwdTextBox.Text = _modifiedProxyConfig.authPwd; | |||
| } | |||
| private void OKButton_Click(object sender, EventArgs e) | |||
| { | |||
| _modifiedProxyConfig.useProxy = UseProxyCheckBox.Checked; | |||
| if (_modifiedProxyConfig.useProxy) | |||
| { | |||
| if (!int.TryParse(ProxyPortTextBox.Text, out _modifiedProxyConfig.proxyPort)) | |||
| { | |||
| MessageBox.Show(I18N.GetString("Illegal port number format")); | |||
| return; | |||
| } | |||
| if (!int.TryParse(ProxyTimeoutTextBox.Text, out _modifiedProxyConfig.proxyTimeout)) | |||
| { | |||
| MessageBox.Show(I18N.GetString("Illegal timeout format")); | |||
| return; | |||
| } | |||
| _modifiedProxyConfig.proxyType = ProxyTypeComboBox.SelectedIndex; | |||
| try | |||
| { | |||
| Configuration.CheckServer(_modifiedProxyConfig.proxyServer = ProxyServerTextBox.Text); | |||
| Configuration.CheckPort(_modifiedProxyConfig.proxyPort); | |||
| Configuration.CheckTimeout(_modifiedProxyConfig.proxyTimeout, ProxyConfig.MaxProxyTimeoutSec); | |||
| _modifiedProxyConfig.useAuth = UseAuthCheckBox.Checked; | |||
| if (_modifiedProxyConfig.useAuth) | |||
| { | |||
| Configuration.CheckProxyAuthUser(_modifiedProxyConfig.authUser = AuthUserTextBox.Text); | |||
| Configuration.CheckProxyAuthPwd(_modifiedProxyConfig.authPwd = AuthPwdTextBox.Text); | |||
| } | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| MessageBox.Show(ex.Message); | |||
| return; | |||
| } | |||
| } | |||
| controller.SaveProxy(_modifiedProxyConfig); | |||
| this.Close(); | |||
| } | |||
| private void CancelButton_Click(object sender, EventArgs e) | |||
| { | |||
| this.Close(); | |||
| } | |||
| private void ProxyForm_FormClosed(object sender, FormClosedEventArgs e) | |||
| { | |||
| controller.ConfigChanged -= controller_ConfigChanged; | |||
| } | |||
| private void UseProxyCheckBox_CheckedChanged(object sender, EventArgs e) | |||
| { | |||
| UpdateEnabled(); | |||
| } | |||
| private void UpdateEnabled() | |||
| { | |||
| if (UseProxyCheckBox.Checked) | |||
| { | |||
| ProxyServerTextBox.Enabled = | |||
| ProxyPortTextBox.Enabled = | |||
| ProxyTimeoutTextBox.Enabled = | |||
| ProxyTypeComboBox.Enabled = true; | |||
| if (ProxyTypeComboBox.SelectedIndex == ProxyConfig.PROXY_HTTP) | |||
| { | |||
| UseAuthCheckBox.Enabled = true; | |||
| if (UseAuthCheckBox.Checked) | |||
| { | |||
| AuthUserTextBox.Enabled = | |||
| AuthPwdTextBox.Enabled = true; | |||
| } | |||
| else | |||
| { | |||
| AuthUserTextBox.Enabled = | |||
| AuthPwdTextBox.Enabled = false; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| // TODO support for SOCK5 auth | |||
| UseAuthCheckBox.Enabled = | |||
| AuthUserTextBox.Enabled = | |||
| AuthPwdTextBox.Enabled = false; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| ProxyServerTextBox.Enabled = | |||
| ProxyPortTextBox.Enabled = | |||
| ProxyTimeoutTextBox.Enabled = | |||
| ProxyTypeComboBox.Enabled = | |||
| UseAuthCheckBox.Enabled = | |||
| AuthUserTextBox.Enabled = | |||
| AuthPwdTextBox.Enabled = false; | |||
| } | |||
| } | |||
| private void ProxyTypeComboBox_SelectedIndexChanged(object sender, EventArgs e) | |||
| { | |||
| // TODO support for SOCK5 auth | |||
| if (ProxyTypeComboBox.SelectedIndex != ProxyConfig.PROXY_HTTP) | |||
| { | |||
| UseAuthCheckBox.Checked = false; | |||
| AuthUserTextBox.Clear(); | |||
| AuthPwdTextBox.Clear(); | |||
| } | |||
| UpdateEnabled(); | |||
| } | |||
| private void UseAuthCheckBox_CheckedChanged(object sender, EventArgs e) | |||
| { | |||
| UpdateEnabled(); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,125 @@ | |||
| using ReactiveUI; | |||
| using ReactiveUI.Fody.Helpers; | |||
| using ReactiveUI.Validation.Extensions; | |||
| using ReactiveUI.Validation.Helpers; | |||
| using Shadowsocks.Controller; | |||
| using Shadowsocks.Model; | |||
| using Shadowsocks.View; | |||
| using System.Linq; | |||
| using System.Reactive; | |||
| using System.Reactive.Linq; | |||
| namespace Shadowsocks.ViewModels | |||
| { | |||
| public class ForwardProxyViewModel : ReactiveValidationObject | |||
| { | |||
| public ForwardProxyViewModel() | |||
| { | |||
| _config = Program.MainController.GetCurrentConfiguration(); | |||
| _controller = Program.MainController; | |||
| _menuViewController = Program.MenuController; | |||
| if (!_config.proxy.useProxy) | |||
| NoProxy = true; | |||
| else if (_config.proxy.proxyType == 0) | |||
| UseSocks5Proxy = true; | |||
| else | |||
| UseHttpProxy = true; | |||
| Address = _config.proxy.proxyServer; | |||
| Port = _config.proxy.proxyPort; | |||
| Timeout = _config.proxy.proxyTimeout; | |||
| Username = _config.proxy.authUser; | |||
| Password = _config.proxy.authPwd; | |||
| AddressRule = this.ValidationRule( | |||
| viewModel => viewModel.Address, | |||
| address => !string.IsNullOrWhiteSpace(address), | |||
| "Address can't be empty or whitespaces."); | |||
| PortRule = this.ValidationRule( | |||
| viewModel => viewModel.Port, | |||
| port => port > 0 && port <= 65535, | |||
| port => $"{port} is out of range (0, 65535]."); | |||
| TimeoutRule = this.ValidationRule( | |||
| viewModel => viewModel.Timeout, | |||
| timeout => timeout > 0 && timeout <= 10, | |||
| timeout => $"{timeout} is out of range (0, 10]."); | |||
| var authValid = this | |||
| .WhenAnyValue(x => x.Username, x => x.Password, (username, password) => new { Username = username, Password = password }) | |||
| .Select(x => string.IsNullOrWhiteSpace(x.Username) == string.IsNullOrWhiteSpace(x.Password)); | |||
| AuthRule = this.ValidationRule(authValid, "You must provide both username and password."); | |||
| var canSave = this.IsValid(); | |||
| Save = ReactiveCommand.Create(() => | |||
| { | |||
| _controller.SaveProxy(GetForwardProxyConfig()); | |||
| _menuViewController.CloseForwardProxyWindow(); | |||
| }, canSave); | |||
| Cancel = ReactiveCommand.Create(_menuViewController.CloseForwardProxyWindow); | |||
| } | |||
| private readonly Configuration _config; | |||
| private readonly ShadowsocksController _controller; | |||
| private readonly MenuViewController _menuViewController; | |||
| public ValidationHelper AddressRule { get; } | |||
| public ValidationHelper PortRule { get; } | |||
| public ValidationHelper TimeoutRule { get; } | |||
| public ValidationHelper AuthRule { get; } | |||
| public ReactiveCommand<Unit, Unit> Save { get; } | |||
| public ReactiveCommand<Unit, Unit> Cancel { get; } | |||
| [Reactive] | |||
| public bool NoProxy { get; set; } | |||
| [Reactive] | |||
| public bool UseSocks5Proxy { get; set; } | |||
| [Reactive] | |||
| public bool UseHttpProxy { get; set; } | |||
| [Reactive] | |||
| public string Address { get; set; } | |||
| [Reactive] | |||
| public int Port { get; set; } | |||
| [Reactive] | |||
| public int Timeout { get; set; } | |||
| [Reactive] | |||
| public string Username { get; set; } | |||
| [Reactive] | |||
| public string Password { get; set; } | |||
| private ForwardProxyConfig GetForwardProxyConfig() | |||
| { | |||
| var forwardProxyConfig = new ForwardProxyConfig() | |||
| { | |||
| proxyServer = Address, | |||
| proxyPort = Port, | |||
| proxyTimeout = Timeout, | |||
| authUser = Username, | |||
| authPwd = Password | |||
| }; | |||
| if (NoProxy) | |||
| forwardProxyConfig.useProxy = false; | |||
| else if (UseSocks5Proxy) | |||
| { | |||
| forwardProxyConfig.useProxy = true; | |||
| forwardProxyConfig.proxyType = 0; | |||
| } | |||
| else | |||
| { | |||
| forwardProxyConfig.useProxy = true; | |||
| forwardProxyConfig.proxyType = 1; | |||
| } | |||
| return forwardProxyConfig; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,189 @@ | |||
| using ReactiveUI; | |||
| using ReactiveUI.Fody.Helpers; | |||
| using Shadowsocks.Controller; | |||
| using Shadowsocks.Model; | |||
| using Shadowsocks.View; | |||
| using System.Reactive; | |||
| using System.Text; | |||
| using System.Windows.Input; | |||
| namespace Shadowsocks.ViewModels | |||
| { | |||
| public class HotkeysViewModel : ReactiveObject | |||
| { | |||
| public HotkeysViewModel() | |||
| { | |||
| _config = Program.MainController.GetCurrentConfiguration(); | |||
| _controller = Program.MainController; | |||
| _menuViewController = Program.MenuController; | |||
| HotkeySystemProxy = _config.hotkey.SwitchSystemProxy; | |||
| HotkeyProxyMode = _config.hotkey.SwitchSystemProxyMode; | |||
| HotkeyAllowLan = _config.hotkey.SwitchAllowLan; | |||
| HotkeyOpenLogs = _config.hotkey.ShowLogs; | |||
| HotkeySwitchPrev = _config.hotkey.ServerMoveUp; | |||
| HotkeySwitchNext = _config.hotkey.ServerMoveDown; | |||
| RegisterAtStartup = _config.hotkey.RegHotkeysAtStartup; | |||
| HotkeySystemProxyStatus = "✔"; | |||
| HotkeyProxyModeStatus = "✔"; | |||
| HotkeyAllowLanStatus = "✔"; | |||
| HotkeyOpenLogsStatus = "✔"; | |||
| HotkeySwitchPrevStatus = "✔"; | |||
| HotkeySwitchNextStatus = "✔"; | |||
| RegisterAll = ReactiveCommand.Create(() => RegisterAllAndUpdateStatus()); | |||
| Save = ReactiveCommand.Create(() => RegisterAllAndUpdateStatus(true)); | |||
| Cancel = ReactiveCommand.Create(_menuViewController.CloseHotkeysWindow); | |||
| } | |||
| private readonly Configuration _config; | |||
| private readonly ShadowsocksController _controller; | |||
| private readonly MenuViewController _menuViewController; | |||
| public ReactiveCommand<Unit, Unit> RegisterAll { get; } | |||
| public ReactiveCommand<Unit, Unit> Save { get; } | |||
| public ReactiveCommand<Unit, Unit> Cancel { get; } | |||
| [Reactive] | |||
| public string HotkeySystemProxy { get; set; } | |||
| [Reactive] | |||
| public string HotkeyProxyMode { get; set; } | |||
| [Reactive] | |||
| public string HotkeyAllowLan { get; set; } | |||
| [Reactive] | |||
| public string HotkeyOpenLogs { get; set; } | |||
| [Reactive] | |||
| public string HotkeySwitchPrev { get; set; } | |||
| [Reactive] | |||
| public string HotkeySwitchNext { get; set; } | |||
| [Reactive] | |||
| public bool RegisterAtStartup { get; set; } | |||
| [Reactive] | |||
| public string HotkeySystemProxyStatus { get; set; } | |||
| [Reactive] | |||
| public string HotkeyProxyModeStatus { get; set; } | |||
| [Reactive] | |||
| public string HotkeyAllowLanStatus { get; set; } | |||
| [Reactive] | |||
| public string HotkeyOpenLogsStatus { get; set; } | |||
| [Reactive] | |||
| public string HotkeySwitchPrevStatus { get; set; } | |||
| [Reactive] | |||
| public string HotkeySwitchNextStatus { get; set; } | |||
| public void RecordKeyDown(int hotkeyIndex, KeyEventArgs keyEventArgs) | |||
| { | |||
| var recordedKeyStringBuilder = new StringBuilder(); | |||
| // record modifiers | |||
| if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) | |||
| recordedKeyStringBuilder.Append("Ctrl+"); | |||
| if ((Keyboard.Modifiers & ModifierKeys.Alt) > 0) | |||
| recordedKeyStringBuilder.Append("Alt+"); | |||
| if ((Keyboard.Modifiers & ModifierKeys.Shift) > 0) | |||
| recordedKeyStringBuilder.Append("Shift+"); | |||
| // record other keys when at least one modifier is pressed | |||
| if (recordedKeyStringBuilder.Length > 0 && (keyEventArgs.Key < Key.LeftShift || keyEventArgs.Key > Key.RightAlt)) | |||
| recordedKeyStringBuilder.Append(keyEventArgs.Key); | |||
| switch (hotkeyIndex) | |||
| { | |||
| case 0: | |||
| HotkeySystemProxy = recordedKeyStringBuilder.ToString(); | |||
| break; | |||
| case 1: | |||
| HotkeyProxyMode = recordedKeyStringBuilder.ToString(); | |||
| break; | |||
| case 2: | |||
| HotkeyAllowLan = recordedKeyStringBuilder.ToString(); | |||
| break; | |||
| case 3: | |||
| HotkeyOpenLogs = recordedKeyStringBuilder.ToString(); | |||
| break; | |||
| case 4: | |||
| HotkeySwitchPrev = recordedKeyStringBuilder.ToString(); | |||
| break; | |||
| case 5: | |||
| HotkeySwitchNext = recordedKeyStringBuilder.ToString(); | |||
| break; | |||
| } | |||
| } | |||
| public void FinishOnKeyUp(int hotkeyIndex, KeyEventArgs keyEventArgs) | |||
| { | |||
| switch (hotkeyIndex) | |||
| { | |||
| case 0: | |||
| if (HotkeySystemProxy.EndsWith("+")) | |||
| HotkeySystemProxy = ""; | |||
| break; | |||
| case 1: | |||
| if (HotkeyProxyMode.EndsWith("+")) | |||
| HotkeyProxyMode = ""; | |||
| break; | |||
| case 2: | |||
| if (HotkeyAllowLan.EndsWith("+")) | |||
| HotkeyAllowLan = ""; | |||
| break; | |||
| case 3: | |||
| if (HotkeyOpenLogs.EndsWith("+")) | |||
| HotkeyOpenLogs = ""; | |||
| break; | |||
| case 4: | |||
| if (HotkeySwitchPrev.EndsWith("+")) | |||
| HotkeySwitchPrev = ""; | |||
| break; | |||
| case 5: | |||
| if (HotkeySwitchNext.EndsWith("+")) | |||
| HotkeySwitchNext = ""; | |||
| break; | |||
| } | |||
| } | |||
| private void RegisterAllAndUpdateStatus(bool save = false) | |||
| { | |||
| HotkeySystemProxyStatus = HotkeyReg.RegHotkeyFromString(HotkeySystemProxy, "SwitchSystemProxyCallback") ? "✔" : "❌"; | |||
| HotkeyProxyModeStatus = HotkeyReg.RegHotkeyFromString(HotkeyProxyMode, "SwitchSystemProxyModeCallback") ? "✔" : "❌"; | |||
| HotkeyAllowLanStatus = HotkeyReg.RegHotkeyFromString(HotkeyAllowLan, "SwitchAllowLanCallback") ? "✔" : "❌"; | |||
| HotkeyOpenLogsStatus = HotkeyReg.RegHotkeyFromString(HotkeyOpenLogs, "ShowLogsCallback") ? "✔" : "❌"; | |||
| HotkeySwitchPrevStatus = HotkeyReg.RegHotkeyFromString(HotkeySwitchPrev, "ServerMoveUpCallback") ? "✔" : "❌"; | |||
| HotkeySwitchNextStatus = HotkeyReg.RegHotkeyFromString(HotkeySwitchNext, "ServerMoveDownCallback") ? "✔" : "❌"; | |||
| if (HotkeySystemProxyStatus == "✔" && | |||
| HotkeyProxyModeStatus == "✔" && | |||
| HotkeyAllowLanStatus == "✔" && | |||
| HotkeyOpenLogsStatus == "✔" && | |||
| HotkeySwitchPrevStatus == "✔" && | |||
| HotkeySwitchNextStatus == "✔" && save) | |||
| { | |||
| _controller.SaveHotkeyConfig(GetHotkeyConfig); | |||
| _menuViewController.CloseHotkeysWindow(); | |||
| } | |||
| } | |||
| private HotkeyConfig GetHotkeyConfig => new HotkeyConfig() | |||
| { | |||
| SwitchSystemProxy = HotkeySystemProxy, | |||
| SwitchSystemProxyMode = HotkeyProxyMode, | |||
| SwitchAllowLan = HotkeyAllowLan, | |||
| ShowLogs = HotkeyOpenLogs, | |||
| ServerMoveUp = HotkeySwitchPrev, | |||
| ServerMoveDown = HotkeySwitchNext, | |||
| RegHotkeysAtStartup = RegisterAtStartup | |||
| }; | |||
| } | |||
| } | |||
| @@ -0,0 +1,115 @@ | |||
| using ReactiveUI; | |||
| using ReactiveUI.Fody.Helpers; | |||
| using ReactiveUI.Validation.Extensions; | |||
| using ReactiveUI.Validation.Helpers; | |||
| using Shadowsocks.Controller; | |||
| using Shadowsocks.Localization; | |||
| using Shadowsocks.Model; | |||
| using Shadowsocks.View; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Collections.ObjectModel; | |||
| using System.Linq; | |||
| using System.Reactive; | |||
| using System.Reactive.Linq; | |||
| using System.Text; | |||
| using System.Windows; | |||
| namespace Shadowsocks.ViewModels | |||
| { | |||
| public class OnlineConfigViewModel : ReactiveValidationObject | |||
| { | |||
| public OnlineConfigViewModel() | |||
| { | |||
| _config = Program.MainController.GetCurrentConfiguration(); | |||
| _controller = Program.MainController; | |||
| _menuViewController = Program.MenuController; | |||
| Sources = new ObservableCollection<string>(_config.onlineConfigSource); | |||
| SelectedSource = ""; | |||
| Address = ""; | |||
| // TODO in v5: if http:// show warning as materialDesign:HintAssist.HelperText | |||
| AddressRule = this.ValidationRule( | |||
| viewModel => viewModel.Address, | |||
| address => address.StartsWith("http://"), | |||
| "Warning: getting online configuration from plain HTTP sources is NOT secure!"); | |||
| var canUpdateCopyRemove = this.WhenAnyValue( | |||
| x => x.SelectedSource, | |||
| selectedSource => !string.IsNullOrWhiteSpace(selectedSource)); | |||
| var canUpdateAll = this.WhenAnyValue( | |||
| x => x.Sources.Count, | |||
| count => count > 0); | |||
| var canAdd = this.WhenAnyValue( | |||
| x => x.Address, | |||
| address => Uri.IsWellFormedUriString(address, UriKind.Absolute) && | |||
| (address.StartsWith("https://") || address.StartsWith("http://"))); | |||
| Update = ReactiveCommand.CreateFromTask(() => _controller.UpdateOnlineConfig(SelectedSource), canUpdateCopyRemove); | |||
| UpdateAll = ReactiveCommand.CreateFromTask(_controller.UpdateAllOnlineConfig, canUpdateAll); | |||
| CopyLink = ReactiveCommand.Create(() => Clipboard.SetText(SelectedSource), canUpdateCopyRemove); | |||
| Remove = ReactiveCommand.Create(() => | |||
| { | |||
| bool result; | |||
| var urlToRemove = SelectedSource; // save it here because SelectedSource is lost once we remove the selection | |||
| do | |||
| { | |||
| result = Sources.Remove(urlToRemove); | |||
| } while (result); | |||
| _controller.RemoveOnlineConfig(urlToRemove); | |||
| }, canUpdateCopyRemove); | |||
| Add = ReactiveCommand.Create(() => | |||
| { | |||
| Sources.Add(Address); | |||
| SelectedSource = Address; | |||
| _controller.SaveOnlineConfigSource(Sources.ToList()); | |||
| Address = ""; | |||
| }, canAdd); | |||
| // TODO in v5: use MaterialDesignThemes snackbar messages | |||
| this.WhenAnyObservable(x => x.Update) | |||
| .Subscribe(x => | |||
| { | |||
| if (x) | |||
| MessageBox.Show(LocalizationProvider.GetLocalizedValue<string>("sip008UpdateSuccess")); | |||
| else | |||
| MessageBox.Show(LocalizationProvider.GetLocalizedValue<string>("sip008UpdateFailure")); | |||
| }); | |||
| this.WhenAnyObservable(x => x.UpdateAll) | |||
| .Subscribe(x => | |||
| { | |||
| if (x.Count == 0) | |||
| MessageBox.Show(LocalizationProvider.GetLocalizedValue<string>("sip008UpdateAllSuccess")); | |||
| else | |||
| { | |||
| var stringBuilder = new StringBuilder(LocalizationProvider.GetLocalizedValue<string>("sip008UpdateAllFailure")); | |||
| foreach (var url in x) | |||
| stringBuilder.AppendLine(url); | |||
| MessageBox.Show(stringBuilder.ToString()); | |||
| } | |||
| }); | |||
| } | |||
| private readonly Configuration _config; | |||
| private readonly ShadowsocksController _controller; | |||
| private readonly MenuViewController _menuViewController; | |||
| public ValidationHelper AddressRule { get; } | |||
| public ReactiveCommand<Unit, bool> Update { get; } | |||
| public ReactiveCommand<Unit, List<string>> UpdateAll { get; } | |||
| public ReactiveCommand<Unit, Unit> CopyLink { get; } | |||
| public ReactiveCommand<Unit, Unit> Remove { get; } | |||
| public ReactiveCommand<Unit, Unit> Add { get; } | |||
| [Reactive] | |||
| public ObservableCollection<string> Sources { get; private set; } | |||
| [Reactive] | |||
| public string SelectedSource { get; set; } | |||
| [Reactive] | |||
| public string Address { get; set; } | |||
| } | |||
| } | |||
| @@ -1,10 +1,13 @@ | |||
| using ReactiveUI; | |||
| using ReactiveUI.Fody.Helpers; | |||
| using Shadowsocks.Model; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Drawing; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Reactive; | |||
| using System.Windows; | |||
| using System.Windows.Media.Imaging; | |||
| namespace Shadowsocks.ViewModels | |||
| @@ -17,18 +20,30 @@ namespace Shadowsocks.ViewModels | |||
| public ServerSharingViewModel() | |||
| { | |||
| _config = Program.MainController.GetCurrentConfiguration(); | |||
| _servers = _config.configs; | |||
| _selectedServer = _servers.First(); | |||
| //_selectedServerUrlImage = new BitmapImage(); | |||
| UpdateUrlAndImage(); | |||
| Servers = _config.configs; | |||
| SelectedServer = Servers[0]; | |||
| this.WhenAnyValue(x => x.SelectedServer) | |||
| .Subscribe(_ => UpdateUrlAndImage()); | |||
| CopyLink = ReactiveCommand.Create(() => Clipboard.SetText(SelectedServerUrl)); | |||
| } | |||
| private readonly Configuration _config; | |||
| private List<Server> _servers; | |||
| private Server _selectedServer; | |||
| private string _selectedServerUrl; | |||
| private BitmapImage _selectedServerUrlImage; | |||
| public ReactiveCommand<Unit, Unit> CopyLink { get; } | |||
| [Reactive] | |||
| public List<Server> Servers { get; private set; } | |||
| [Reactive] | |||
| public Server SelectedServer { get; set; } | |||
| [Reactive] | |||
| public string SelectedServerUrl { get; private set; } | |||
| [Reactive] | |||
| public BitmapImage SelectedServerUrlImage { get; private set; } | |||
| /// <summary> | |||
| /// Called when SelectedServer changed | |||
| @@ -37,10 +52,10 @@ namespace Shadowsocks.ViewModels | |||
| private void UpdateUrlAndImage() | |||
| { | |||
| // update SelectedServerUrl | |||
| SelectedServerUrl = _selectedServer.GetURL(_config.generateLegacyUrl); | |||
| SelectedServerUrl = SelectedServer.GetURL(_config.generateLegacyUrl); | |||
| // generate QR code | |||
| var qrCode = ZXing.QrCode.Internal.Encoder.encode(_selectedServerUrl, ZXing.QrCode.Internal.ErrorCorrectionLevel.L); | |||
| var qrCode = ZXing.QrCode.Internal.Encoder.encode(SelectedServerUrl, ZXing.QrCode.Internal.ErrorCorrectionLevel.L); | |||
| var byteMatrix = qrCode.Matrix; | |||
| // paint bitmap | |||
| @@ -77,33 +92,5 @@ namespace Shadowsocks.ViewModels | |||
| } | |||
| SelectedServerUrlImage = bitmapImage; | |||
| } | |||
| public List<Server> Servers | |||
| { | |||
| get => _servers; | |||
| set => this.RaiseAndSetIfChanged(ref _servers, value); | |||
| } | |||
| public Server SelectedServer | |||
| { | |||
| get => _selectedServer; | |||
| set | |||
| { | |||
| this.RaiseAndSetIfChanged(ref _selectedServer, value); | |||
| UpdateUrlAndImage(); | |||
| } | |||
| } | |||
| public string SelectedServerUrl | |||
| { | |||
| get => _selectedServerUrl; | |||
| set => this.RaiseAndSetIfChanged(ref _selectedServerUrl, value); | |||
| } | |||
| public BitmapImage SelectedServerUrlImage | |||
| { | |||
| get => _selectedServerUrlImage; | |||
| set => this.RaiseAndSetIfChanged(ref _selectedServerUrlImage, value); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| using Newtonsoft.Json.Linq; | |||
| using ReactiveUI; | |||
| using Shadowsocks.Controller; | |||
| using System.Reactive; | |||
| namespace Shadowsocks.ViewModels | |||
| { | |||
| public class VersionUpdatePromptViewModel : ReactiveObject | |||
| { | |||
| public VersionUpdatePromptViewModel(JToken releaseObject) | |||
| { | |||
| _updateChecker = Program.MenuController.updateChecker; | |||
| _releaseObject = releaseObject; | |||
| ReleaseNotes = string.Concat( | |||
| $"# {((bool)_releaseObject["prerelease"] ? "⚠ Pre-release" : "ℹ Release")} {(string)_releaseObject["tag_name"] ?? "Failed to get tag name"}\r\n", | |||
| (string)_releaseObject["body"] ?? "Failed to get release notes"); | |||
| Update = ReactiveCommand.CreateFromTask(_updateChecker.DoUpdate); | |||
| SkipVersion = ReactiveCommand.Create(_updateChecker.SkipUpdate); | |||
| NotNow = ReactiveCommand.Create(_updateChecker.CloseVersionUpdatePromptWindow); | |||
| } | |||
| private readonly UpdateChecker _updateChecker; | |||
| private readonly JToken _releaseObject; | |||
| public string ReleaseNotes { get; } | |||
| public ReactiveCommand<Unit, Unit> Update { get; } | |||
| public ReactiveCommand<Unit, Unit> SkipVersion { get; } | |||
| public ReactiveCommand<Unit, Unit> NotNow { get; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,100 @@ | |||
| <reactiveui:ReactiveUserControl | |||
| x:Class="Shadowsocks.Views.ForwardProxyView" | |||
| x:TypeArguments="vms:ForwardProxyViewModel" | |||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
| xmlns:local="clr-namespace:Shadowsocks.Views" | |||
| xmlns:vms="clr-namespace:Shadowsocks.ViewModels" | |||
| xmlns:reactiveui="http://reactiveui.net" | |||
| xmlns:lex="http://wpflocalizeextension.codeplex.com" | |||
| lex:LocalizeDictionary.DesignCulture="en" | |||
| lex:ResxLocalizationProvider.DefaultAssembly="Shadowsocks" | |||
| lex:ResxLocalizationProvider.DefaultDictionary="Strings" | |||
| mc:Ignorable="d" | |||
| d:DesignHeight="380" d:DesignWidth="280"> | |||
| <Grid Margin="8"> | |||
| <Grid.RowDefinitions> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="*" /> | |||
| </Grid.RowDefinitions> | |||
| <Grid.ColumnDefinitions> | |||
| <ColumnDefinition Width="Auto" /> | |||
| <ColumnDefinition Width="*" /> | |||
| </Grid.ColumnDefinitions> | |||
| <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" | |||
| Margin="4 8 4 8" | |||
| FontSize="16" | |||
| Text="{lex:Loc Type}"/> | |||
| <RadioButton x:Name="noProxyRadioButton" Grid.Row="1" Grid.Column="0" | |||
| Margin="4" | |||
| GroupName="ProxyType" | |||
| Content="{lex:Loc NoProxy}"/> | |||
| <RadioButton x:Name="socks5RadioButton" Grid.Row="2" Grid.Column="0" | |||
| Margin="4" | |||
| GroupName="ProxyType" | |||
| Content="{lex:Loc SOCKS5}"/> | |||
| <RadioButton x:Name="httpRadioButton" Grid.Row="3" Grid.Column="0" | |||
| Margin="4" | |||
| GroupName="ProxyType" | |||
| Content="{lex:Loc HTTP}"/> | |||
| <TextBlock Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" | |||
| Margin="4 8 4 8" | |||
| FontSize="16" | |||
| Text="{lex:Loc Details}"/> | |||
| <TextBlock Grid.Row="5" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc Address}"/> | |||
| <TextBox x:Name="addressTextBox" Grid.Row="5" Grid.Column="1" | |||
| Margin="4"/> | |||
| <TextBlock Grid.Row="6" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc Port}"/> | |||
| <TextBox x:Name="portTextBox" Grid.Row="6" Grid.Column="1" | |||
| Margin="4" | |||
| HorizontalContentAlignment="Right"/> | |||
| <TextBlock Grid.Row="7" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc Timeout}"/> | |||
| <TextBox x:Name="timeoutTextBox" Grid.Row="7" Grid.Column="1" | |||
| Margin="4" | |||
| HorizontalContentAlignment="Right"/> | |||
| <TextBlock Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="2" | |||
| Margin="4 8 4 8" | |||
| FontSize="16" | |||
| Text="{lex:Loc CredentialsOptional}"/> | |||
| <TextBlock Grid.Row="9" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc Username}"/> | |||
| <TextBox x:Name="usernameTextBox" Grid.Row="9" Grid.Column="1" | |||
| Margin="4"/> | |||
| <TextBlock Grid.Row="10" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc Password}"/> | |||
| <TextBox x:Name="passwordTextBox" Grid.Row="10" Grid.Column="1" | |||
| Margin="4"/> | |||
| <StackPanel Grid.Row="11" Grid.Column="0" Grid.ColumnSpan="2" | |||
| Orientation="Horizontal" | |||
| HorizontalAlignment="Right" | |||
| VerticalAlignment="Bottom"> | |||
| <Button x:Name="saveButton" Margin="4" MinWidth="75" Content="{lex:Loc}"/> | |||
| <Button x:Name="cancelButton" Margin="4" MinWidth="75" Content="{lex:Loc}"/> | |||
| </StackPanel> | |||
| </Grid> | |||
| </reactiveui:ReactiveUserControl> | |||
| @@ -0,0 +1,72 @@ | |||
| using ReactiveUI; | |||
| using Shadowsocks.ViewModels; | |||
| using System.Reactive.Disposables; | |||
| namespace Shadowsocks.Views | |||
| { | |||
| /// <summary> | |||
| /// Interaction logic for ForwardProxyView.xaml | |||
| /// </summary> | |||
| public partial class ForwardProxyView : ReactiveUserControl<ForwardProxyViewModel> | |||
| { | |||
| public ForwardProxyView() | |||
| { | |||
| InitializeComponent(); | |||
| ViewModel = new ForwardProxyViewModel(); | |||
| this.WhenActivated(disposables => | |||
| { | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.NoProxy, | |||
| view => view.noProxyRadioButton.IsChecked) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.UseSocks5Proxy, | |||
| view => view.socks5RadioButton.IsChecked) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.UseHttpProxy, | |||
| view => view.httpRadioButton.IsChecked) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.Address, | |||
| view => view.addressTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.Port, | |||
| view => view.portTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.Timeout, | |||
| view => view.timeoutTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.Username, | |||
| view => view.usernameTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.Password, | |||
| view => view.passwordTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.UseHttpProxy, | |||
| view => view.usernameTextBox.IsEnabled) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.UseHttpProxy, | |||
| view => view.passwordTextBox.IsEnabled) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.Save, | |||
| view => view.saveButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.Cancel, | |||
| view => view.cancelButton) | |||
| .DisposeWith(disposables); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,115 @@ | |||
| <reactiveui:ReactiveUserControl | |||
| x:Class="Shadowsocks.Views.HotkeysView" | |||
| x:TypeArguments="vms:HotkeysViewModel" | |||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
| xmlns:local="clr-namespace:Shadowsocks.Views" | |||
| xmlns:vms="clr-namespace:Shadowsocks.ViewModels" | |||
| xmlns:reactiveui="http://reactiveui.net" | |||
| xmlns:lex="http://wpflocalizeextension.codeplex.com" | |||
| lex:LocalizeDictionary.DesignCulture="en" | |||
| lex:ResxLocalizationProvider.DefaultAssembly="Shadowsocks" | |||
| lex:ResxLocalizationProvider.DefaultDictionary="Strings" | |||
| mc:Ignorable="d" | |||
| d:DesignHeight="240" d:DesignWidth="280"> | |||
| <Grid Margin="8"> | |||
| <Grid.RowDefinitions> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="*" /> | |||
| </Grid.RowDefinitions> | |||
| <Grid.ColumnDefinitions> | |||
| <ColumnDefinition Width="Auto" /> | |||
| <ColumnDefinition Width="*" /> | |||
| <ColumnDefinition Width="Auto" /> | |||
| </Grid.ColumnDefinitions> | |||
| <TextBlock Grid.Row="0" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc ToggleSystemProxy}"/> | |||
| <TextBox x:Name="systemProxyTextBox" | |||
| Grid.Row="0" Grid.Column="1" | |||
| Margin="4" IsReadOnly="True" /> | |||
| <TextBlock x:Name="systemProxyStatusTextBlock" | |||
| Grid.Row="0" Grid.Column="2" | |||
| Margin="4" /> | |||
| <TextBlock Grid.Row="1" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc ToggleProxyMode}"/> | |||
| <TextBox x:Name="proxyModeTextBox" | |||
| Grid.Row="1" Grid.Column="1" | |||
| Margin="4" IsReadOnly="True" /> | |||
| <TextBlock x:Name="proxyModeStatusTextBlock" | |||
| Grid.Row="1" Grid.Column="2" | |||
| Margin="4" /> | |||
| <TextBlock Grid.Row="2" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc AllowClientsFromLAN}"/> | |||
| <TextBox x:Name="allowLanTextBox" | |||
| Grid.Row="2" Grid.Column="1" | |||
| Margin="4" IsReadOnly="True" /> | |||
| <TextBlock x:Name="allowLanStatusTextBlock" | |||
| Grid.Row="2" Grid.Column="2" | |||
| Margin="4" /> | |||
| <TextBlock Grid.Row="3" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc OpenLogsWindow}"/> | |||
| <TextBox x:Name="openLogsTextBox" | |||
| Grid.Row="3" Grid.Column="1" | |||
| Margin="4" IsReadOnly="True" /> | |||
| <TextBlock x:Name="openLogsStatusTextBlock" | |||
| Grid.Row="3" Grid.Column="2" | |||
| Margin="4" /> | |||
| <TextBlock Grid.Row="4" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc SwitchToPreviousServer}"/> | |||
| <TextBox x:Name="switchPrevTextBox" | |||
| Grid.Row="4" Grid.Column="1" | |||
| Margin="4" IsReadOnly="True" /> | |||
| <TextBlock x:Name="switchPrevStatusTextBlock" | |||
| Grid.Row="4" Grid.Column="2" | |||
| Margin="4" /> | |||
| <TextBlock Grid.Row="5" Grid.Column="0" | |||
| Margin="4" | |||
| Text="{lex:Loc SwitchToNextServer}"/> | |||
| <TextBox x:Name="switchNextTextBox" | |||
| Grid.Row="5" Grid.Column="1" | |||
| Margin="4" IsReadOnly="True" /> | |||
| <TextBlock x:Name="switchNextStatusTextBlock" | |||
| Grid.Row="5" Grid.Column="2" | |||
| Margin="4" /> | |||
| <StackPanel Grid.Row="6" Grid.ColumnSpan="2" Orientation="Horizontal"> | |||
| <CheckBox x:Name="registerAtStartupCheckBox" Margin="4" VerticalAlignment="Center"/> | |||
| <TextBlock Margin="4" Text="{lex:Loc RegisterHotkeysAtStartup}"/> | |||
| </StackPanel> | |||
| <StackPanel Grid.Row="7" | |||
| Grid.ColumnSpan="3" | |||
| Orientation="Horizontal" | |||
| HorizontalAlignment="Left" | |||
| VerticalAlignment="Bottom"> | |||
| <Button x:Name="registerAllButton" Margin="4" MinWidth="75" Content="{lex:Loc}"/> | |||
| </StackPanel> | |||
| <StackPanel Grid.Row="7" | |||
| Grid.ColumnSpan="3" | |||
| Orientation="Horizontal" | |||
| HorizontalAlignment="Right" | |||
| VerticalAlignment="Bottom"> | |||
| <Button x:Name="saveButton" Margin="4" MinWidth="75" Content="{lex:Loc}"/> | |||
| <Button x:Name="cancelButton" Margin="4" MinWidth="75" Content="{lex:Loc}"/> | |||
| </StackPanel> | |||
| </Grid> | |||
| </reactiveui:ReactiveUserControl> | |||
| @@ -0,0 +1,169 @@ | |||
| using ReactiveUI; | |||
| using Shadowsocks.ViewModels; | |||
| using System; | |||
| using System.Reactive.Disposables; | |||
| using System.Windows; | |||
| using System.Windows.Controls; | |||
| using System.Windows.Data; | |||
| using System.Windows.Documents; | |||
| using System.Windows.Input; | |||
| using System.Windows.Media; | |||
| using System.Windows.Media.Imaging; | |||
| using System.Windows.Navigation; | |||
| namespace Shadowsocks.Views | |||
| { | |||
| /// <summary> | |||
| /// Interaction logic for HotkeysView.xaml | |||
| /// </summary> | |||
| public partial class HotkeysView : ReactiveUserControl<HotkeysViewModel> | |||
| { | |||
| public HotkeysView() | |||
| { | |||
| InitializeComponent(); | |||
| ViewModel = new HotkeysViewModel(); | |||
| this.WhenActivated(disposables => | |||
| { | |||
| systemProxyTextBox | |||
| .Events().KeyDown | |||
| .Subscribe(keyEventArgs => ViewModel.RecordKeyDown(0, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| systemProxyTextBox | |||
| .Events().KeyUp | |||
| .Subscribe(keyEventArgs => ViewModel.FinishOnKeyUp(0, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| proxyModeTextBox | |||
| .Events().KeyDown | |||
| .Subscribe(keyEventArgs => ViewModel.RecordKeyDown(1, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| proxyModeTextBox | |||
| .Events().KeyUp | |||
| .Subscribe(keyEventArgs => ViewModel.FinishOnKeyUp(1, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| allowLanTextBox | |||
| .Events().KeyDown | |||
| .Subscribe(keyEventArgs => ViewModel.RecordKeyDown(2, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| allowLanTextBox | |||
| .Events().KeyUp | |||
| .Subscribe(keyEventArgs => ViewModel.FinishOnKeyUp(2, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| openLogsTextBox | |||
| .Events().KeyDown | |||
| .Subscribe(keyEventArgs => ViewModel.RecordKeyDown(3, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| openLogsTextBox | |||
| .Events().KeyUp | |||
| .Subscribe(keyEventArgs => ViewModel.FinishOnKeyUp(3, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| switchPrevTextBox | |||
| .Events().KeyDown | |||
| .Subscribe(keyEventArgs => ViewModel.RecordKeyDown(4, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| switchPrevTextBox | |||
| .Events().KeyUp | |||
| .Subscribe(keyEventArgs => ViewModel.FinishOnKeyUp(4, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| switchNextTextBox | |||
| .Events().KeyDown | |||
| .Subscribe(keyEventArgs => ViewModel.RecordKeyDown(5, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| switchNextTextBox | |||
| .Events().KeyUp | |||
| .Subscribe(keyEventArgs => ViewModel.FinishOnKeyUp(5, keyEventArgs)) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeySystemProxy, | |||
| view => view.systemProxyTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeyProxyMode, | |||
| view => view.proxyModeTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeyAllowLan, | |||
| view => view.allowLanTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeyOpenLogs, | |||
| view => view.openLogsTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeySwitchPrev, | |||
| view => view.switchPrevTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeySwitchNext, | |||
| view => view.switchNextTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.RegisterAtStartup, | |||
| view => view.registerAtStartupCheckBox.IsChecked) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeySystemProxyStatus, | |||
| view => view.systemProxyStatusTextBlock.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeyProxyModeStatus, | |||
| view => view.proxyModeStatusTextBlock.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeyAllowLanStatus, | |||
| view => view.allowLanStatusTextBlock.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeyOpenLogsStatus, | |||
| view => view.openLogsStatusTextBlock.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeySwitchPrevStatus, | |||
| view => view.switchPrevStatusTextBlock.Text) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.HotkeySwitchNextStatus, | |||
| view => view.switchNextStatusTextBlock.Text) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.RegisterAll, | |||
| view => view.registerAllButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.Save, | |||
| view => view.saveButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.Cancel, | |||
| view => view.cancelButton) | |||
| .DisposeWith(disposables); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,61 @@ | |||
| <reactiveui:ReactiveUserControl | |||
| x:Class="Shadowsocks.Views.OnlineConfigView" | |||
| x:TypeArguments="vms:OnlineConfigViewModel" | |||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
| xmlns:local="clr-namespace:Shadowsocks.Views" | |||
| xmlns:vms="clr-namespace:Shadowsocks.ViewModels" | |||
| xmlns:reactiveui="http://reactiveui.net" | |||
| xmlns:lex="http://wpflocalizeextension.codeplex.com" | |||
| lex:LocalizeDictionary.DesignCulture="en" | |||
| lex:ResxLocalizationProvider.DefaultAssembly="Shadowsocks" | |||
| lex:ResxLocalizationProvider.DefaultDictionary="Strings" | |||
| mc:Ignorable="d" | |||
| d:DesignHeight="500" d:DesignWidth="480"> | |||
| <Grid Margin="8"> | |||
| <Grid.RowDefinitions> | |||
| <RowDefinition Height="*" /> | |||
| <RowDefinition Height="Auto" /> | |||
| </Grid.RowDefinitions> | |||
| <Grid.ColumnDefinitions> | |||
| <ColumnDefinition Width="Auto" /> | |||
| <ColumnDefinition Width="*" /> | |||
| <ColumnDefinition Width="Auto" /> | |||
| </Grid.ColumnDefinitions> | |||
| <ListBox x:Name="sourcesListBox" Margin="8 8 4 4" | |||
| Grid.Row="0" | |||
| Grid.Column="0" | |||
| Grid.ColumnSpan="2"> | |||
| <ListBox.ItemTemplate> | |||
| <DataTemplate> | |||
| <TextBlock Text="{Binding}"/> | |||
| </DataTemplate> | |||
| </ListBox.ItemTemplate> | |||
| </ListBox> | |||
| <StackPanel Grid.Row="0" Grid.Column="2"> | |||
| <Button x:Name="updateButton" Margin="4 8 8 4" | |||
| MinWidth="75" Content="{lex:Loc}"/> | |||
| <Button x:Name="updateAllButton" Margin="4 4 8 4" | |||
| MinWidth="75" Content="{lex:Loc}"/> | |||
| <Button x:Name="copyLinkButton" Margin="4 4 8 8" | |||
| MinWidth="75" Content="{lex:Loc}"/> | |||
| <Button x:Name="removeButton" Margin="4 8 8 8" | |||
| MinWidth="75" Content="{lex:Loc}"/> | |||
| </StackPanel> | |||
| <TextBlock Margin="8 4 4 8" | |||
| Grid.Row="1" | |||
| Grid.Column="0">URL</TextBlock> | |||
| <TextBox x:Name="urlTextBox" Margin="4 4 4 8" | |||
| Grid.Row="1" | |||
| Grid.Column="1"/> | |||
| <Button x:Name="addButton" Margin="4 4 8 8" | |||
| Grid.Row="1" | |||
| Grid.Column="2" | |||
| MinWidth="75" | |||
| Content="{lex:Loc}"/> | |||
| </Grid> | |||
| </reactiveui:ReactiveUserControl> | |||
| @@ -0,0 +1,54 @@ | |||
| using ReactiveUI; | |||
| using Shadowsocks.ViewModels; | |||
| using System.Reactive.Disposables; | |||
| namespace Shadowsocks.Views | |||
| { | |||
| /// <summary> | |||
| /// Interaction logic for OnlineConfigView.xaml | |||
| /// </summary> | |||
| public partial class OnlineConfigView : ReactiveUserControl<OnlineConfigViewModel> | |||
| { | |||
| public OnlineConfigView() | |||
| { | |||
| InitializeComponent(); | |||
| ViewModel = new OnlineConfigViewModel(); | |||
| this.WhenActivated(disposables => | |||
| { | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.Sources, | |||
| view => view.sourcesListBox.ItemsSource) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.SelectedSource, | |||
| view => view.sourcesListBox.SelectedItem) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.Address, | |||
| view => view.urlTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.Update, | |||
| view => view.updateButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.UpdateAll, | |||
| view => view.updateAllButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.CopyLink, | |||
| view => view.copyLinkButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.Remove, | |||
| view => view.removeButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.Add, | |||
| view => view.addButton) | |||
| .DisposeWith(disposables); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,11 +1,19 @@ | |||
| <UserControl x:Class="Shadowsocks.Views.ServerSharingView" | |||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
| xmlns:local="clr-namespace:Shadowsocks.Views" | |||
| mc:Ignorable="d" | |||
| d:DesignHeight="400" d:DesignWidth="660"> | |||
| <reactiveui:ReactiveUserControl | |||
| x:Class="Shadowsocks.Views.ServerSharingView" | |||
| x:TypeArguments="vms:ServerSharingViewModel" | |||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
| xmlns:local="clr-namespace:Shadowsocks.Views" | |||
| xmlns:vms="clr-namespace:Shadowsocks.ViewModels" | |||
| xmlns:reactiveui="http://reactiveui.net" | |||
| xmlns:lex="http://wpflocalizeextension.codeplex.com" | |||
| lex:LocalizeDictionary.DesignCulture="en" | |||
| lex:ResxLocalizationProvider.DefaultAssembly="Shadowsocks" | |||
| lex:ResxLocalizationProvider.DefaultDictionary="Strings" | |||
| mc:Ignorable="d" | |||
| d:DesignHeight="400" d:DesignWidth="660"> | |||
| <Grid Margin="8"> | |||
| <Grid.RowDefinitions> | |||
| <RowDefinition Height="*" /> | |||
| @@ -15,22 +23,31 @@ | |||
| <ColumnDefinition Width="*" /> | |||
| <ColumnDefinition Width="*" /> | |||
| </Grid.ColumnDefinitions> | |||
| <Image Grid.Row="0" | |||
| <Image x:Name="qrCodeImage" Grid.Row="0" | |||
| Grid.Column="0" | |||
| Margin="8" | |||
| Source="{Binding SelectedServerUrlImage}"/> | |||
| <ListBox Grid.Row="0" | |||
| Margin="8"/> | |||
| <ListBox x:Name="serversListBox" Grid.Row="0" | |||
| Grid.Column="1" | |||
| Margin="8" | |||
| ItemsSource="{Binding Servers}" | |||
| SelectedItem="{Binding SelectedServer}"/> | |||
| <TextBox x:Name="urlTextBox" | |||
| Grid.Row="1" | |||
| Margin="8"> | |||
| <ListBox.ItemTemplate> | |||
| <DataTemplate> | |||
| <TextBlock Text="{Binding}"/> | |||
| </DataTemplate> | |||
| </ListBox.ItemTemplate> | |||
| </ListBox> | |||
| <Grid Grid.Row="1" | |||
| Grid.Column="0" | |||
| Grid.ColumnSpan="2"> | |||
| <Grid.ColumnDefinitions> | |||
| <ColumnDefinition Width="*" /> | |||
| <ColumnDefinition Width="Auto" /> | |||
| </Grid.ColumnDefinitions> | |||
| <TextBox x:Name="urlTextBox" | |||
| Grid.Column="0" | |||
| Grid.ColumnSpan="2" | |||
| Margin="8" | |||
| Margin="8 8 4 8" | |||
| IsReadOnly="True" | |||
| Text="{Binding SelectedServerUrl}" | |||
| PreviewMouseDoubleClick="urlTextBox_PreviewMouseDoubleClick"/> | |||
| <Button x:Name="copyLinkButton" Grid.Column="1" Margin="4 8 8 8" MinWidth="36" Content="{lex:Loc Copy}"/> | |||
| </Grid> | |||
| </Grid> | |||
| </UserControl> | |||
| </reactiveui:ReactiveUserControl> | |||
| @@ -1,5 +1,6 @@ | |||
| using Shadowsocks.ViewModels; | |||
| using System.Windows.Controls; | |||
| using ReactiveUI; | |||
| using Shadowsocks.ViewModels; | |||
| using System.Reactive.Disposables; | |||
| using System.Windows.Input; | |||
| namespace Shadowsocks.Views | |||
| @@ -7,13 +8,36 @@ namespace Shadowsocks.Views | |||
| /// <summary> | |||
| /// Interaction logic for ServerSharingView.xaml | |||
| /// </summary> | |||
| public partial class ServerSharingView : UserControl | |||
| public partial class ServerSharingView : ReactiveUserControl<ServerSharingViewModel> | |||
| { | |||
| public ServerSharingView() | |||
| { | |||
| InitializeComponent(); | |||
| ViewModel = new ServerSharingViewModel(); | |||
| this.WhenActivated(disposables => | |||
| { | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.SelectedServerUrlImage, | |||
| view => view.qrCodeImage.Source) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.Servers, | |||
| view => view.serversListBox.ItemsSource) | |||
| .DisposeWith(disposables); | |||
| this.Bind(ViewModel, | |||
| viewModel => viewModel.SelectedServer, | |||
| view => view.serversListBox.SelectedItem) | |||
| .DisposeWith(disposables); | |||
| this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.SelectedServerUrl, | |||
| view => view.urlTextBox.Text) | |||
| .DisposeWith(disposables); | |||
| DataContext = new ServerSharingViewModel(); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.CopyLink, | |||
| view => view.copyLinkButton) | |||
| .DisposeWith(disposables); | |||
| }); | |||
| } | |||
| private void urlTextBox_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) | |||
| @@ -0,0 +1,43 @@ | |||
| <reactiveui:ReactiveUserControl | |||
| x:Class="Shadowsocks.Views.VersionUpdatePromptView" | |||
| x:TypeArguments="vms:VersionUpdatePromptViewModel" | |||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
| xmlns:local="clr-namespace:Shadowsocks.Views" | |||
| xmlns:vms="clr-namespace:Shadowsocks.ViewModels" | |||
| xmlns:reactiveui="http://reactiveui.net" | |||
| xmlns:mdxam="clr-namespace:MdXaml;assembly=MdXaml" | |||
| xmlns:lex="http://wpflocalizeextension.codeplex.com" | |||
| lex:LocalizeDictionary.DesignCulture="en" | |||
| lex:ResxLocalizationProvider.DefaultAssembly="Shadowsocks" | |||
| lex:ResxLocalizationProvider.DefaultDictionary="Strings" | |||
| mc:Ignorable="d" | |||
| d:DesignHeight="480" d:DesignWidth="640"> | |||
| <Grid Margin="8"> | |||
| <Grid.RowDefinitions> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="Auto" /> | |||
| <RowDefinition Height="*" /> | |||
| <RowDefinition Height="Auto" /> | |||
| </Grid.RowDefinitions> | |||
| <TextBlock Margin="8 8 8 4" Grid.Row="0" | |||
| FontSize="16" | |||
| Text="{lex:Loc updatePromptTitle}" /> | |||
| <TextBlock Margin="8 4 8 8" Grid.Row="1" | |||
| Text="{lex:Loc updatePromptBody}" /> | |||
| <mdxam:MarkdownScrollViewer x:Name="releaseNotesMarkdownScrollViewer" | |||
| Margin="8" | |||
| Grid.Row="2" | |||
| Markdown="{Binding ReleaseNotes}" | |||
| MarkdownStyle="{x:Static mdxam:MarkdownStyle.GithubLike}"/> | |||
| <StackPanel Orientation="Horizontal" Grid.Row="3"> | |||
| <Button x:Name="updateButton" Margin="8 8 4 4" Width="75" Height="23" Content="{lex:Loc}"/> | |||
| </StackPanel> | |||
| <StackPanel Orientation="Horizontal" Grid.Row="3" HorizontalAlignment="Right"> | |||
| <Button x:Name="skipVersionButton" Margin="4 8 4 4" Width="75" Height="23" Content="{lex:Loc}"/> | |||
| <Button x:Name="notNowButton" Margin="4 8 8 4" Width="75" Height="23" Content="{lex:Loc}"/> | |||
| </StackPanel> | |||
| </Grid> | |||
| </reactiveui:ReactiveUserControl> | |||
| @@ -0,0 +1,40 @@ | |||
| using Newtonsoft.Json.Linq; | |||
| using ReactiveUI; | |||
| using Shadowsocks.ViewModels; | |||
| using System.Reactive.Disposables; | |||
| namespace Shadowsocks.Views | |||
| { | |||
| /// <summary> | |||
| /// Interaction logic for VersionUpdatePromptView.xaml | |||
| /// </summary> | |||
| public partial class VersionUpdatePromptView : ReactiveUserControl<VersionUpdatePromptViewModel> | |||
| { | |||
| public VersionUpdatePromptView(JToken releaseObject) | |||
| { | |||
| InitializeComponent(); | |||
| ViewModel = new VersionUpdatePromptViewModel(releaseObject); | |||
| DataContext = ViewModel; // for compatibility with MdXaml | |||
| this.WhenActivated(disposables => | |||
| { | |||
| /*this.OneWayBind(ViewModel, | |||
| viewModel => viewModel.ReleaseNotes, | |||
| view => releaseNotesMarkdownScrollViewer.Markdown) | |||
| .DisposeWith(disposables);*/ | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.Update, | |||
| view => view.updateButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.SkipVersion, | |||
| view => view.skipVersionButton) | |||
| .DisposeWith(disposables); | |||
| this.BindCommand(ViewModel, | |||
| viewModel => viewModel.NotNow, | |||
| view => view.notNowButton) | |||
| .DisposeWith(disposables); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -26,6 +26,10 @@ | |||
| <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> | |||
| <bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" /> | |||
| </dependentAssembly> | |||
| <dependentAssembly> | |||
| <assemblyIdentity name="ICSharpCode.AvalonEdit" publicKeyToken="9cc39be672370310" culture="neutral" /> | |||
| <bindingRedirect oldVersion="0.0.0.0-6.0.1.278" newVersion="6.0.1.278" /> | |||
| </dependentAssembly> | |||
| </assemblyBinding> | |||
| </runtime> | |||
| <userSettings> | |||
| @@ -1,17 +1,23 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <packages> | |||
| <package id="AvalonEdit" version="6.0.1" targetFramework="net472" /> | |||
| <package id="Caseless.Fody" version="1.9.0" targetFramework="net472" /> | |||
| <package id="CommandLineParser" version="2.8.0" targetFramework="net472" /> | |||
| <package id="Costura.Fody" version="4.1.0" targetFramework="net472" /> | |||
| <package id="DynamicData" version="6.17.14" targetFramework="net472" /> | |||
| <package id="Fody" version="6.2.6" targetFramework="net472" developmentDependency="true" /> | |||
| <package id="Fody" version="6.3.0" targetFramework="net472" developmentDependency="true" /> | |||
| <package id="GlobalHotKey" version="1.1.0" targetFramework="net472" /> | |||
| <package id="Google.Protobuf" version="3.13.0" targetFramework="net472" /> | |||
| <package id="MdXaml" version="1.6.0" targetFramework="net472" /> | |||
| <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" /> | |||
| <package id="NLog" version="4.7.5" targetFramework="net472" /> | |||
| <package id="Pharmacist.Common" version="1.8.1" targetFramework="net472" /> | |||
| <package id="ReactiveUI" version="11.5.35" targetFramework="net472" /> | |||
| <package id="ReactiveUI.Events.WPF" version="11.5.35" targetFramework="net472" /> | |||
| <package id="ReactiveUI.Fody" version="11.5.35" targetFramework="net472" /> | |||
| <package id="ReactiveUI.Validation" version="1.7.1" targetFramework="net472" /> | |||
| <package id="ReactiveUI.WPF" version="11.5.35" targetFramework="net472" /> | |||
| <package id="Splat" version="9.5.49" targetFramework="net472" /> | |||
| <package id="Splat" version="9.6.1" targetFramework="net472" /> | |||
| <package id="System.Buffers" version="4.5.1" targetFramework="net472" /> | |||
| <package id="System.IO" version="4.3.0" targetFramework="net472" /> | |||
| <package id="System.Memory" version="4.5.4" targetFramework="net472" /> | |||
| @@ -26,5 +32,7 @@ | |||
| <package id="System.Security.Cryptography.X509Certificates" version="4.3.2" targetFramework="net472" /> | |||
| <package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" /> | |||
| <package id="System.ValueTuple" version="4.5.0" targetFramework="net472" /> | |||
| <package id="WPFLocalizeExtension" version="3.8.0" targetFramework="net472" /> | |||
| <package id="XAMLMarkupExtensions" version="2.0.0" targetFramework="net472" /> | |||
| <package id="ZXing.Net" version="0.16.6" targetFramework="net472" /> | |||
| </packages> | |||
| @@ -1,5 +1,6 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <Import Project="..\packages\ReactiveUI.Fody.11.5.35\build\ReactiveUI.Fody.props" Condition="Exists('..\packages\ReactiveUI.Fody.11.5.35\build\ReactiveUI.Fody.props')" /> | |||
| <Import Project="..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" /> | |||
| <Import Project="..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props" Condition="Exists('..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props')" /> | |||
| <PropertyGroup> | |||
| @@ -87,6 +88,12 @@ | |||
| <Reference Include="Google.Protobuf, Version=3.13.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\Google.Protobuf.3.13.0\lib\net45\Google.Protobuf.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="ICSharpCode.AvalonEdit, Version=6.0.1.278, Culture=neutral, PublicKeyToken=9cc39be672370310, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\AvalonEdit.6.0.1\lib\net45\ICSharpCode.AvalonEdit.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="MdXaml, Version=1.6.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\MdXaml.1.6.0\lib\net45\MdXaml.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="Microsoft.CSharp" /> | |||
| <Reference Include="Microsoft.VisualBasic" /> | |||
| <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
| @@ -95,16 +102,29 @@ | |||
| <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\NLog.4.7.5\lib\net45\NLog.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="Pharmacist.Common, Version=1.8.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\Pharmacist.Common.1.8.1\lib\netstandard2.0\Pharmacist.Common.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="PresentationCore" /> | |||
| <Reference Include="PresentationFramework" /> | |||
| <Reference Include="PresentationFramework.Aero" /> | |||
| <Reference Include="ReactiveUI, Version=11.5.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\ReactiveUI.11.5.35\lib\net461\ReactiveUI.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="ReactiveUI.Events.WPF, Version=11.5.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\ReactiveUI.Events.WPF.11.5.35\lib\net472\ReactiveUI.Events.WPF.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="ReactiveUI.Fody.Helpers, Version=11.5.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\ReactiveUI.Fody.11.5.35\lib\net461\ReactiveUI.Fody.Helpers.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="ReactiveUI.Validation, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\ReactiveUI.Validation.1.7.1\lib\net461\ReactiveUI.Validation.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="ReactiveUI.WPF, Version=11.5.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\ReactiveUI.WPF.11.5.35\lib\net472\ReactiveUI.WPF.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="Splat, Version=9.5.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\Splat.9.5.49\lib\net461\Splat.dll</HintPath> | |||
| <Reference Include="Splat, Version=9.6.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\Splat.9.6.1\lib\net461\Splat.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="System" /> | |||
| <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||
| @@ -184,6 +204,12 @@ | |||
| <Reference Include="UIAutomationProvider" /> | |||
| <Reference Include="WindowsBase" /> | |||
| <Reference Include="WindowsFormsIntegration" /> | |||
| <Reference Include="WPFLocalizeExtension, Version=3.8.0.0, Culture=neutral, PublicKeyToken=c726e0262981a1eb, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\WPFLocalizeExtension.3.8.0\lib\net452\WPFLocalizeExtension.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="XAMLMarkupExtensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=c726e0262981a1eb, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\XAMLMarkupExtensions.2.0.0\lib\net472\XAMLMarkupExtensions.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="zxing, Version=0.16.6.0, Culture=neutral, PublicKeyToken=4e88037ac681fe60, processorArchitecture=MSIL"> | |||
| <HintPath>..\packages\ZXing.Net.0.16.6\lib\net47\zxing.dll</HintPath> | |||
| </Reference> | |||
| @@ -218,10 +244,16 @@ | |||
| <Compile Include="Encryption\Stream\StreamMbedTLSEncryptor.cs" /> | |||
| <Compile Include="Encryption\Stream\StreamOpenSSLEncryptor.cs" /> | |||
| <Compile Include="Encryption\Stream\StreamSodiumEncryptor.cs" /> | |||
| <Compile Include="Localization\LocalizationProvider.cs" /> | |||
| <Compile Include="Localization\Strings.Designer.cs"> | |||
| <AutoGen>True</AutoGen> | |||
| <DesignTime>True</DesignTime> | |||
| <DependentUpon>Strings.resx</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="Model\Geosite\Geosite.cs" /> | |||
| <Compile Include="Model\HotKeyConfig.cs" /> | |||
| <Compile Include="Model\NLogConfig.cs" /> | |||
| <Compile Include="Model\ProxyConfig.cs" /> | |||
| <Compile Include="Model\ForwardProxyConfig.cs" /> | |||
| <Compile Include="Model\SysproxyConfig.cs" /> | |||
| <Compile Include="Properties\Resources.Designer.cs"> | |||
| <AutoGen>True</AutoGen> | |||
| @@ -268,7 +300,23 @@ | |||
| <Compile Include="Util\SystemProxy\Sysproxy.cs" /> | |||
| <Compile Include="Util\Util.cs" /> | |||
| <Compile Include="Util\ViewUtils.cs" /> | |||
| <Compile Include="ViewModels\ForwardProxyViewModel.cs" /> | |||
| <Compile Include="ViewModels\HotkeysViewModel.cs" /> | |||
| <Compile Include="ViewModels\OnlineConfigViewModel.cs" /> | |||
| <Compile Include="ViewModels\ServerSharingViewModel.cs" /> | |||
| <Compile Include="ViewModels\VersionUpdatePromptViewModel.cs" /> | |||
| <Compile Include="Views\ForwardProxyView.xaml.cs"> | |||
| <DependentUpon>ForwardProxyView.xaml</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="Views\HotkeysView.xaml.cs"> | |||
| <DependentUpon>HotkeysView.xaml</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="Views\OnlineConfigView.xaml.cs"> | |||
| <DependentUpon>OnlineConfigView.xaml</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="Views\VersionUpdatePromptView.xaml.cs"> | |||
| <DependentUpon>VersionUpdatePromptView.xaml</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="View\ConfigForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| @@ -287,12 +335,6 @@ | |||
| <Compile Include="View\CalculationControl.Designer.cs"> | |||
| <DependentUpon>CalculationControl.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="View\HotkeySettingsForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="View\HotkeySettingsForm.designer.cs"> | |||
| <DependentUpon>HotkeySettingsForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="View\LogForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| @@ -300,18 +342,6 @@ | |||
| <DependentUpon>LogForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="View\MenuViewController.cs" /> | |||
| <Compile Include="View\OnlineConfigForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="View\OnlineConfigForm.Designer.cs"> | |||
| <DependentUpon>OnlineConfigForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="View\ProxyForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="View\ProxyForm.Designer.cs"> | |||
| <DependentUpon>ProxyForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="View\QRCodeSplashForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| @@ -324,30 +354,31 @@ | |||
| <Compile Include="View\StatisticsStrategyConfigurationForm.Designer.cs"> | |||
| <DependentUpon>StatisticsStrategyConfigurationForm.cs</DependentUpon> | |||
| </Compile> | |||
| <EmbeddedResource Include="Localization\Strings.fr.resx" /> | |||
| <EmbeddedResource Include="Localization\Strings.ja.resx" /> | |||
| <EmbeddedResource Include="Localization\Strings.ko.resx" /> | |||
| <EmbeddedResource Include="Localization\Strings.resx"> | |||
| <Generator>ResXFileCodeGenerator</Generator> | |||
| <LastGenOutput>Strings.Designer.cs</LastGenOutput> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="Localization\Strings.ru.resx" /> | |||
| <EmbeddedResource Include="Localization\Strings.zh-Hans.resx" /> | |||
| <EmbeddedResource Include="Localization\Strings.zh-Hant.resx" /> | |||
| <EmbeddedResource Include="View\ConfigForm.resx"> | |||
| <DependentUpon>ConfigForm.cs</DependentUpon> | |||
| <SubType>Designer</SubType> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="Properties\Resources.resx"> | |||
| <Generator>ResXFileCodeGenerator</Generator> | |||
| <Generator>PublicResXFileCodeGenerator</Generator> | |||
| <SubType>Designer</SubType> | |||
| <LastGenOutput>Resources.Designer.cs</LastGenOutput> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="View\CalculationControl.resx"> | |||
| <DependentUpon>CalculationControl.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="View\HotkeySettingsForm.resx"> | |||
| <DependentUpon>HotkeySettingsForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="View\LogForm.resx"> | |||
| <DependentUpon>LogForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="View\OnlineConfigForm.resx"> | |||
| <DependentUpon>OnlineConfigForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="View\ProxyForm.resx"> | |||
| <DependentUpon>ProxyForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="View\StatisticsStrategyConfigurationForm.resx"> | |||
| <DependentUpon>StatisticsStrategyConfigurationForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| @@ -412,22 +443,39 @@ | |||
| </BootstrapperPackage> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Page Include="Views\ForwardProxyView.xaml"> | |||
| <SubType>Designer</SubType> | |||
| <Generator>MSBuild:Compile</Generator> | |||
| </Page> | |||
| <Page Include="Views\HotkeysView.xaml"> | |||
| <SubType>Designer</SubType> | |||
| <Generator>MSBuild:Compile</Generator> | |||
| </Page> | |||
| <Page Include="Views\OnlineConfigView.xaml"> | |||
| <SubType>Designer</SubType> | |||
| <Generator>MSBuild:Compile</Generator> | |||
| </Page> | |||
| <Page Include="Views\ServerSharingView.xaml"> | |||
| <SubType>Designer</SubType> | |||
| <Generator>MSBuild:Compile</Generator> | |||
| </Page> | |||
| <Page Include="Views\VersionUpdatePromptView.xaml"> | |||
| <SubType>Designer</SubType> | |||
| <Generator>MSBuild:Compile</Generator> | |||
| </Page> | |||
| </ItemGroup> | |||
| <ItemGroup /> | |||
| <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
| <Import Project="..\packages\Fody.6.2.6\build\Fody.targets" Condition="Exists('..\packages\Fody.6.2.6\build\Fody.targets')" /> | |||
| <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||
| <PropertyGroup> | |||
| <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |||
| </PropertyGroup> | |||
| <Error Condition="!Exists('..\packages\Fody.6.2.6\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.2.6\build\Fody.targets'))" /> | |||
| <Error Condition="!Exists('..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props'))" /> | |||
| <Error Condition="!Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" /> | |||
| <Error Condition="!Exists('..\packages\Fody.6.3.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.3.0\build\Fody.targets'))" /> | |||
| <Error Condition="!Exists('..\packages\ReactiveUI.Fody.11.5.35\build\ReactiveUI.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\ReactiveUI.Fody.11.5.35\build\ReactiveUI.Fody.props'))" /> | |||
| </Target> | |||
| <Import Project="..\packages\Fody.6.3.0\build\Fody.targets" Condition="Exists('..\packages\Fody.6.3.0\build\Fody.targets')" /> | |||
| <!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||
| Other similar extension points exist, see Microsoft.Common.targets. | |||
| <Target Name="BeforeBuild"> | |||
| @@ -10,6 +10,10 @@ | |||
| <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> | |||
| <bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" /> | |||
| </dependentAssembly> | |||
| <dependentAssembly> | |||
| <assemblyIdentity name="ICSharpCode.AvalonEdit" publicKeyToken="9cc39be672370310" culture="neutral" /> | |||
| <bindingRedirect oldVersion="0.0.0.0-6.0.1.278" newVersion="6.0.1.278" /> | |||
| </dependentAssembly> | |||
| </assemblyBinding> | |||
| </runtime> | |||
| </configuration> | |||