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