Files
ShadowsocksX-NG/ShadowsocksX-NG/AppDelegate.swift
2016-06-09 06:59:42 +08:00

273 lines
9.2 KiB
Swift

//
// AppDelegate.swift
// ShadowsocksX-NG
//
// Created by on 16/6/5.
// Copyright © 2016 qiuyuzhou. All rights reserved.
//
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {
var qrcodeWinCtrl: SWBQRCodeWindowController!
var preferencesWinCtrl: PreferencesWindowController!
var advPreferencesWinCtrl: AdvPreferencesWindowController!
@IBOutlet weak var window: NSWindow!
@IBOutlet weak var statusMenu: NSMenu!
@IBOutlet weak var runningStatusMenuItem: NSMenuItem!
@IBOutlet weak var toggleRunningMenuItem: NSMenuItem!
@IBOutlet weak var autoModeMenuItem: NSMenuItem!
@IBOutlet weak var globalModeMenuItem: NSMenuItem!
@IBOutlet weak var serversMenuItem: NSMenuItem!
@IBOutlet var serversPreferencesMenuItem: NSMenuItem!
@IBOutlet weak var lanchAtLoginMenuItem: NSMenuItem!
var statusItem: NSStatusItem!
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self
// Prepare ss-local
InstallSSLocal()
// Prepare defaults
let defaults = NSUserDefaults.standardUserDefaults()
defaults.registerDefaults([
"ShadowsocksOn": true,
"LocalSocks5.ListenPort": NSNumber(unsignedShort: 1086),
"LocalSocks5.ListenAddress": "localhost",
"LocalSocks5.Timeout": NSNumber(unsignedInteger: 60),
"LocalSocks5.EnableUDPRelay": NSNumber(bool: false),
"GFWListURL": "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"
])
statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(20)
let image = NSImage(named: "menu_icon")
image?.template = true
statusItem.image = image
statusItem.menu = statusMenu
updateServersMenu()
let notifyCenter = NSNotificationCenter.defaultCenter()
notifyCenter.addObserverForName(NOTIFY_SERVER_PROFILES_CHANGED, object: nil, queue: nil
, usingBlock: {
(note) in
self.updateServersMenu()
SyncSSLocal()
}
)
notifyCenter.addObserverForName(NOTIFY_ADV_CONF_CHANGED, object: nil, queue: nil
, usingBlock: {
(note) in
SyncSSLocal()
}
)
notifyCenter.addObserverForName("NOTIFY_FOUND_SS_URL", object: nil, queue: nil) {
(note: NSNotification) in
if let userInfo = note.userInfo {
let urls: [NSURL] = userInfo["urls"] as! [NSURL]
let mgr = ServerProfileManager()
var isChanged = false
for url in urls {
let profielDict = ParseSSURL(url)
if let profielDict = profielDict {
let profile = ServerProfile.fromDictionary(profielDict)
mgr.profiles.append(profile)
isChanged = true
let userNote = NSUserNotification()
userNote.title = "Add Shadowsocks Server Profile".localized
userNote.subtitle = "By scan QR Code".localized
userNote.informativeText = "Host: \(profile.serverHost)"
" Port: \(profile.serverPort)"
" Encription Method: \(profile.method)".localized
userNote.soundName = NSUserNotificationDefaultSoundName
NSUserNotificationCenter.defaultUserNotificationCenter()
.deliverNotification(userNote);
}
}
if isChanged {
mgr.save()
self.updateServersMenu()
}
}
}
updateMainMenu()
SyncSSLocal()
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
@IBAction func toggleRunning(sender: NSMenuItem) {
let defaults = NSUserDefaults.standardUserDefaults()
var isOn = defaults.boolForKey("ShadowsocksOn")
isOn = !isOn
defaults.setBool(isOn, forKey: "ShadowsocksOn")
updateMainMenu()
if isOn {
StartSSLocal()
} else {
StopSSLocal()
}
}
@IBAction func updateGFWList(sender: NSMenuItem) {
UpdatePACFromGFWList()
}
@IBAction func showQRCodeForCurrentServer(sender: NSMenuItem) {
var errMsg: String?
let mgr = ServerProfileManager()
if let profile = mgr.getActiveProfile() {
if profile.isValid() {
// Show window
if qrcodeWinCtrl != nil{
qrcodeWinCtrl.close()
}
qrcodeWinCtrl = SWBQRCodeWindowController(windowNibName: "SWBQRCodeWindowController")
qrcodeWinCtrl.qrCode = profile.URL()!.absoluteString
qrcodeWinCtrl.showWindow(self)
NSApp.activateIgnoringOtherApps(true)
qrcodeWinCtrl.window?.makeKeyAndOrderFront(nil)
return
} else {
errMsg = "Current server profile is not valid.".localized
}
} else {
errMsg = "No current server profile.".localized
}
let userNote = NSUserNotification()
userNote.title = errMsg
userNote.soundName = NSUserNotificationDefaultSoundName
NSUserNotificationCenter.defaultUserNotificationCenter()
.deliverNotification(userNote);
}
@IBAction func scanQRCodeFromScreen(sender: NSMenuItem) {
ScanQRCodeOnScreen()
}
@IBAction func toggleLaunghAtLogin(sender: NSMenuItem) {
}
@IBAction func selectPACMode(sender: NSMenuItem) {
}
@IBAction func selectGlobalMode(sender: NSMenuItem) {
}
@IBAction func editServerPreferences(sender: NSMenuItem) {
if preferencesWinCtrl != nil {
preferencesWinCtrl.close()
}
let ctrl = PreferencesWindowController(windowNibName: "PreferencesWindowController")
preferencesWinCtrl = ctrl
ctrl.showWindow(self)
NSApp.activateIgnoringOtherApps(true)
ctrl.window?.makeKeyAndOrderFront(self)
}
@IBAction func editAdvPreferences(sender: NSMenuItem) {
if advPreferencesWinCtrl != nil {
advPreferencesWinCtrl.close()
}
let ctrl = AdvPreferencesWindowController(windowNibName: "AdvPreferencesWindowController")
advPreferencesWinCtrl = ctrl
ctrl.showWindow(self)
NSApp.activateIgnoringOtherApps(true)
ctrl.window?.makeKeyAndOrderFront(self)
}
@IBAction func selectServer(sender: NSMenuItem) {
let index = sender.tag
let spMgr = ServerProfileManager()
let newProfile = spMgr.profiles[index]
if newProfile.uuid != spMgr.activeProfileId {
spMgr.setActiveProfiledId(newProfile.uuid)
updateServersMenu()
SyncSSLocal()
}
}
func updateMainMenu() {
let defaults = NSUserDefaults.standardUserDefaults()
let isOn = defaults.boolForKey("ShadowsocksOn")
if isOn {
runningStatusMenuItem.title = "Shadowsocks: On".localized
toggleRunningMenuItem.title = "Close Shadowsocks".localized
} else {
runningStatusMenuItem.title = "Shadowsocks: Off".localized
toggleRunningMenuItem.title = "Open Shadowsocks".localized
}
}
func updateServersMenu() {
let mgr = ServerProfileManager()
serversMenuItem.submenu?.removeAllItems()
let preferencesItem = serversPreferencesMenuItem
var i = 0
for p in mgr.profiles {
let item = NSMenuItem()
item.tag = i
if p.remark.isEmpty {
item.title = "\(p.serverHost):\(p.serverPort)"
} else {
item.title = "\(p.remark) (\(p.serverHost):\(p.serverPort))"
}
if mgr.activeProfileId == p.uuid {
item.state = 1
}
if !p.isValid() {
item.enabled = false
}
item.action = #selector(AppDelegate.selectServer)
serversMenuItem.submenu?.addItem(item)
i += 1
}
if !mgr.profiles.isEmpty {
serversMenuItem.submenu?.addItem(NSMenuItem.separatorItem())
}
serversMenuItem.submenu?.addItem(preferencesItem)
}
//------------------------------------------------------------
// NSUserNotificationCenterDelegate
func userNotificationCenter(center: NSUserNotificationCenter
, shouldPresentNotification notification: NSUserNotification) -> Bool {
return true
}
}