Dynamically update ports menu

This commit is contained in:
Matthias Neeracher 2014-12-09 06:54:30 +01:00 committed by Matthias Neeracher
parent ec370e7e09
commit e13c8d4b0e
3 changed files with 53 additions and 10 deletions

View File

@ -39,6 +39,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
var currentTheme : UInt = 0 var currentTheme : UInt = 0
var fontSize : UInt = 12 var fontSize : UInt = 12
var themeObserver : AnyObject? var themeObserver : AnyObject?
var serialObserver : AnyObject?
var board = "uno" var board = "uno"
var programmer = "arduino" var programmer = "arduino"
dynamic var port : String = "" { dynamic var port : String = "" {
@ -85,22 +86,28 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
} }
} }
} }
fontSize = UInt(userDefaults.integerForKey(kFontSizeKey)) fontSize = UInt(userDefaults.integerForKey(kFontSizeKey))
themeObserver = NSNotificationCenter.defaultCenter().addObserverForName(kBindingsKey, object: nil, queue: nil, usingBlock: { (NSNotification) in
self.editor.setKeyboardHandler(keyboardHandler)
})
board = userDefaults.stringForKey(kBoardKey)! board = userDefaults.stringForKey(kBoardKey)!
programmer = userDefaults.stringForKey(kProgrammerKey)! programmer = userDefaults.stringForKey(kProgrammerKey)!
port = userDefaults.stringForKey(kPortKey)! port = userDefaults.stringForKey(kPortKey)!
recentBoards = userDefaults.objectForKey(kRecentBoardsKey) as [String] recentBoards = userDefaults.objectForKey(kRecentBoardsKey) as [String]
recentProgrammers = userDefaults.objectForKey(kRecentProgrammersKey) as [String] recentProgrammers = userDefaults.objectForKey(kRecentProgrammersKey) as [String]
var nc = NSNotificationCenter.defaultCenter()
themeObserver = nc.addObserverForName(kBindingsKey, object: nil, queue: nil, usingBlock: { (NSNotification) in
self.editor.setKeyboardHandler(keyboardHandler)
})
serialObserver = nc.addObserverForName(kASSerialPortsChanged, object: nil, queue: nil, usingBlock: { (NSNotification) in
self.rebuildPortMenu()
})
updateLogTimer = updateLogTimer =
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "updateLog:", userInfo: nil, repeats: true) NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "updateLog:", userInfo: nil, repeats: true)
} }
override func finalize() { override func finalize() {
saveCurEditor() saveCurEditor()
NSNotificationCenter.defaultCenter().removeObserver(themeObserver!) NSNotificationCenter.defaultCenter().removeObserver(themeObserver!)
NSNotificationCenter.defaultCenter().removeObserver(serialObserver!)
} }
override func windowControllerDidLoadNib(aController: NSWindowController) { override func windowControllerDidLoadNib(aController: NSWindowController) {
@ -120,10 +127,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
outlineViewSelectionDidChange(NSNotification(name: "", object: nil)) outlineViewSelectionDidChange(NSNotification(name: "", object: nil))
menuNeedsUpdate(boardTool.menu!) menuNeedsUpdate(boardTool.menu!)
menuNeedsUpdate(progTool.menu!) menuNeedsUpdate(progTool.menu!)
portTool.removeAllItems() rebuildPortMenu()
portTool.addItemWithTitle("Title")
portTool.addItemsWithTitles(ASSerial.ports())
portTool.setTitle(port)
updateChangeCount(.ChangeCleared) updateChangeCount(.ChangeCleared)
} }
@ -348,6 +352,15 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
selectNodeInOutline(files.buildLog) selectNodeInOutline(files.buildLog)
} }
func rebuildPortMenu() {
willChangeValueForKey("hasValidPort")
portTool.removeAllItems()
portTool.addItemWithTitle("Title")
portTool.addItemsWithTitles(ASSerial.instance().ports())
portTool.setTitle(port)
didChangeValueForKey("hasValidPort")
}
func menuNeedsUpdate(menu: NSMenu) { func menuNeedsUpdate(menu: NSMenu) {
switch menu.title { switch menu.title {
case "Boards": case "Boards":
@ -442,13 +455,19 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
return NSSet(object: "board") return NSSet(object: "board")
} }
var hasValidPort : Bool {
get {
return (ASSerial.instance().ports() as NSArray).containsObject(port)
}
}
var canUpload : Bool { var canUpload : Bool {
get { get {
return port != "" && (hasUploadProtocol || programmer != "") return hasValidPort && (hasUploadProtocol || programmer != "")
} }
} }
class func keyPathsForValuesAffectingCanUpload() -> NSSet { class func keyPathsForValuesAffectingCanUpload() -> NSSet {
return NSSet(objects: "port", "board", "programmer") return NSSet(objects: "hasValidPort", "hasUploadProtocol", "programmer")
} }
@IBAction func uploadProject(sender: AnyObject) { @IBAction func uploadProject(sender: AnyObject) {

View File

@ -8,8 +8,27 @@
import Foundation import Foundation
let kASSerialPortsChanged = "PortsChanged"
class ASSerialWatcher {
}
private let serialInstance = ASSerial()
class ASSerial { class ASSerial {
class func ports() -> [String] { class func instance() -> ASSerial { return serialInstance }
let watchSlashDev : dispatch_source_t
init() {
let fd = open("/dev", O_EVTONLY)
watchSlashDev = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, UInt(fd), DISPATCH_VNODE_WRITE, dispatch_get_main_queue())
dispatch_source_set_event_handler(watchSlashDev) { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName(kASSerialPortsChanged, object: nil)
}
dispatch_resume(watchSlashDev)
}
func ports() -> [String] {
let devices = NSFileManager.defaultManager().contentsOfDirectoryAtPath("/dev", error: nil)! let devices = NSFileManager.defaultManager().contentsOfDirectoryAtPath("/dev", error: nil)!
var cuDevs = [String]() var cuDevs = [String]()
for dev in devices as [String] { for dev in devices as [String] {

View File

@ -183,6 +183,11 @@
</popUpButtonCell> </popUpButtonCell>
<connections> <connections>
<action selector="selectPort:" target="-2" id="tRd-x3-Oig"/> <action selector="selectPort:" target="-2" id="tRd-x3-Oig"/>
<binding destination="-2" name="fontItalic" keyPath="hasValidPort" id="M4d-Nc-aZd">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections> </connections>
</popUpButton> </popUpButton>
</toolbarItem> </toolbarItem>