Improve sharing server profiles.
* New share server profiles window. * Import server profile urls from pasteboard.
This commit is contained in:
19
README.md
19
README.md
@ -6,7 +6,7 @@ Current version is 1.8.0
|
|||||||
|
|
||||||
Next Generation of [ShadowsocksX](https://github.com/shadowsocks/shadowsocks-iOS)
|
Next Generation of [ShadowsocksX](https://github.com/shadowsocks/shadowsocks-iOS)
|
||||||
|
|
||||||
## Why?
|
## Why a new implementation?
|
||||||
|
|
||||||
It's hard to maintain the original implementation as there is too much unused code in it.
|
It's hard to maintain the original implementation as there is too much unused code in it.
|
||||||
It also embeds the `ss-local` source. It's crazy to maintain dependencies of `ss-local`.
|
It also embeds the `ss-local` source. It's crazy to maintain dependencies of `ss-local`.
|
||||||
@ -36,21 +36,12 @@ From [here](https://github.com/shadowsocks/ShadowsocksX-NG/releases/)
|
|||||||
- `ss-local` from shadowsocks-libev 3.2.0
|
- `ss-local` from shadowsocks-libev 3.2.0
|
||||||
- Support SIP003 plugins. Embed `kcptun` and `simple-obfs`.
|
- Support SIP003 plugins. Embed `kcptun` and `simple-obfs`.
|
||||||
- Could update PAC by download GFW List from GitHub.
|
- Could update PAC by download GFW List from GitHub.
|
||||||
- Shows QRCode for current server profile in legacy and SIP002 format.
|
- Share your server profiles by qrcode or url.
|
||||||
- Scans QRCode from screen.
|
- Import server profile urls from pasteboard.
|
||||||
- Auto launch at login.
|
- Import server profile by scan QRCode on screen.
|
||||||
- User rules for PAC.
|
- Custom rules for PAC.
|
||||||
- Support for [AEAD Ciphers](https://shadowsocks.org/en/spec/AEAD-Ciphers.html)
|
- Support for [AEAD Ciphers](https://shadowsocks.org/en/spec/AEAD-Ciphers.html)
|
||||||
- HTTP Proxy by [privoxy](http://www.privoxy.org/)
|
- HTTP Proxy by [privoxy](http://www.privoxy.org/)
|
||||||
- An advanced preferences panel for configuring:
|
|
||||||
- Local SOCKS5 listen address.
|
|
||||||
- Local SOCKS5 listen port.
|
|
||||||
- Local SOCKS5 timeout.
|
|
||||||
- If enable UDP relay.
|
|
||||||
- GFW List URL.
|
|
||||||
- Manually specify network service profiles which would be used to configure the proxy.
|
|
||||||
- Could reorder shadowsocks profiles by drag-&-dropping in servers preferences panel.
|
|
||||||
- Configurable global shortcuts for toggle running and switch proxy mode.
|
|
||||||
|
|
||||||
## Difference from original ShadowsocksX
|
## Difference from original ShadowsocksX
|
||||||
|
|
||||||
|
@ -46,10 +46,11 @@
|
|||||||
9B5832031E741F8D009D5B7D /* command-512.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B5832021E741F8D009D5B7D /* command-512.png */; };
|
9B5832031E741F8D009D5B7D /* command-512.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B5832021E741F8D009D5B7D /* command-512.png */; };
|
||||||
9B5832071E7421B2009D5B7D /* virtual-server-icon-3.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B5832061E7421B2009D5B7D /* virtual-server-icon-3.png */; };
|
9B5832071E7421B2009D5B7D /* virtual-server-icon-3.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B5832061E7421B2009D5B7D /* virtual-server-icon-3.png */; };
|
||||||
9B58320B1E7422DB009D5B7D /* http.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B58320A1E7422DB009D5B7D /* http.png */; };
|
9B58320B1E7422DB009D5B7D /* http.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B58320A1E7422DB009D5B7D /* http.png */; };
|
||||||
9B5832111E742632009D5B7D /* kcptun_1.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B5832101E742632009D5B7D /* kcptun_1.png */; };
|
|
||||||
9B5AA0AC209C43C200E8B659 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 9B5AA0AB209C43C200E8B659 /* Credits.rtf */; };
|
9B5AA0AC209C43C200E8B659 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 9B5AA0AB209C43C200E8B659 /* Credits.rtf */; };
|
||||||
9B6BF9541E27B2570061B9A7 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B6BF9531E27B2570061B9A7 /* ServiceManagement.framework */; };
|
9B6BF9541E27B2570061B9A7 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B6BF9531E27B2570061B9A7 /* ServiceManagement.framework */; };
|
||||||
9B7297E7214D69C300FD24AA /* libmbedcrypto.2.12.0.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 9B7297E5214D68F800FD24AA /* libmbedcrypto.2.12.0.dylib */; };
|
9B7297E7214D69C300FD24AA /* libmbedcrypto.2.12.0.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 9B7297E5214D68F800FD24AA /* libmbedcrypto.2.12.0.dylib */; };
|
||||||
|
9B7297EA214D7C6B00FD24AA /* ShareServerProfilesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B7297E8214D7C6B00FD24AA /* ShareServerProfilesWindowController.swift */; };
|
||||||
|
9B7297EC214DA88A00FD24AA /* ShareServerProfilesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B7297EE214DA88A00FD24AA /* ShareServerProfilesWindowController.xib */; };
|
||||||
9B86459D1E7C2CAD00A84029 /* ProxyInterfacesViewCtrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B86459C1E7C2CAD00A84029 /* ProxyInterfacesViewCtrl.swift */; };
|
9B86459D1E7C2CAD00A84029 /* ProxyInterfacesViewCtrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B86459C1E7C2CAD00A84029 /* ProxyInterfacesViewCtrl.swift */; };
|
||||||
9B938D991E864B38005F5636 /* menu_g_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B938D931E864B38005F5636 /* menu_g_icon.png */; };
|
9B938D991E864B38005F5636 /* menu_g_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B938D931E864B38005F5636 /* menu_g_icon.png */; };
|
||||||
9B938D9A1E864B38005F5636 /* menu_g_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B938D941E864B38005F5636 /* menu_g_icon@2x.png */; };
|
9B938D9A1E864B38005F5636 /* menu_g_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B938D941E864B38005F5636 /* menu_g_icon@2x.png */; };
|
||||||
@ -195,12 +196,14 @@
|
|||||||
9B5832021E741F8D009D5B7D /* command-512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "command-512.png"; sourceTree = "<group>"; };
|
9B5832021E741F8D009D5B7D /* command-512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "command-512.png"; sourceTree = "<group>"; };
|
||||||
9B5832061E7421B2009D5B7D /* virtual-server-icon-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "virtual-server-icon-3.png"; sourceTree = "<group>"; };
|
9B5832061E7421B2009D5B7D /* virtual-server-icon-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "virtual-server-icon-3.png"; sourceTree = "<group>"; };
|
||||||
9B58320A1E7422DB009D5B7D /* http.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = http.png; sourceTree = "<group>"; };
|
9B58320A1E7422DB009D5B7D /* http.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = http.png; sourceTree = "<group>"; };
|
||||||
9B5832101E742632009D5B7D /* kcptun_1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = kcptun_1.png; sourceTree = "<group>"; };
|
|
||||||
9B5AA09F209C100C00E8B659 /* libsodium.23.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libsodium.23.dylib; sourceTree = "<group>"; };
|
9B5AA09F209C100C00E8B659 /* libsodium.23.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libsodium.23.dylib; sourceTree = "<group>"; };
|
||||||
9B5AA0A2209C103900E8B659 /* libcares.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libcares.2.dylib; sourceTree = "<group>"; };
|
9B5AA0A2209C103900E8B659 /* libcares.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libcares.2.dylib; sourceTree = "<group>"; };
|
||||||
9B5AA0AB209C43C200E8B659 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
|
9B5AA0AB209C43C200E8B659 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
|
||||||
9B6BF9531E27B2570061B9A7 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
|
9B6BF9531E27B2570061B9A7 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
|
||||||
9B7297E5214D68F800FD24AA /* libmbedcrypto.2.12.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libmbedcrypto.2.12.0.dylib; sourceTree = "<group>"; };
|
9B7297E5214D68F800FD24AA /* libmbedcrypto.2.12.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libmbedcrypto.2.12.0.dylib; sourceTree = "<group>"; };
|
||||||
|
9B7297E8214D7C6B00FD24AA /* ShareServerProfilesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareServerProfilesWindowController.swift; sourceTree = "<group>"; };
|
||||||
|
9B7297ED214DA88A00FD24AA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ShareServerProfilesWindowController.xib; sourceTree = "<group>"; };
|
||||||
|
9B7297F0214DA89000FD24AA /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/ShareServerProfilesWindowController.strings"; sourceTree = "<group>"; };
|
||||||
9B86459C1E7C2CAD00A84029 /* ProxyInterfacesViewCtrl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxyInterfacesViewCtrl.swift; sourceTree = "<group>"; };
|
9B86459C1E7C2CAD00A84029 /* ProxyInterfacesViewCtrl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxyInterfacesViewCtrl.swift; sourceTree = "<group>"; };
|
||||||
9B938D931E864B38005F5636 /* menu_g_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_g_icon.png; sourceTree = "<group>"; };
|
9B938D931E864B38005F5636 /* menu_g_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_g_icon.png; sourceTree = "<group>"; };
|
||||||
9B938D941E864B38005F5636 /* menu_g_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu_g_icon@2x.png"; sourceTree = "<group>"; };
|
9B938D941E864B38005F5636 /* menu_g_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu_g_icon@2x.png"; sourceTree = "<group>"; };
|
||||||
@ -308,7 +311,6 @@
|
|||||||
9B938D961E864B38005F5636 /* menu_m_icon@2x.png */,
|
9B938D961E864B38005F5636 /* menu_m_icon@2x.png */,
|
||||||
9B938D971E864B38005F5636 /* menu_p_icon.png */,
|
9B938D971E864B38005F5636 /* menu_p_icon.png */,
|
||||||
9B938D981E864B38005F5636 /* menu_p_icon@2x.png */,
|
9B938D981E864B38005F5636 /* menu_p_icon@2x.png */,
|
||||||
9B5832101E742632009D5B7D /* kcptun_1.png */,
|
|
||||||
9B58320A1E7422DB009D5B7D /* http.png */,
|
9B58320A1E7422DB009D5B7D /* http.png */,
|
||||||
9B5832061E7421B2009D5B7D /* virtual-server-icon-3.png */,
|
9B5832061E7421B2009D5B7D /* virtual-server-icon-3.png */,
|
||||||
9B5832021E741F8D009D5B7D /* command-512.png */,
|
9B5832021E741F8D009D5B7D /* command-512.png */,
|
||||||
@ -411,6 +413,8 @@
|
|||||||
9B86459C1E7C2CAD00A84029 /* ProxyInterfacesViewCtrl.swift */,
|
9B86459C1E7C2CAD00A84029 /* ProxyInterfacesViewCtrl.swift */,
|
||||||
9B3546701E802B1200B510B4 /* ToastWindowController.swift */,
|
9B3546701E802B1200B510B4 /* ToastWindowController.swift */,
|
||||||
9B3546711E802B1200B510B4 /* ToastWindowController.xib */,
|
9B3546711E802B1200B510B4 /* ToastWindowController.xib */,
|
||||||
|
9B7297E8214D7C6B00FD24AA /* ShareServerProfilesWindowController.swift */,
|
||||||
|
9B7297EE214DA88A00FD24AA /* ShareServerProfilesWindowController.xib */,
|
||||||
);
|
);
|
||||||
name = UI;
|
name = UI;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -622,7 +626,6 @@
|
|||||||
C6D429971DA75988002A5711 /* stop_privoxy.sh in Resources */,
|
C6D429971DA75988002A5711 /* stop_privoxy.sh in Resources */,
|
||||||
C8E42A6E1D4F2CAF0074C7EA /* UserRulesController.xib in Resources */,
|
C8E42A6E1D4F2CAF0074C7EA /* UserRulesController.xib in Resources */,
|
||||||
9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */,
|
9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */,
|
||||||
9B5832111E742632009D5B7D /* kcptun_1.png in Resources */,
|
|
||||||
9B16E59A1F99FD0700E54DC5 /* icons8-Eye Filled-50.png in Resources */,
|
9B16E59A1F99FD0700E54DC5 /* icons8-Eye Filled-50.png in Resources */,
|
||||||
9B938D9C1E864B38005F5636 /* menu_m_icon@2x.png in Resources */,
|
9B938D9C1E864B38005F5636 /* menu_m_icon@2x.png in Resources */,
|
||||||
9B3546731E802B1200B510B4 /* ToastWindowController.xib in Resources */,
|
9B3546731E802B1200B510B4 /* ToastWindowController.xib in Resources */,
|
||||||
@ -638,6 +641,7 @@
|
|||||||
1C82DBA81FA96C7500B32551 /* obfs-local in Resources */,
|
1C82DBA81FA96C7500B32551 /* obfs-local in Resources */,
|
||||||
9B938D9D1E864B38005F5636 /* menu_p_icon.png in Resources */,
|
9B938D9D1E864B38005F5636 /* menu_p_icon.png in Resources */,
|
||||||
9B938D9B1E864B38005F5636 /* menu_m_icon.png in Resources */,
|
9B938D9B1E864B38005F5636 /* menu_m_icon.png in Resources */,
|
||||||
|
9B7297EC214DA88A00FD24AA /* ShareServerProfilesWindowController.xib in Resources */,
|
||||||
9B3FFF271D0898EB0019A709 /* gfwlist.txt in Resources */,
|
9B3FFF271D0898EB0019A709 /* gfwlist.txt in Resources */,
|
||||||
C6D429931DA75988002A5711 /* install_privoxy.sh in Resources */,
|
C6D429931DA75988002A5711 /* install_privoxy.sh in Resources */,
|
||||||
9B58320B1E7422DB009D5B7D /* http.png in Resources */,
|
9B58320B1E7422DB009D5B7D /* http.png in Resources */,
|
||||||
@ -818,6 +822,7 @@
|
|||||||
9B5831F61E7302F8009D5B7D /* ShortcutsController.m in Sources */,
|
9B5831F61E7302F8009D5B7D /* ShortcutsController.m in Sources */,
|
||||||
9BB706A71D1B982300551F0E /* SWBApplication.m in Sources */,
|
9BB706A71D1B982300551F0E /* SWBApplication.m in Sources */,
|
||||||
9B3FFF1E1D0732660019A709 /* Utils.m in Sources */,
|
9B3FFF1E1D0732660019A709 /* Utils.m in Sources */,
|
||||||
|
9B7297EA214D7C6B00FD24AA /* ShareServerProfilesWindowController.swift in Sources */,
|
||||||
9B3FFF321D08CEE40019A709 /* SWBQRCodeWindowController.m in Sources */,
|
9B3FFF321D08CEE40019A709 /* SWBQRCodeWindowController.m in Sources */,
|
||||||
9B3FFF211D08826E0019A709 /* PACUtils.swift in Sources */,
|
9B3FFF211D08826E0019A709 /* PACUtils.swift in Sources */,
|
||||||
9B3FFF141D0705810019A709 /* Notifications.swift in Sources */,
|
9B3FFF141D0705810019A709 /* Notifications.swift in Sources */,
|
||||||
@ -894,6 +899,15 @@
|
|||||||
name = PreferencesWindowController.xib;
|
name = PreferencesWindowController.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
9B7297EE214DA88A00FD24AA /* ShareServerProfilesWindowController.xib */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
9B7297ED214DA88A00FD24AA /* Base */,
|
||||||
|
9B7297F0214DA89000FD24AA /* zh-Hans */,
|
||||||
|
);
|
||||||
|
name = ShareServerProfilesWindowController.xib;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
9BAFE2E41E83ED7F00F71CCE /* PreferencesWinController.xib */ = {
|
9BAFE2E41E83ED7F00F71CCE /* PreferencesWinController.xib */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -14,6 +14,7 @@ import RxSwift
|
|||||||
@NSApplicationMain
|
@NSApplicationMain
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {
|
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {
|
||||||
|
|
||||||
|
var shareWinCtrl: ShareServerProfilesWindowController!
|
||||||
var qrcodeWinCtrl: SWBQRCodeWindowController!
|
var qrcodeWinCtrl: SWBQRCodeWindowController!
|
||||||
var preferencesWinCtrl: PreferencesWindowController!
|
var preferencesWinCtrl: PreferencesWindowController!
|
||||||
var editUserRulesWinCtrl: UserRulesController!
|
var editUserRulesWinCtrl: UserRulesController!
|
||||||
@ -279,9 +280,50 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction func showShareServerProfiles(_ sender: NSMenuItem) {
|
||||||
|
if shareWinCtrl != nil {
|
||||||
|
shareWinCtrl.close()
|
||||||
|
}
|
||||||
|
shareWinCtrl = ShareServerProfilesWindowController(windowNibName: NSNib.Name(rawValue: "ShareServerProfilesWindowController"))
|
||||||
|
shareWinCtrl.showWindow(self)
|
||||||
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
|
shareWinCtrl.window?.makeKeyAndOrderFront(nil)
|
||||||
|
}
|
||||||
|
|
||||||
@IBAction func scanQRCodeFromScreen(_ sender: NSMenuItem) {
|
@IBAction func scanQRCodeFromScreen(_ sender: NSMenuItem) {
|
||||||
ScanQRCodeOnScreen()
|
ScanQRCodeOnScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction func importProfileURLFromPasteboard(_ sender: NSMenuItem) {
|
||||||
|
let pb = NSPasteboard.general
|
||||||
|
if #available(OSX 10.13, *) {
|
||||||
|
if let text = pb.string(forType: NSPasteboard.PasteboardType.URL) {
|
||||||
|
if let url = URL(string: text) {
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: Notification.Name(rawValue: "NOTIFY_FOUND_SS_URL"), object: nil
|
||||||
|
, userInfo: [
|
||||||
|
"urls": [url],
|
||||||
|
"source": "pasteboard",
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let text = pb.string(forType: NSPasteboard.PasteboardType.string) {
|
||||||
|
var urls = text.split(separator: "\n")
|
||||||
|
.map { String($0).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) }
|
||||||
|
.map { URL(string: $0) }
|
||||||
|
.filter { $0 != nil }
|
||||||
|
.map { $0! }
|
||||||
|
urls = urls.filter { $0.scheme == "ss" }
|
||||||
|
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: Notification.Name(rawValue: "NOTIFY_FOUND_SS_URL"), object: nil
|
||||||
|
, userInfo: [
|
||||||
|
"urls": urls,
|
||||||
|
"source": "pasteboard",
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@IBAction func selectPACMode(_ sender: NSMenuItem) {
|
@IBAction func selectPACMode(_ sender: NSMenuItem) {
|
||||||
let defaults = UserDefaults.standard
|
let defaults = UserDefaults.standard
|
||||||
@ -528,29 +570,30 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
|||||||
let urls: [URL] = userInfo["urls"] as! [URL]
|
let urls: [URL] = userInfo["urls"] as! [URL]
|
||||||
|
|
||||||
let mgr = ServerProfileManager.instance
|
let mgr = ServerProfileManager.instance
|
||||||
var isChanged = false
|
var addCount = 0
|
||||||
|
|
||||||
|
var subtitle: String = ""
|
||||||
|
if userInfo["source"] as! String == "qrcode" {
|
||||||
|
subtitle = "By scan QR Code".localized
|
||||||
|
} else if userInfo["source"] as! String == "url" {
|
||||||
|
subtitle = "By handle SS URL".localized
|
||||||
|
} else if userInfo["source"] as! String == "pasteboard" {
|
||||||
|
subtitle = "By import from pasteboard".localized
|
||||||
|
}
|
||||||
|
|
||||||
for url in urls {
|
for url in urls {
|
||||||
if let profile = ServerProfile(url: url) {
|
if let profile = ServerProfile(url: url) {
|
||||||
mgr.profiles.append(profile)
|
mgr.profiles.append(profile)
|
||||||
isChanged = true
|
addCount = addCount + 1
|
||||||
|
|
||||||
var subtitle: String = ""
|
|
||||||
if userInfo["source"] as! String == "qrcode" {
|
|
||||||
subtitle = "By scan QR Code".localized
|
|
||||||
} else if userInfo["source"] as! String == "url" {
|
|
||||||
subtitle = "By Handle SS URL".localized
|
|
||||||
}
|
|
||||||
|
|
||||||
sendNotify("Add Shadowsocks Server Profile".localized, subtitle, "Host: \(profile.serverHost)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isChanged {
|
if addCount > 0 {
|
||||||
|
sendNotify("Add \(addCount) Shadowsocks Server Profile".localized, subtitle, "")
|
||||||
mgr.save()
|
mgr.save()
|
||||||
self.updateServersMenu()
|
self.updateServersMenu()
|
||||||
} else {
|
} else {
|
||||||
sendNotify("Not found valid qrcode of shadowsocks profile.", "", "")
|
sendNotify("", "", "Not found valid qrcode or url of shadowsocks profile".localized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
* ./AppDelegate.swift
|
* ./AppDelegate.swift
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"Add Shadowsocks Server Profile" = "Add Shadowsocks Server Profile";
|
"Add \(addCount) Shadowsocks Server Profile" = "Add \(addCount) Shadowsocks Server Profile";
|
||||||
|
|
||||||
|
"Not found valid qrcode or url of shadowsocks profile" = "Not found valid qrcode or url of shadowsocks profile";
|
||||||
|
|
||||||
"By scan QR Code" = "By scan QR Code";
|
"By scan QR Code" = "By scan QR Code";
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
<outlet property="serverProfilesBeginSeparatorMenuItem" destination="4iN-w2-but" id="Jyu-48-AzD"/>
|
<outlet property="serverProfilesBeginSeparatorMenuItem" destination="4iN-w2-but" id="Jyu-48-AzD"/>
|
||||||
<outlet property="serverProfilesEndSeparatorMenuItem" destination="3cf-dF-7dx" id="eyc-6W-nWV"/>
|
<outlet property="serverProfilesEndSeparatorMenuItem" destination="3cf-dF-7dx" id="eyc-6W-nWV"/>
|
||||||
<outlet property="serversMenuItem" destination="u5M-hQ-VSc" id="8gp-SY-Y4U"/>
|
<outlet property="serversMenuItem" destination="u5M-hQ-VSc" id="8gp-SY-Y4U"/>
|
||||||
<outlet property="showQRCodeMenuItem" destination="R6A-96-Zcb" id="XHz-pz-nCz"/>
|
|
||||||
<outlet property="statusMenu" destination="Hob-KD-bx9" id="clA-ZW-0pT"/>
|
<outlet property="statusMenu" destination="Hob-KD-bx9" id="clA-ZW-0pT"/>
|
||||||
<outlet property="toggleRunningMenuItem" destination="GSu-Tf-StS" id="XHw-pU-nCa"/>
|
<outlet property="toggleRunningMenuItem" destination="GSu-Tf-StS" id="XHw-pU-nCa"/>
|
||||||
</connections>
|
</connections>
|
||||||
@ -72,21 +71,27 @@
|
|||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="4iN-w2-but"/>
|
<menuItem isSeparatorItem="YES" id="4iN-w2-but"/>
|
||||||
<menuItem isSeparatorItem="YES" id="3cf-dF-7dx"/>
|
<menuItem isSeparatorItem="YES" id="3cf-dF-7dx"/>
|
||||||
<menuItem title="Scan QR Code From Screen ..." id="Qe6-bF-paT">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="scanQRCodeFromScreen:" target="Voe-Tx-rLC" id="zQZ-IT-H4a"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Show QR Code For Current Server..." id="R6A-96-Zcb">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="showQRCodeForCurrentServer:" target="Voe-Tx-rLC" id="t45-Zk-cai"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
<menuItem title="Scan QR Code From Screen" id="Qe6-bF-paT">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="scanQRCodeFromScreen:" target="Voe-Tx-rLC" id="zQZ-IT-H4a"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Import Server URLs From Pasteboard" id="7Eq-XD-K5c">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="importProfileURLFromPasteboard:" target="Voe-Tx-rLC" id="RwL-Ms-BaC"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Share Server Profiles..." id="r5z-RB-LIZ">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="showShareServerProfiles:" target="Voe-Tx-rLC" id="3Qv-n1-5h1"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="vwY-hQ-ZIz"/>
|
<menuItem isSeparatorItem="YES" id="vwY-hQ-ZIz"/>
|
||||||
<menuItem title="Preferences..." keyEquivalent="," id="4CS-qD-zW5">
|
<menuItem title="Preferences..." keyEquivalent="," id="4CS-qD-zW5">
|
||||||
<connections>
|
<connections>
|
||||||
|
@ -29,20 +29,21 @@
|
|||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<window title="Server Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
<window title="Server Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||||
<rect key="contentRect" x="423" y="365" width="590" height="564"/>
|
<rect key="contentRect" x="423" y="365" width="557" height="301"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||||
<view key="contentView" id="se5-gp-TjO">
|
<view key="contentView" id="se5-gp-TjO">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="590" height="564"/>
|
<rect key="frame" x="0.0" y="0.0" width="557" height="301"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<scrollView focusRingType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u4U-Ju-FJV">
|
<scrollView focusRingType="none" fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u4U-Ju-FJV">
|
||||||
<rect key="frame" x="20" y="80" width="233" height="464"/>
|
<rect key="frame" x="20" y="80" width="200" height="201"/>
|
||||||
<clipView key="contentView" focusRingType="none" id="1oC-7s-16v">
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<rect key="frame" x="1" y="1" width="231" height="462"/>
|
<clipView key="contentView" focusRingType="none" ambiguous="YES" id="1oC-7s-16v">
|
||||||
|
<rect key="frame" x="1" y="1" width="198" height="199"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" id="r91-ho-Lum">
|
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" id="r91-ho-Lum">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="231" height="462"/>
|
<rect key="frame" x="0.0" y="0.0" width="198" height="199"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<size key="intercellSpacing" width="3" height="2"/>
|
<size key="intercellSpacing" width="3" height="2"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -88,97 +89,106 @@
|
|||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
<box boxType="custom" borderType="none" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="oZ5-85-pwY">
|
<box fixedFrame="YES" boxType="custom" borderType="none" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="oZ5-85-pwY">
|
||||||
<rect key="frame" x="273" y="61" width="297" height="483"/>
|
<rect key="frame" x="240" y="61" width="297" height="220"/>
|
||||||
<view key="contentView" id="a3z-VL-3xV">
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<rect key="frame" x="0.0" y="0.0" width="297" height="483"/>
|
<view key="contentView" ambiguous="YES" id="a3z-VL-3xV">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="297" height="220"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HPg-NP-kjP">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HPg-NP-kjP">
|
||||||
<rect key="frame" x="46" y="444" width="58" height="17"/>
|
<rect key="frame" x="46" y="181" width="58" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Address:" id="yHs-XE-XEB">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Address:" id="yHs-XE-XEB">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Otb-CO-KUH">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Otb-CO-KUH">
|
||||||
<rect key="frame" x="212" y="446" width="9" height="17"/>
|
<rect key="frame" x="212" y="183" width="9" height="17"/>
|
||||||
<constraints>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<constraint firstAttribute="width" constant="5" id="JAU-I8-jVc"/>
|
|
||||||
</constraints>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title=":" id="Ibr-Gs-5Js">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title=":" id="Ibr-Gs-5Js">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<comboBox verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ef4-8J-eFn">
|
<comboBox verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ef4-8J-eFn">
|
||||||
<rect key="frame" x="110" y="409" width="166" height="26"/>
|
<rect key="frame" x="110" y="146" width="166" height="26"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="11" id="5Qb-ey-uS5">
|
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="11" id="5Qb-ey-uS5">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</comboBoxCell>
|
</comboBoxCell>
|
||||||
</comboBox>
|
</comboBox>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kft-TG-O5S">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kft-TG-O5S">
|
||||||
<rect key="frame" x="30" y="414" width="74" height="17"/>
|
<rect key="frame" x="30" y="151" width="74" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Encryption:" id="mOh-nD-7EX">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Encryption:" id="mOh-nD-7EX">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="q3C-S0-iNn">
|
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="q3C-S0-iNn">
|
||||||
<rect key="frame" x="110" y="287" width="170" height="22"/>
|
<rect key="frame" x="110" y="24" width="170" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="oxu-qq-MGC">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="oxu-qq-MGC">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5eh-s9-YH8">
|
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5eh-s9-YH8">
|
||||||
<rect key="frame" x="110" y="319" width="170" height="22"/>
|
<rect key="frame" x="110" y="56" width="170" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="dtO-2M-4yX">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="dtO-2M-4yX">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0PP-Ng-z0v">
|
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0PP-Ng-z0v">
|
||||||
<rect key="frame" x="110" y="351" width="135" height="22"/>
|
<rect key="frame" x="110" y="88" width="135" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="IGs-KE-ySP">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="IGs-KE-ySP">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Baj-Yh-kmj">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Baj-Yh-kmj">
|
||||||
<rect key="frame" x="43" y="290" width="61" height="17"/>
|
<rect key="frame" x="43" y="27" width="61" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Remarks:" id="MiN-VE-FtC">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Remarks:" id="MiN-VE-FtC">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DGz-Sq-t0c">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DGz-Sq-t0c">
|
||||||
<rect key="frame" x="58" y="354" width="46" height="17"/>
|
<rect key="frame" x="58" y="91" width="46" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Plugin:" id="gDt-yZ-Mqs">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Plugin:" id="gDt-yZ-Mqs">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" ambiguous="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="R4F-j7-GkK">
|
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="R4F-j7-GkK">
|
||||||
<rect key="frame" x="110" y="441" width="96" height="22"/>
|
<rect key="frame" x="110" y="178" width="96" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="IP" drawsBackground="YES" id="MWO-hQ-nMt">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="IP" drawsBackground="YES" id="MWO-hQ-nMt">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" ambiguous="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lng-AE-g0J">
|
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lng-AE-g0J">
|
||||||
<rect key="frame" x="223" y="441" width="50" height="22"/>
|
<rect key="frame" x="223" y="178" width="50" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Port" drawsBackground="YES" id="e1F-jd-e0J">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Port" drawsBackground="YES" id="e1F-jd-e0J">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -191,17 +201,19 @@
|
|||||||
<outlet property="formatter" destination="QZc-kt-D7Z" id="ZB9-Of-Xi9"/>
|
<outlet property="formatter" destination="QZc-kt-D7Z" id="ZB9-Of-Xi9"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<tabView focusRingType="none" drawsBackground="NO" type="noTabsNoBorder" initialItem="aRD-sh-uEl" translatesAutoresizingMaskIntoConstraints="NO" id="DHz-Hx-kZ5">
|
<tabView focusRingType="none" fixedFrame="YES" drawsBackground="NO" type="noTabsNoBorder" initialItem="aRD-sh-uEl" translatesAutoresizingMaskIntoConstraints="NO" id="DHz-Hx-kZ5">
|
||||||
<rect key="frame" x="110" y="383" width="135" height="22"/>
|
<rect key="frame" x="110" y="120" width="135" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<tabViewItems>
|
<tabViewItems>
|
||||||
<tabViewItem label="Secure" identifier="secure" id="aRD-sh-uEl">
|
<tabViewItem label="Secure" identifier="secure" id="aRD-sh-uEl">
|
||||||
<view key="view" id="rXs-ye-nly">
|
<view key="view" ambiguous="YES" id="rXs-ye-nly">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="135" height="22"/>
|
<rect key="frame" x="0.0" y="0.0" width="135" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<secureTextField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZXA-oi-Zv3">
|
<secureTextField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZXA-oi-Zv3">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="135" height="22"/>
|
<rect key="frame" x="0.0" y="0.0" width="135" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="zuN-Jd-LeS">
|
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="zuN-Jd-LeS">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -212,11 +224,6 @@
|
|||||||
</secureTextFieldCell>
|
</secureTextFieldCell>
|
||||||
</secureTextField>
|
</secureTextField>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="ZXA-oi-Zv3" secondAttribute="trailing" id="N5U-Eb-r6N"/>
|
|
||||||
<constraint firstItem="ZXA-oi-Zv3" firstAttribute="leading" secondItem="rXs-ye-nly" secondAttribute="leading" id="kHp-7I-hYq"/>
|
|
||||||
<constraint firstItem="ZXA-oi-Zv3" firstAttribute="top" secondItem="rXs-ye-nly" secondAttribute="top" id="oRQ-oR-A5o"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="Insecure" identifier="insecure" id="SYv-Tn-tur">
|
<tabViewItem label="Insecure" identifier="insecure" id="SYv-Tn-tur">
|
||||||
@ -224,8 +231,9 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="135" height="22"/>
|
<rect key="frame" x="0.0" y="0.0" width="135" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3Ad-X4-DBi">
|
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3Ad-X4-DBi">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="135" height="22"/>
|
<rect key="frame" x="0.0" y="0.0" width="135" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="DNt-0X-3Z0">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="DNt-0X-3Z0">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -233,20 +241,13 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="3Ad-X4-DBi" firstAttribute="top" secondItem="Z6k-mP-BgX" secondAttribute="top" id="GRU-7C-6XV"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="3Ad-X4-DBi" secondAttribute="trailing" id="cRR-i4-0ty"/>
|
|
||||||
<constraint firstItem="3Ad-X4-DBi" firstAttribute="leading" secondItem="Z6k-mP-BgX" secondAttribute="leading" id="s6R-BF-mOG"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
</tabViewItems>
|
</tabViewItems>
|
||||||
</tabView>
|
</tabView>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jDI-cn-wYa">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jDI-cn-wYa">
|
||||||
<rect key="frame" x="254" y="381" width="26" height="25"/>
|
<rect key="frame" x="254" y="118" width="26" height="25"/>
|
||||||
<constraints>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<constraint firstAttribute="width" constant="26" id="vGB-iL-nWP"/>
|
|
||||||
</constraints>
|
|
||||||
<buttonCell key="cell" type="squareTextured" bezelStyle="texturedSquare" image="icons8-Blind Filled-50" imagePosition="only" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="axesIndependently" inset="2" id="8Bw-DM-zYg">
|
<buttonCell key="cell" type="squareTextured" bezelStyle="texturedSquare" image="icons8-Blind Filled-50" imagePosition="only" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="axesIndependently" inset="2" id="8Bw-DM-zYg">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -255,24 +256,27 @@
|
|||||||
<action selector="togglePasswordVisible:" target="-2" id="3kh-Pz-mr0"/>
|
<action selector="togglePasswordVisible:" target="-2" id="3kh-Pz-mr0"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qfe-Ql-iCO">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qfe-Ql-iCO">
|
||||||
<rect key="frame" x="38" y="385" width="66" height="17"/>
|
<rect key="frame" x="38" y="122" width="66" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Password:" id="kil-xC-HPD">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Password:" id="kil-xC-HPD">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4LD-CD-u7b">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4LD-CD-u7b">
|
||||||
<rect key="frame" x="26" y="321" width="78" height="17"/>
|
<rect key="frame" x="26" y="58" width="78" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Plugin Opts:" id="orT-7j-dxE">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Plugin Opts:" id="orT-7j-dxE">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jch-rI-Swc">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jch-rI-Swc">
|
||||||
<rect key="frame" x="254" y="349" width="25" height="25"/>
|
<rect key="frame" x="254" y="86" width="25" height="25"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="help" bezelStyle="helpButton" imagePosition="left" borderStyle="border" inset="2" id="IF1-Fy-5la">
|
<buttonCell key="cell" type="help" bezelStyle="helpButton" imagePosition="left" borderStyle="border" inset="2" id="IF1-Fy-5la">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -282,62 +286,19 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="Baj-Yh-kmj" firstAttribute="baseline" secondItem="q3C-S0-iNn" secondAttribute="baseline" id="0Fs-Yi-WBo"/>
|
|
||||||
<constraint firstItem="lng-AE-g0J" firstAttribute="leading" secondItem="Otb-CO-KUH" secondAttribute="trailing" constant="4" id="0bx-FE-Nqz"/>
|
|
||||||
<constraint firstItem="R4F-j7-GkK" firstAttribute="baseline" secondItem="lng-AE-g0J" secondAttribute="baseline" id="0dG-a6-exG"/>
|
|
||||||
<constraint firstItem="5eh-s9-YH8" firstAttribute="top" secondItem="0PP-Ng-z0v" secondAttribute="bottom" constant="10" symbolic="YES" id="1aa-nq-sFq"/>
|
|
||||||
<constraint firstItem="DHz-Hx-kZ5" firstAttribute="leading" secondItem="Qfe-Ql-iCO" secondAttribute="trailing" constant="8" symbolic="YES" id="1bR-S3-Tdq"/>
|
|
||||||
<constraint firstItem="ef4-8J-eFn" firstAttribute="top" secondItem="R4F-j7-GkK" secondAttribute="bottom" constant="8" symbolic="YES" id="41P-Ix-it2"/>
|
|
||||||
<constraint firstItem="jDI-cn-wYa" firstAttribute="trailing" secondItem="0PP-Ng-z0v" secondAttribute="trailing" constant="35" id="5DS-4j-Cr9"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="lng-AE-g0J" secondAttribute="trailing" constant="24" id="6W3-BA-gYo"/>
|
|
||||||
<constraint firstItem="0PP-Ng-z0v" firstAttribute="centerY" secondItem="DGz-Sq-t0c" secondAttribute="centerY" id="99Q-Zk-mdj"/>
|
|
||||||
<constraint firstItem="R4F-j7-GkK" firstAttribute="top" secondItem="a3z-VL-3xV" secondAttribute="top" constant="20" symbolic="YES" id="Dkz-UA-ymg"/>
|
|
||||||
<constraint firstItem="0PP-Ng-z0v" firstAttribute="top" secondItem="DHz-Hx-kZ5" secondAttribute="bottom" constant="10" id="Fwl-Mu-bKH"/>
|
|
||||||
<constraint firstItem="DHz-Hx-kZ5" firstAttribute="top" secondItem="ef4-8J-eFn" secondAttribute="bottom" constant="8" symbolic="YES" id="I7k-9o-SLi"/>
|
|
||||||
<constraint firstItem="jDI-cn-wYa" firstAttribute="leading" secondItem="DHz-Hx-kZ5" secondAttribute="trailing" constant="9" id="IMV-t5-Set"/>
|
|
||||||
<constraint firstItem="jDI-cn-wYa" firstAttribute="trailing" secondItem="q3C-S0-iNn" secondAttribute="trailing" id="Idl-zd-MSU"/>
|
|
||||||
<constraint firstItem="5eh-s9-YH8" firstAttribute="centerY" secondItem="4LD-CD-u7b" secondAttribute="centerY" id="Ik2-zM-uly"/>
|
|
||||||
<constraint firstItem="DHz-Hx-kZ5" firstAttribute="leading" secondItem="q3C-S0-iNn" secondAttribute="leading" id="JBi-Dy-gPS"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="jDI-cn-wYa" secondAttribute="trailing" constant="17" id="JSl-uN-iMh"/>
|
|
||||||
<constraint firstItem="ef4-8J-eFn" firstAttribute="leading" secondItem="DHz-Hx-kZ5" secondAttribute="leading" id="L85-np-Xpn"/>
|
|
||||||
<constraint firstItem="q3C-S0-iNn" firstAttribute="leading" secondItem="Baj-Yh-kmj" secondAttribute="trailing" constant="8" symbolic="YES" id="LTy-e7-h27"/>
|
|
||||||
<constraint firstItem="q3C-S0-iNn" firstAttribute="top" secondItem="5eh-s9-YH8" secondAttribute="bottom" constant="10" symbolic="YES" id="ORc-LV-dNZ"/>
|
|
||||||
<constraint firstItem="DHz-Hx-kZ5" firstAttribute="bottom" secondItem="jDI-cn-wYa" secondAttribute="bottom" id="RM1-vq-zAm"/>
|
|
||||||
<constraint firstItem="Kft-TG-O5S" firstAttribute="centerY" secondItem="ef4-8J-eFn" secondAttribute="centerY" id="RYD-o2-vjB"/>
|
|
||||||
<constraint firstItem="Kft-TG-O5S" firstAttribute="leading" secondItem="a3z-VL-3xV" secondAttribute="leading" constant="32" id="TsS-51-KLG"/>
|
|
||||||
<constraint firstItem="ef4-8J-eFn" firstAttribute="leading" secondItem="Kft-TG-O5S" secondAttribute="trailing" constant="8" symbolic="YES" id="VGj-2V-kmi"/>
|
|
||||||
<constraint firstItem="Otb-CO-KUH" firstAttribute="leading" secondItem="R4F-j7-GkK" secondAttribute="trailing" constant="8" symbolic="YES" id="dL8-po-Zhh"/>
|
|
||||||
<constraint firstItem="jch-rI-Swc" firstAttribute="centerX" secondItem="jDI-cn-wYa" secondAttribute="centerX" id="eTA-qv-ID2"/>
|
|
||||||
<constraint firstItem="HPg-NP-kjP" firstAttribute="baseline" secondItem="R4F-j7-GkK" secondAttribute="baseline" id="fb7-sB-eHL"/>
|
|
||||||
<constraint firstItem="DHz-Hx-kZ5" firstAttribute="top" secondItem="jDI-cn-wYa" secondAttribute="top" id="fbb-RF-Wvf"/>
|
|
||||||
<constraint firstItem="Qfe-Ql-iCO" firstAttribute="leading" secondItem="a3z-VL-3xV" secondAttribute="leading" constant="40" id="fw1-Zg-LaZ"/>
|
|
||||||
<constraint firstItem="lng-AE-g0J" firstAttribute="trailing" secondItem="ef4-8J-eFn" secondAttribute="trailing" id="gxe-uL-y5w"/>
|
|
||||||
<constraint firstItem="R4F-j7-GkK" firstAttribute="leading" secondItem="HPg-NP-kjP" secondAttribute="trailing" constant="8" symbolic="YES" id="hKJ-ZW-uLY"/>
|
|
||||||
<constraint firstItem="jDI-cn-wYa" firstAttribute="trailing" secondItem="5eh-s9-YH8" secondAttribute="trailing" id="jLS-U1-IJa"/>
|
|
||||||
<constraint firstItem="0PP-Ng-z0v" firstAttribute="leading" secondItem="DHz-Hx-kZ5" secondAttribute="leading" id="kEJ-EJ-v0T"/>
|
|
||||||
<constraint firstItem="Otb-CO-KUH" firstAttribute="top" secondItem="lng-AE-g0J" secondAttribute="top" id="kLj-6Z-ZDw"/>
|
|
||||||
<constraint firstItem="5eh-s9-YH8" firstAttribute="leading" secondItem="DHz-Hx-kZ5" secondAttribute="leading" id="kXe-DX-Fsi"/>
|
|
||||||
<constraint firstItem="0PP-Ng-z0v" firstAttribute="leading" secondItem="DGz-Sq-t0c" secondAttribute="trailing" constant="8" symbolic="YES" id="mcp-te-11z"/>
|
|
||||||
<constraint firstItem="R4F-j7-GkK" firstAttribute="leading" secondItem="ef4-8J-eFn" secondAttribute="leading" id="opP-Lo-SO0"/>
|
|
||||||
<constraint firstItem="5eh-s9-YH8" firstAttribute="leading" secondItem="4LD-CD-u7b" secondAttribute="trailing" constant="8" symbolic="YES" id="uFv-U2-g2d"/>
|
|
||||||
<constraint firstItem="Qfe-Ql-iCO" firstAttribute="centerY" secondItem="DHz-Hx-kZ5" secondAttribute="centerY" id="wKU-B5-A3m"/>
|
|
||||||
<constraint firstItem="jch-rI-Swc" firstAttribute="top" secondItem="0PP-Ng-z0v" secondAttribute="top" id="zzw-ge-6mH"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</box>
|
</box>
|
||||||
<box boxType="custom" borderType="none" title="Box" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Gqv-5O-Wwf">
|
<box fixedFrame="YES" boxType="custom" borderType="none" title="Box" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Gqv-5O-Wwf">
|
||||||
<rect key="frame" x="20" y="61" width="233" height="19"/>
|
<rect key="frame" x="20" y="61" width="200" height="19"/>
|
||||||
<view key="contentView" id="MbP-FS-YEs">
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<rect key="frame" x="0.0" y="0.0" width="233" height="19"/>
|
<view key="contentView" ambiguous="YES" id="MbP-FS-YEs">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="200" height="19"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4ig-lF-m2R">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4ig-lF-m2R">
|
||||||
<rect key="frame" x="0.0" y="-1" width="22" height="21"/>
|
<rect key="frame" x="0.0" y="-1" width="22" height="21"/>
|
||||||
<constraints>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<constraint firstAttribute="width" constant="22" id="sgm-c9-nQI"/>
|
|
||||||
</constraints>
|
|
||||||
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSAddTemplate" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="VkE-bG-mJb">
|
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSAddTemplate" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="VkE-bG-mJb">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -346,11 +307,9 @@
|
|||||||
<action selector="addProfile:" target="-2" id="NEh-IP-KO8"/>
|
<action selector="addProfile:" target="-2" id="NEh-IP-KO8"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3ei-2f-kHB">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3ei-2f-kHB">
|
||||||
<rect key="frame" x="20" y="-1" width="22" height="21"/>
|
<rect key="frame" x="20" y="-1" width="22" height="21"/>
|
||||||
<constraints>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<constraint firstAttribute="width" constant="22" id="LYH-ae-nU6"/>
|
|
||||||
</constraints>
|
|
||||||
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSRemoveTemplate" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Nu6-Aw-ihE">
|
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSRemoveTemplate" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Nu6-Aw-ihE">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -360,21 +319,12 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="4ig-lF-m2R" firstAttribute="leading" secondItem="MbP-FS-YEs" secondAttribute="leading" id="25E-Gc-eBh"/>
|
|
||||||
<constraint firstItem="4ig-lF-m2R" firstAttribute="top" secondItem="MbP-FS-YEs" secondAttribute="top" id="3Ss-BU-JcV"/>
|
|
||||||
<constraint firstItem="4ig-lF-m2R" firstAttribute="baseline" secondItem="3ei-2f-kHB" secondAttribute="baseline" id="Pp6-ir-tQB"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="4ig-lF-m2R" secondAttribute="bottom" id="dIB-U3-h90"/>
|
|
||||||
<constraint firstItem="3ei-2f-kHB" firstAttribute="leading" secondItem="MbP-FS-YEs" secondAttribute="leading" constant="20" symbolic="YES" id="fOJ-7v-G14"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
<color key="fillColor" red="1" green="1" blue="1" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
|
<color key="fillColor" red="1" green="1" blue="1" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
|
||||||
</box>
|
</box>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yyD-qq-aSk">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yyD-qq-aSk">
|
||||||
<rect key="frame" x="495" y="13" width="81" height="32"/>
|
<rect key="frame" x="462" y="13" width="81" height="32"/>
|
||||||
<constraints>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<constraint firstAttribute="width" constant="69" id="SDg-E4-Aza"/>
|
|
||||||
</constraints>
|
|
||||||
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="zPE-oD-PwK">
|
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="zPE-oD-PwK">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -386,11 +336,9 @@ DQ
|
|||||||
<action selector="ok:" target="-2" id="ifI-e4-Htf"/>
|
<action selector="ok:" target="-2" id="ifI-e4-Htf"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kGm-Zm-ipY">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kGm-Zm-ipY">
|
||||||
<rect key="frame" x="414" y="13" width="81" height="32"/>
|
<rect key="frame" x="381" y="13" width="81" height="32"/>
|
||||||
<constraints>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<constraint firstAttribute="width" constant="69" id="P30-kh-sbD"/>
|
|
||||||
</constraints>
|
|
||||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="j03-9E-uHW">
|
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="j03-9E-uHW">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -403,28 +351,11 @@ Gw
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="oZ5-85-pwY" secondAttribute="trailing" constant="20" symbolic="YES" id="6XB-Xo-ULh"/>
|
|
||||||
<constraint firstItem="oZ5-85-pwY" firstAttribute="trailing" secondItem="yyD-qq-aSk" secondAttribute="trailing" id="CEw-Ad-ctb"/>
|
|
||||||
<constraint firstItem="u4U-Ju-FJV" firstAttribute="top" secondItem="oZ5-85-pwY" secondAttribute="top" id="IMn-dq-QUj"/>
|
|
||||||
<constraint firstItem="Gqv-5O-Wwf" firstAttribute="top" secondItem="u4U-Ju-FJV" secondAttribute="bottom" id="IYg-B8-HlS"/>
|
|
||||||
<constraint firstItem="yyD-qq-aSk" firstAttribute="leading" secondItem="kGm-Zm-ipY" secondAttribute="trailing" constant="12" symbolic="YES" id="JBX-pg-6SB"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="kGm-Zm-ipY" secondAttribute="bottom" constant="20" symbolic="YES" id="LQl-3C-29i"/>
|
|
||||||
<constraint firstItem="oZ5-85-pwY" firstAttribute="leading" secondItem="Gqv-5O-Wwf" secondAttribute="trailing" constant="20" symbolic="YES" id="bvQ-7l-IZO"/>
|
|
||||||
<constraint firstItem="u4U-Ju-FJV" firstAttribute="leading" secondItem="Gqv-5O-Wwf" secondAttribute="leading" id="jtv-6s-2wd"/>
|
|
||||||
<constraint firstItem="oZ5-85-pwY" firstAttribute="leading" secondItem="u4U-Ju-FJV" secondAttribute="trailing" constant="20" symbolic="YES" id="nkb-ca-YNA"/>
|
|
||||||
<constraint firstItem="kGm-Zm-ipY" firstAttribute="top" secondItem="oZ5-85-pwY" secondAttribute="bottom" constant="20" symbolic="YES" id="rEF-Az-fO2"/>
|
|
||||||
<constraint firstItem="Gqv-5O-Wwf" firstAttribute="bottom" secondItem="oZ5-85-pwY" secondAttribute="bottom" id="sb3-Xg-ZeX"/>
|
|
||||||
<constraint firstItem="kGm-Zm-ipY" firstAttribute="baseline" secondItem="yyD-qq-aSk" secondAttribute="baseline" id="tvk-rK-yV5"/>
|
|
||||||
<constraint firstItem="u4U-Ju-FJV" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="vkk-Ys-and"/>
|
|
||||||
<constraint firstItem="u4U-Ju-FJV" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="yg3-ls-7P7"/>
|
|
||||||
<constraint firstItem="oZ5-85-pwY" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="273" id="zO0-Le-Yu1"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||||
</connections>
|
</connections>
|
||||||
<point key="canvasLocation" x="406" y="177"/>
|
<point key="canvasLocation" x="389.5" y="45.5"/>
|
||||||
</window>
|
</window>
|
||||||
<numberFormatter formatterBehavior="default10_4" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="QZc-kt-D7Z" userLabel="Port Number Formatter">
|
<numberFormatter formatterBehavior="default10_4" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="QZc-kt-D7Z" userLabel="Port Number Formatter">
|
||||||
<real key="minimum" value="1"/>
|
<real key="minimum" value="1"/>
|
||||||
|
@ -0,0 +1,163 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="ShareServerProfilesWindowController" customModule="ShadowsocksX_NG" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="copyAllServerURLsButton" destination="PkN-2i-ex7" id="5gY-Vs-cfn"/>
|
||||||
|
<outlet property="copyQRCodeButton" destination="GPl-Kb-AZg" id="pId-jX-erp"/>
|
||||||
|
<outlet property="copyURLButton" destination="Myo-Gh-Sba" id="3uJ-PP-nOS"/>
|
||||||
|
<outlet property="profilesTableView" destination="LWb-xh-GIK" id="qqJ-Qa-fWq"/>
|
||||||
|
<outlet property="qrCodeImageView" destination="atP-ge-P5H" id="Wc7-Ht-oJE"/>
|
||||||
|
<outlet property="saveAllServerURLsAsFileButton" destination="WOW-rs-fyP" id="A7T-IN-ub2"/>
|
||||||
|
<outlet property="saveQRCodeAsFileButton" destination="4WD-tD-JDA" id="Bfg-wE-8ls"/>
|
||||||
|
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<window title="Share Server Profiles" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
|
<rect key="contentRect" x="562" y="341" width="508" height="386"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||||
|
<view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="508" height="386"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="d0q-qb-o6U">
|
||||||
|
<rect key="frame" x="20" y="86" width="200" height="280"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<clipView key="contentView" ambiguous="YES" id="G7B-Z5-glP">
|
||||||
|
<rect key="frame" x="1" y="1" width="198" height="278"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="LWb-xh-GIK">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="198" height="278"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<size key="intercellSpacing" width="3" height="2"/>
|
||||||
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<tableColumns>
|
||||||
|
<tableColumn identifier="" editable="NO" width="195" minWidth="40" maxWidth="1000" id="BVB-7v-GrU">
|
||||||
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Server">
|
||||||
|
<font key="font" metaFont="smallSystem"/>
|
||||||
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</tableHeaderCell>
|
||||||
|
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Z7X-TN-APg">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
|
<prototypeCellViews>
|
||||||
|
<tableCellView identifier="cellTitle" id="a8X-ox-vkA">
|
||||||
|
<rect key="frame" x="1" y="1" width="195" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kni-HI-MDc">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="195" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="EIQ-Bg-vVe">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
<connections>
|
||||||
|
<outlet property="textField" destination="Kni-HI-MDc" id="wnh-Vn-cT5"/>
|
||||||
|
</connections>
|
||||||
|
</tableCellView>
|
||||||
|
</prototypeCellViews>
|
||||||
|
</tableColumn>
|
||||||
|
</tableColumns>
|
||||||
|
<connections>
|
||||||
|
<outlet property="dataSource" destination="-2" id="4GA-ch-rOE"/>
|
||||||
|
<outlet property="delegate" destination="-2" id="IdR-br-h7j"/>
|
||||||
|
</connections>
|
||||||
|
</tableView>
|
||||||
|
</subviews>
|
||||||
|
</clipView>
|
||||||
|
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="gkA-hM-aoX">
|
||||||
|
<rect key="frame" x="1" y="224" width="178" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</scroller>
|
||||||
|
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="UQv-FS-DZa">
|
||||||
|
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</scroller>
|
||||||
|
</scrollView>
|
||||||
|
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="atP-ge-P5H">
|
||||||
|
<rect key="frame" x="238" y="116" width="250" height="250"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="V51-A5-F2F"/>
|
||||||
|
</imageView>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GPl-Kb-AZg">
|
||||||
|
<rect key="frame" x="232" y="46" width="262" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Copy QRCode" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="PrW-s6-Uab">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="copyQRCode:" target="-2" id="cLd-uU-Mqd"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4WD-tD-JDA">
|
||||||
|
<rect key="frame" x="232" y="13" width="262" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Save QRCode As File" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IaI-Rj-Kss">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="saveQRCodeAsFile:" target="-2" id="cHE-5h-cbg"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PkN-2i-ex7">
|
||||||
|
<rect key="frame" x="14" y="46" width="212" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Copy All Server URLs" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Yt2-p1-4w0">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="copyAllServerURLs:" target="-2" id="y34-hx-a7y"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WOW-rs-fyP">
|
||||||
|
<rect key="frame" x="14" y="13" width="212" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Save All Server URLs As File" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="9OS-xy-GB1">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="saveAllServerURLsAsFile:" target="-2" id="Urh-dz-B8d"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Myo-Gh-Sba">
|
||||||
|
<rect key="frame" x="232" y="79" width="262" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Copy URL" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="PHX-gY-lZe">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="copyURL:" target="-2" id="dqq-Ps-sEh"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||||
|
</connections>
|
||||||
|
<point key="canvasLocation" x="143" y="207"/>
|
||||||
|
</window>
|
||||||
|
</objects>
|
||||||
|
</document>
|
@ -36,8 +36,6 @@ class PreferencesWindowController: NSWindowController
|
|||||||
var profileMgr: ServerProfileManager!
|
var profileMgr: ServerProfileManager!
|
||||||
|
|
||||||
var editingProfile: ServerProfile!
|
var editingProfile: ServerProfile!
|
||||||
|
|
||||||
var enabledKcptunSubDisosable: Disposable?
|
|
||||||
|
|
||||||
|
|
||||||
override func windowDidLoad() {
|
override func windowDidLoad() {
|
||||||
@ -207,10 +205,7 @@ class PreferencesWindowController: NSWindowController
|
|||||||
|
|
||||||
func bindProfile(_ index:Int) {
|
func bindProfile(_ index:Int) {
|
||||||
NSLog("bind profile \(index)")
|
NSLog("bind profile \(index)")
|
||||||
if let dis = enabledKcptunSubDisosable {
|
|
||||||
dis.dispose()
|
|
||||||
enabledKcptunSubDisosable = Optional.none
|
|
||||||
}
|
|
||||||
if index >= 0 && index < profileMgr.profiles.count {
|
if index >= 0 && index < profileMgr.profiles.count {
|
||||||
editingProfile = profileMgr.profiles[index]
|
editingProfile = profileMgr.profiles[index]
|
||||||
|
|
||||||
|
189
ShadowsocksX-NG/ShareServerProfilesWindowController.swift
Normal file
189
ShadowsocksX-NG/ShareServerProfilesWindowController.swift
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
//
|
||||||
|
// ShareServerProfilesWindowController.swift
|
||||||
|
// ShadowsocksX-NG
|
||||||
|
//
|
||||||
|
// Created by 邱宇舟 on 2018/9/16.
|
||||||
|
// Copyright © 2018年 qiuyuzhou. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class ShareServerProfilesWindowController: NSWindowController
|
||||||
|
, NSTableViewDataSource, NSTableViewDelegate {
|
||||||
|
|
||||||
|
@IBOutlet weak var profilesTableView: NSTableView!
|
||||||
|
|
||||||
|
@IBOutlet weak var qrCodeImageView: NSImageView!
|
||||||
|
|
||||||
|
@IBOutlet weak var copyAllServerURLsButton: NSButton!
|
||||||
|
@IBOutlet weak var saveAllServerURLsAsFileButton: NSButton!
|
||||||
|
|
||||||
|
@IBOutlet weak var copyURLButton: NSButton!
|
||||||
|
@IBOutlet weak var copyQRCodeButton: NSButton!
|
||||||
|
@IBOutlet weak var saveQRCodeAsFileButton: NSButton!
|
||||||
|
|
||||||
|
var defaults: UserDefaults!
|
||||||
|
var profileMgr: ServerProfileManager!
|
||||||
|
|
||||||
|
override func windowDidLoad() {
|
||||||
|
super.windowDidLoad()
|
||||||
|
|
||||||
|
defaults = UserDefaults.standard
|
||||||
|
profileMgr = ServerProfileManager.instance
|
||||||
|
|
||||||
|
if !profileMgr.profiles.isEmpty {
|
||||||
|
let index = IndexSet(integer: 0)
|
||||||
|
profilesTableView.selectRowIndexes(index, byExtendingSelection: false)
|
||||||
|
} else {
|
||||||
|
copyAllServerURLsButton.isEnabled = false
|
||||||
|
saveAllServerURLsAsFileButton.isEnabled = false
|
||||||
|
copyURLButton.isEnabled = false
|
||||||
|
copyQRCodeButton.isEnabled = false
|
||||||
|
saveQRCodeAsFileButton.isEnabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func copyURL(_ sender: NSButton) {
|
||||||
|
let profile = getSelectedProfile()
|
||||||
|
if profile.isValid(), let url = profile.URL() {
|
||||||
|
let pb = NSPasteboard.general
|
||||||
|
pb.clearContents()
|
||||||
|
if pb.writeObjects([url as NSPasteboardWriting]) {
|
||||||
|
NSLog("Copy URL to clipboard")
|
||||||
|
} else {
|
||||||
|
NSLog("Failed to copy URL to clipboard")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func copyQRCode(_ sender: NSButton) {
|
||||||
|
if let img = qrCodeImageView.image {
|
||||||
|
let pb = NSPasteboard.general
|
||||||
|
pb.clearContents()
|
||||||
|
if pb.writeObjects([img as NSPasteboardWriting]) {
|
||||||
|
NSLog("Copy QRCode to clipboard")
|
||||||
|
} else {
|
||||||
|
NSLog("Failed to copy QRCode to clipboard")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func saveQRCodeAsFile(_ sender: NSButton) {
|
||||||
|
if let img = qrCodeImageView.image {
|
||||||
|
let savePanel = NSSavePanel()
|
||||||
|
savePanel.title = "Save All Server URLs To File".localized
|
||||||
|
savePanel.canCreateDirectories = true
|
||||||
|
savePanel.allowedFileTypes = ["gif"]
|
||||||
|
savePanel.isExtensionHidden = false
|
||||||
|
|
||||||
|
let profile = getSelectedProfile()
|
||||||
|
if profile.remark.isEmpty {
|
||||||
|
savePanel.nameFieldStringValue = "shadowsocks_qrcode.gif"
|
||||||
|
} else {
|
||||||
|
savePanel.nameFieldStringValue = "shadowsocks_qrcode_\(profile.remark).gif"
|
||||||
|
}
|
||||||
|
|
||||||
|
savePanel.becomeKey()
|
||||||
|
let result = savePanel.runModal()
|
||||||
|
if (result.rawValue == NSFileHandlingPanelOKButton && (savePanel.url) != nil) {
|
||||||
|
let imgRep = NSBitmapImageRep(data: img.tiffRepresentation!)
|
||||||
|
let data = imgRep?.representation(using: NSBitmapImageRep.FileType.gif, properties: [:])
|
||||||
|
try! data?.write(to: savePanel.url!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func copyAllServerURLs(_ sender: NSButton) {
|
||||||
|
let pb = NSPasteboard.general
|
||||||
|
pb.clearContents()
|
||||||
|
if pb.writeObjects([getAllServerURLs() as NSPasteboardWriting]) {
|
||||||
|
NSLog("Copy all server URLs to clipboard")
|
||||||
|
} else {
|
||||||
|
NSLog("Failed to all server URLs to clipboard")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func saveAllServerURLsAsFile(_ sender: NSButton) {
|
||||||
|
let formatter = DateFormatter()
|
||||||
|
formatter.dateFormat = "yyyyMMdd"
|
||||||
|
let date_string = formatter.string(from: Date())
|
||||||
|
|
||||||
|
let savePanel = NSSavePanel()
|
||||||
|
savePanel.title = "Save All Server URLs To File".localized
|
||||||
|
savePanel.canCreateDirectories = true
|
||||||
|
savePanel.allowedFileTypes = ["txt"]
|
||||||
|
savePanel.isExtensionHidden = false
|
||||||
|
savePanel.nameFieldStringValue = "shadowsocks_profiles_\(date_string).txt"
|
||||||
|
savePanel.becomeKey()
|
||||||
|
let result = savePanel.runModal()
|
||||||
|
if (result.rawValue == NSFileHandlingPanelOKButton && (savePanel.url) != nil) {
|
||||||
|
let urls = getAllServerURLs()
|
||||||
|
try! urls.write(to: (savePanel.url)!, atomically: true, encoding: String.Encoding.utf8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllServerURLs() -> String {
|
||||||
|
let urls = profileMgr.profiles.filter({ (profile) -> Bool in
|
||||||
|
return profile.isValid()
|
||||||
|
}).map { (profile) -> String in
|
||||||
|
return profile.URL()!.absoluteString
|
||||||
|
}
|
||||||
|
return urls.joined(separator: "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSelectedProfile() -> ServerProfile {
|
||||||
|
let i = profilesTableView.selectedRow
|
||||||
|
return profileMgr.profiles[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDataAtRow(_ index:Int) -> String {
|
||||||
|
let profile = profileMgr.profiles[index]
|
||||||
|
if !profile.remark.isEmpty {
|
||||||
|
return profile.remark
|
||||||
|
} else {
|
||||||
|
return profile.serverHost
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// For NSTableViewDataSource
|
||||||
|
|
||||||
|
func numberOfRows(in tableView: NSTableView) -> Int {
|
||||||
|
if let mgr = profileMgr {
|
||||||
|
return mgr.profiles.count
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// For NSTableViewDelegate
|
||||||
|
|
||||||
|
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
||||||
|
let colId = NSUserInterfaceItemIdentifier(rawValue: "cellTitle")
|
||||||
|
if let cell = tableView.makeView(withIdentifier: colId, owner: self) as? NSTableCellView {
|
||||||
|
cell.textField?.stringValue = getDataAtRow(row)
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableViewSelectionDidChange(_ notification: Notification) {
|
||||||
|
if profilesTableView.selectedRow >= 0 {
|
||||||
|
let profile = getSelectedProfile()
|
||||||
|
if profile.isValid(), let url = profile.URL() {
|
||||||
|
let img = createQRImage(url.absoluteString, NSMakeSize(250, 250))
|
||||||
|
qrCodeImageView.image = img
|
||||||
|
|
||||||
|
copyURLButton.isEnabled = true
|
||||||
|
copyQRCodeButton.isEnabled = true
|
||||||
|
saveQRCodeAsFileButton.isEnabled = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qrCodeImageView.image = nil
|
||||||
|
|
||||||
|
copyURLButton.isEnabled = false
|
||||||
|
copyQRCodeButton.isEnabled = false
|
||||||
|
saveQRCodeAsFileButton.isEnabled = false
|
||||||
|
}
|
||||||
|
}
|
@ -11,4 +11,6 @@
|
|||||||
|
|
||||||
void ScanQRCodeOnScreen();
|
void ScanQRCodeOnScreen();
|
||||||
|
|
||||||
|
NSImage* createQRImage(NSString *string, NSSize size);
|
||||||
|
|
||||||
#endif /* QRCodeUtils_h */
|
#endif /* QRCodeUtils_h */
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <CoreImage/CoreImage.h>
|
#import <CoreImage/CoreImage.h>
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
|
||||||
void ScanQRCodeOnScreen() {
|
void ScanQRCodeOnScreen() {
|
||||||
/* displays[] Quartz display ID's */
|
/* displays[] Quartz display ID's */
|
||||||
@ -75,3 +76,42 @@ void ScanQRCodeOnScreen() {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSImage* createQRImage(NSString *string, NSSize size) {
|
||||||
|
NSImage *outputImage = [[NSImage alloc]initWithSize:size];
|
||||||
|
[outputImage lockFocus];
|
||||||
|
|
||||||
|
// Setup the QR filter with our string
|
||||||
|
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
|
||||||
|
[filter setDefaults];
|
||||||
|
|
||||||
|
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
[filter setValue:data forKey:@"inputMessage"];
|
||||||
|
/*
|
||||||
|
L: 7%
|
||||||
|
M: 15%
|
||||||
|
Q: 25%
|
||||||
|
H: 30%
|
||||||
|
*/
|
||||||
|
[filter setValue:@"Q" forKey:@"inputCorrectionLevel"];
|
||||||
|
|
||||||
|
CIImage *image = [filter valueForKey:@"outputImage"];
|
||||||
|
|
||||||
|
// Calculate the size of the generated image and the scale for the desired image size
|
||||||
|
CGRect extent = CGRectIntegral(image.extent);
|
||||||
|
CGFloat scale = MIN(size.width / CGRectGetWidth(extent), size.height / CGRectGetHeight(extent));
|
||||||
|
|
||||||
|
CGImageRef bitmapImage = [NSGraphicsContext.currentContext.CIContext createCGImage:image fromRect:extent];
|
||||||
|
|
||||||
|
CGContextRef graphicsContext = NSGraphicsContext.currentContext.CGContext;
|
||||||
|
|
||||||
|
CGContextSetInterpolationQuality(graphicsContext, kCGInterpolationNone);
|
||||||
|
CGContextScaleCTM(graphicsContext, scale, scale);
|
||||||
|
CGContextDrawImage(graphicsContext, extent, bitmapImage);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
CGImageRelease(bitmapImage);
|
||||||
|
|
||||||
|
[outputImage unlockFocus];
|
||||||
|
return outputImage;
|
||||||
|
}
|
||||||
|
@ -26,7 +26,9 @@
|
|||||||
* ./AppDelegate.swift
|
* ./AppDelegate.swift
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"Add Shadowsocks Server Profile" = "已添加新Shadowsocks服务器配置";
|
"Add \(addCount) Shadowsocks Server Profile" = "已添加\(addCount)个Shadowsocks服务器配置";
|
||||||
|
|
||||||
|
"Not found valid qrcode or url of shadowsocks profile" = "没有找到有效的shadowsocks配置二维码或链接";
|
||||||
|
|
||||||
"By scan QR Code" = "通过扫描二维码";
|
"By scan QR Code" = "通过扫描二维码";
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
/* Class = "NSMenuItem"; title = "Preferences..."; ObjectID = "4CS-qD-zW5"; */
|
/* Class = "NSMenuItem"; title = "Preferences..."; ObjectID = "4CS-qD-zW5"; */
|
||||||
"4CS-qD-zW5.title" = "偏好设置...";
|
"4CS-qD-zW5.title" = "偏好设置...";
|
||||||
|
|
||||||
|
/* Class = "NSMenuItem"; title = "Import Server URLs From Pasteboard"; ObjectID = "7Eq-XD-K5c"; */
|
||||||
|
"7Eq-XD-K5c.title" = "从剪贴板导入服务器配置链接";
|
||||||
|
|
||||||
/* Class = "NSMenuItem"; title = "应用用户自定规则到 PAC"; ObjectID = "6qf-cg-HXc"; */
|
/* Class = "NSMenuItem"; title = "应用用户自定规则到 PAC"; ObjectID = "6qf-cg-HXc"; */
|
||||||
"6qf-cg-HXc.title" = "应用用户自定规则到 PAC";
|
"6qf-cg-HXc.title" = "应用用户自定规则到 PAC";
|
||||||
|
|
||||||
@ -30,7 +33,7 @@
|
|||||||
"Mw3-Jm-eXA.title" = "全局模式";
|
"Mw3-Jm-eXA.title" = "全局模式";
|
||||||
|
|
||||||
/* Class = "NSMenuItem"; title = "扫描屏幕上的二维码..."; ObjectID = "Qe6-bF-paT"; */
|
/* Class = "NSMenuItem"; title = "扫描屏幕上的二维码..."; ObjectID = "Qe6-bF-paT"; */
|
||||||
"Qe6-bF-paT.title" = "扫描屏幕上的二维码...";
|
"Qe6-bF-paT.title" = "扫描屏幕上的二维码";
|
||||||
|
|
||||||
/* Class = "NSMenuItem"; title = "显示当前服务器的二维码..."; ObjectID = "R6A-96-Zcb"; */
|
/* Class = "NSMenuItem"; title = "显示当前服务器的二维码..."; ObjectID = "R6A-96-Zcb"; */
|
||||||
"R6A-96-Zcb.title" = "显示当前服务器的二维码...";
|
"R6A-96-Zcb.title" = "显示当前服务器的二维码...";
|
||||||
@ -98,4 +101,5 @@
|
|||||||
/* Class = "NSMenuItem"; title = "Preferences"; ObjectID = "iVn-LD-Ynd"; */
|
/* Class = "NSMenuItem"; title = "Preferences"; ObjectID = "iVn-LD-Ynd"; */
|
||||||
"iVn-LD-Ynd.title" = "偏好设置";
|
"iVn-LD-Ynd.title" = "偏好设置";
|
||||||
|
|
||||||
|
/* Class = "NSMenuItem"; title = "Share Server Profiles..."; ObjectID = "r5z-RB-LIZ"; */
|
||||||
|
"r5z-RB-LIZ.title" = "分享服务器配置...";
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
/* Class = "NSButtonCell"; title = "Save All Server URLs As File"; ObjectID = "9OS-xy-GB1"; */
|
||||||
|
"9OS-xy-GB1.title" = "保存所有服务器链接到文件";
|
||||||
|
|
||||||
|
/* Class = "NSWindow"; title = "Share Server Profiles"; ObjectID = "F0z-JX-Cv5"; */
|
||||||
|
"F0z-JX-Cv5.title" = "分享服务器配置";
|
||||||
|
|
||||||
|
/* Class = "NSButtonCell"; title = "Save QRCode As File"; ObjectID = "IaI-Rj-Kss"; */
|
||||||
|
"IaI-Rj-Kss.title" = "保存二维码到文件";
|
||||||
|
|
||||||
|
/* Class = "NSButtonCell"; title = "Copy URL"; ObjectID = "PHX-gY-lZe"; */
|
||||||
|
"PHX-gY-lZe.title" = "复制链接";
|
||||||
|
|
||||||
|
/* Class = "NSButtonCell"; title = "Copy QRCode"; ObjectID = "PrW-s6-Uab"; */
|
||||||
|
"PrW-s6-Uab.title" = "复制二维码";
|
||||||
|
|
||||||
|
/* Class = "NSButtonCell"; title = "Copy All Server URLs"; ObjectID = "Yt2-p1-4w0"; */
|
||||||
|
"Yt2-p1-4w0.title" = "复制所有服务器链接";
|
||||||
|
|
Reference in New Issue
Block a user