mirror of
https://github.com/qinyuhang/ShadowsocksX-NG-R.git
synced 2026-10-17 11:14:00 +00:00
239 lines
7.8 KiB
Swift
239 lines
7.8 KiB
Swift
//
|
|
// PreferencesWindowController.swift
|
|
// ShadowsocksX-NG
|
|
//
|
|
// Created by 邱宇舟 on 16/6/6.
|
|
// Copyright © 2016年 qiuyuzhou. All rights reserved.
|
|
//
|
|
|
|
import Cocoa
|
|
|
|
class PreferencesWindowController: NSWindowController
|
|
, NSTableViewDataSource, NSTableViewDelegate {
|
|
|
|
@IBOutlet weak var profilesTableView: NSTableView!
|
|
|
|
@IBOutlet weak var profileBox: NSBox!
|
|
|
|
@IBOutlet weak var hostTextField: NSTextField!
|
|
@IBOutlet weak var portTextField: NSTextField!
|
|
@IBOutlet weak var methodTextField: NSComboBox!
|
|
|
|
@IBOutlet weak var passwordTextField: NSTextField!
|
|
@IBOutlet weak var remarkTextField: NSTextField!
|
|
|
|
@IBOutlet weak var otaCheckBoxBtn: NSButton!
|
|
|
|
@IBOutlet weak var copyURLBtn: NSButton!
|
|
|
|
var defaults: NSUserDefaults!
|
|
var profileMgr: ServerProfileManager!
|
|
|
|
var editingProfile: ServerProfile!
|
|
|
|
override func windowDidLoad() {
|
|
super.windowDidLoad()
|
|
|
|
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
|
defaults = NSUserDefaults.standardUserDefaults()
|
|
profileMgr = ServerProfileManager.instance
|
|
|
|
methodTextField.addItemsWithObjectValues([
|
|
"aes-128-cfb",
|
|
"aes-192-cfb",
|
|
"aes-256-cfb",
|
|
"des-cfb",
|
|
"bf-cfb",
|
|
"cast5-cfb",
|
|
"rc4-md5",
|
|
"chacha20",
|
|
"salsa20",
|
|
"rc4",
|
|
"table",
|
|
])
|
|
|
|
profilesTableView.reloadData()
|
|
updateProfileBoxVisible()
|
|
}
|
|
|
|
@IBAction func addProfile(sender: NSButton) {
|
|
if editingProfile != nil && !editingProfile.isValid(){
|
|
return
|
|
}
|
|
profilesTableView.beginUpdates()
|
|
let profile = ServerProfile()
|
|
profile.remark = "New Server".localized
|
|
profileMgr.profiles.append(profile)
|
|
|
|
let index = NSIndexSet(index: profileMgr.profiles.count-1)
|
|
profilesTableView.insertRowsAtIndexes(index, withAnimation: .EffectFade)
|
|
|
|
self.profilesTableView.scrollRowToVisible(self.profileMgr.profiles.count-1)
|
|
self.profilesTableView.selectRowIndexes(index, byExtendingSelection: false)
|
|
profilesTableView.endUpdates()
|
|
updateProfileBoxVisible()
|
|
}
|
|
|
|
@IBAction func removeProfile(sender: NSButton) {
|
|
let index = profilesTableView.selectedRow
|
|
if index >= 0 {
|
|
profilesTableView.beginUpdates()
|
|
profileMgr.profiles.removeAtIndex(index)
|
|
profilesTableView.removeRowsAtIndexes(NSIndexSet(index: index), withAnimation: .EffectFade)
|
|
profilesTableView.endUpdates()
|
|
}
|
|
updateProfileBoxVisible()
|
|
}
|
|
|
|
@IBAction func ok(sender: NSButton) {
|
|
if editingProfile != nil {
|
|
if !editingProfile.isValid() {
|
|
// TODO Shake window?
|
|
return
|
|
}
|
|
}
|
|
profileMgr.save()
|
|
window?.performClose(nil)
|
|
|
|
NSNotificationCenter.defaultCenter()
|
|
.postNotificationName(NOTIFY_SERVER_PROFILES_CHANGED, object: nil)
|
|
}
|
|
|
|
@IBAction func cancel(sender: NSButton) {
|
|
window?.performClose(self)
|
|
}
|
|
|
|
@IBAction func copyCurrentProfileURL2Pasteboard(sender: NSButton) {
|
|
let index = profilesTableView.selectedRow
|
|
if index >= 0 {
|
|
let profile = profileMgr.profiles[index]
|
|
let ssURL = profile.URL()
|
|
if let url = ssURL {
|
|
// Then copy url to pasteboard
|
|
// TODO Why it not working?? It's ok in objective-c
|
|
let pboard = NSPasteboard.generalPasteboard()
|
|
pboard.clearContents()
|
|
let rs = pboard.writeObjects([url])
|
|
if rs {
|
|
NSLog("copy to pasteboard success")
|
|
} else {
|
|
NSLog("copy to pasteboard failed")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func updateProfileBoxVisible() {
|
|
if profileMgr.profiles.isEmpty {
|
|
profileBox.hidden = true
|
|
} else {
|
|
profileBox.hidden = false
|
|
}
|
|
}
|
|
|
|
func bindProfile(index:Int) {
|
|
NSLog("bind profile \(index)")
|
|
if index >= 0 && index < profileMgr.profiles.count {
|
|
editingProfile = profileMgr.profiles[index]
|
|
|
|
hostTextField.bind("value", toObject: editingProfile, withKeyPath: "serverHost"
|
|
, options: [NSContinuouslyUpdatesValueBindingOption: true])
|
|
portTextField.bind("value", toObject: editingProfile, withKeyPath: "serverPort"
|
|
, options: [NSContinuouslyUpdatesValueBindingOption: true])
|
|
|
|
methodTextField.bind("value", toObject: editingProfile, withKeyPath: "method"
|
|
, options: [NSContinuouslyUpdatesValueBindingOption: true])
|
|
passwordTextField.bind("value", toObject: editingProfile, withKeyPath: "password"
|
|
, options: [NSContinuouslyUpdatesValueBindingOption: true])
|
|
|
|
remarkTextField.bind("value", toObject: editingProfile, withKeyPath: "remark"
|
|
, options: [NSContinuouslyUpdatesValueBindingOption: true])
|
|
|
|
otaCheckBoxBtn.bind("value", toObject: editingProfile, withKeyPath: "ota"
|
|
, options: [NSContinuouslyUpdatesValueBindingOption: true])
|
|
} else {
|
|
editingProfile = nil
|
|
hostTextField.unbind("value")
|
|
portTextField.unbind("value")
|
|
|
|
methodTextField.unbind("value")
|
|
passwordTextField.unbind("value")
|
|
|
|
remarkTextField.unbind("value")
|
|
|
|
otaCheckBoxBtn.unbind("value")
|
|
}
|
|
}
|
|
|
|
func getDataAtRow(index:Int) -> (String, Bool) {
|
|
let profile = profileMgr.profiles[index]
|
|
let isActive = (profileMgr.activeProfileId == profile.uuid)
|
|
if !profile.remark.isEmpty {
|
|
return (profile.remark, isActive)
|
|
} else {
|
|
return (profile.serverHost, isActive)
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// For NSTableViewDataSource
|
|
|
|
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
|
|
if let mgr = profileMgr {
|
|
return mgr.profiles.count
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func tableView(tableView: NSTableView
|
|
, objectValueForTableColumn tableColumn: NSTableColumn?
|
|
, row: Int) -> AnyObject? {
|
|
|
|
let (title, isActive) = getDataAtRow(row)
|
|
|
|
if tableColumn?.identifier == "main" {
|
|
return title
|
|
} else if tableColumn?.identifier == "status" {
|
|
if isActive {
|
|
return NSImage(named: "NSMenuOnStateTemplate")
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// For NSTableViewDelegate
|
|
|
|
func tableView(tableView: NSTableView
|
|
, shouldEditTableColumn tableColumn: NSTableColumn?, row: Int) -> Bool {
|
|
return false
|
|
}
|
|
|
|
func tableView(tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
|
|
if row < 0 {
|
|
editingProfile = nil
|
|
return true
|
|
}
|
|
if editingProfile != nil {
|
|
if !editingProfile.isValid() {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func tableViewSelectionDidChange(notification: NSNotification) {
|
|
if profilesTableView.selectedRow >= 0 {
|
|
bindProfile(profilesTableView.selectedRow)
|
|
} else {
|
|
if !profileMgr.profiles.isEmpty {
|
|
let index = NSIndexSet(index: profileMgr.profiles.count - 1)
|
|
profilesTableView.selectRowIndexes(index, byExtendingSelection: false)
|
|
}
|
|
}
|
|
}
|
|
}
|