From 040ae7981c245b829141adac50bfffa20259f149 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 8 Nov 2014 20:05:11 +0800 Subject: [PATCH] add qrcode form --- .../Controller/ShadowsocksController.cs | 8 ++ shadowsocks-csharp/Data/qrcode.htm | 29 +++-- shadowsocks-csharp/Data/qrcode.min.js.gz | Bin 7029 -> 7024 bytes .../Properties/Resources.Designer.cs | 45 ++++++++ shadowsocks-csharp/Properties/Resources.resx | 6 ++ shadowsocks-csharp/View/ConfigForm.Designer.cs | 15 ++- shadowsocks-csharp/View/ConfigForm.cs | 5 + shadowsocks-csharp/View/QRCodeForm.Designer.cs | 64 +++++++++++ shadowsocks-csharp/View/QRCodeForm.cs | 52 +++++++++ shadowsocks-csharp/View/QRCodeForm.resx | 120 +++++++++++++++++++++ shadowsocks-csharp/shadowsocks-csharp.csproj | 13 +++ 11 files changed, 344 insertions(+), 13 deletions(-) create mode 100755 shadowsocks-csharp/View/QRCodeForm.Designer.cs create mode 100755 shadowsocks-csharp/View/QRCodeForm.cs create mode 100755 shadowsocks-csharp/View/QRCodeForm.resx diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 5823e448..4111d2b8 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -116,6 +116,14 @@ namespace Shadowsocks.Controller } } + public string GetQRCodeForCurrentServer() + { + Server server = GetCurrentServer(); + string parts = server.method + ":" + server.password + "@" + server.server + ":" + server.server_port; + string base64 = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); + return "ss://" + base64; + } + private void updateSystemProxy() { if (config.enabled) diff --git a/shadowsocks-csharp/Data/qrcode.htm b/shadowsocks-csharp/Data/qrcode.htm index c792bc35..c8729dba 100644 --- a/shadowsocks-csharp/Data/qrcode.htm +++ b/shadowsocks-csharp/Data/qrcode.htm @@ -1,28 +1,37 @@ - - -
+ + +
\ No newline at end of file + genCode("__SSURL__"); + + + diff --git a/shadowsocks-csharp/Data/qrcode.min.js.gz b/shadowsocks-csharp/Data/qrcode.min.js.gz index 0dbeb45956d82a08ffa0a968cde6b51d6c210b93..48de1fc93338099581c838b819610ad49c89737a 100644 GIT binary patch delta 1570 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 ZrBc)qkZ8)%hqfq6+J6GMT}; + /// Looks up a localized string similar to <!doctype html> + ///<html> + ///<head> + ///<script> + /// __QRCODELIB__ + ///</script> + ///<style> + /// body { + /// padding: 10px; + /// margin: 0; + /// } + /// #qrcode { + /// width:300px; + /// height:300px; + /// } + ///</style> + ///</head> + ///<body> + ///<div id="qrcode" name="qrcode"></div> + ///<script type="text/javascript"> + /// function genCode(code) { + /// new QRCode("qrcode", { + /// text: code, + /// width: 300, + /// height: 300, + /// colorDark : "#000000", + /// colorLig [rest of string was truncated]";. + /// + internal static string qrcode { + get { + return ResourceManager.GetString("qrcode", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] qrcode_min_js { + get { + object obj = ResourceManager.GetObject("qrcode_min_js", resourceCulture); + return ((byte[])(obj)); + } + } } } diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index 14c098ec..520c1732 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -130,4 +130,10 @@ ..\Data\proxy.pac.txt.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Data\qrcode.htm;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;gb2312 + + + ..\Data\qrcode.min.js.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 2447e311..6d6f8881 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -63,6 +63,7 @@ this.AddButton = new System.Windows.Forms.Button(); this.ServerGroupBox = new System.Windows.Forms.GroupBox(); this.ServersListBox = new System.Windows.Forms.ListBox(); + this.QRCodeItem = new System.Windows.Forms.MenuItem(); this.tableLayoutPanel1.SuspendLayout(); this.panel1.SuspendLayout(); this.panel3.SuspendLayout(); @@ -287,6 +288,7 @@ this.ServersItem, this.menuItem4, this.editPACFileItem, + this.QRCodeItem, this.aboutItem, this.menuItem3, this.quitItem}); @@ -329,18 +331,18 @@ // // aboutItem // - this.aboutItem.Index = 4; + this.aboutItem.Index = 5; this.aboutItem.Text = "About..."; this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); // // menuItem3 // - this.menuItem3.Index = 5; + this.menuItem3.Index = 6; this.menuItem3.Text = "-"; // // quitItem // - this.quitItem.Index = 6; + this.quitItem.Index = 7; this.quitItem.Text = "&Quit"; this.quitItem.Click += new System.EventHandler(this.Quit_Click); // @@ -394,6 +396,12 @@ this.ServersListBox.TabIndex = 5; this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); // + // QRCodeItem + // + this.QRCodeItem.Index = 4; + this.QRCodeItem.Text = "Show &QRCode..."; + this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); + // // ConfigForm // this.AcceptButton = this.OKButton; @@ -461,6 +469,7 @@ private System.Windows.Forms.MenuItem menuItem4; private System.Windows.Forms.TextBox RemarksTextBox; private System.Windows.Forms.Label label6; + private System.Windows.Forms.MenuItem QRCodeItem; } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 208e683a..174d10fd 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -302,5 +302,10 @@ namespace Shadowsocks.View { IPTextBox.Focus(); } + + private void QRCodeItem_Click(object sender, EventArgs e) + { + new QRCodeForm(controller.GetQRCodeForCurrentServer()).Show(); + } } } diff --git a/shadowsocks-csharp/View/QRCodeForm.Designer.cs b/shadowsocks-csharp/View/QRCodeForm.Designer.cs new file mode 100755 index 00000000..34ca088c --- /dev/null +++ b/shadowsocks-csharp/View/QRCodeForm.Designer.cs @@ -0,0 +1,64 @@ +namespace Shadowsocks.View +{ + partial class QRCodeForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.QRCodeWebBrowser = new System.Windows.Forms.WebBrowser(); + this.SuspendLayout(); + // + // QRCodeWebBrowser + // + this.QRCodeWebBrowser.Dock = System.Windows.Forms.DockStyle.Fill; + this.QRCodeWebBrowser.Location = new System.Drawing.Point(0, 0); + this.QRCodeWebBrowser.MinimumSize = new System.Drawing.Size(20, 20); + this.QRCodeWebBrowser.Name = "QRCodeWebBrowser"; + this.QRCodeWebBrowser.ScriptErrorsSuppressed = true; + this.QRCodeWebBrowser.ScrollBarsEnabled = false; + this.QRCodeWebBrowser.Size = new System.Drawing.Size(184, 182); + this.QRCodeWebBrowser.TabIndex = 0; + // + // QRCodeForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(184, 182); + this.Controls.Add(this.QRCodeWebBrowser); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.Name = "QRCodeForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Load += new System.EventHandler(this.QRCodeForm_Load); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.WebBrowser QRCodeWebBrowser; + } +} \ No newline at end of file diff --git a/shadowsocks-csharp/View/QRCodeForm.cs b/shadowsocks-csharp/View/QRCodeForm.cs new file mode 100755 index 00000000..36c2c804 --- /dev/null +++ b/shadowsocks-csharp/View/QRCodeForm.cs @@ -0,0 +1,52 @@ +using Shadowsocks.Properties; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.IO.Compression; +using System.Text; +using System.Windows.Forms; + +namespace Shadowsocks.View +{ + public partial class QRCodeForm : Form + { + private string code; + + public QRCodeForm(string code) + { + this.code = code; + InitializeComponent(); + } + + private string QRCodeHTML(string ssURL) + { + string html = Resources.qrcode; + string qrcodeLib; + + byte[] qrcodeGZ = Resources.qrcode_min_js; + byte[] buffer = new byte[1024 * 1024]; // builtin pac gzip size: maximum 1M + int n; + + using (GZipStream input = new GZipStream(new MemoryStream(qrcodeGZ), + CompressionMode.Decompress, false)) + { + n = input.Read(buffer, 0, buffer.Length); + if (n == 0) + { + throw new IOException("can not decompress qrcode lib"); + } + qrcodeLib = System.Text.Encoding.UTF8.GetString(buffer, 0, n); + } + string result = html.Replace("__QRCODELIB__", qrcodeLib); + return result.Replace("__SSURL__", ssURL); + } + + private void QRCodeForm_Load(object sender, EventArgs e) + { + QRCodeWebBrowser.DocumentText = QRCodeHTML(code); + } + } +} diff --git a/shadowsocks-csharp/View/QRCodeForm.resx b/shadowsocks-csharp/View/QRCodeForm.resx new file mode 100755 index 00000000..5ea0895e --- /dev/null +++ b/shadowsocks-csharp/View/QRCodeForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index bc811330..22422445 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -79,8 +79,10 @@ + + @@ -106,6 +108,12 @@ + + Form + + + QRCodeForm.cs + ConfigForm.cs Designer @@ -120,9 +128,13 @@ Resources.resx True + + QRCodeForm.cs + + SettingsSingleFileGenerator Settings.Designer.cs @@ -135,6 +147,7 @@ +