Modernize to Swift 2.0
This commit is contained in:
parent
bc77af7a80
commit
8d7e8c8c10
|
@ -316,6 +316,7 @@
|
||||||
9501D7F41A17025C0034C530 /* Project object */ = {
|
9501D7F41A17025C0034C530 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
|
LastSwiftMigration = 0710;
|
||||||
LastSwiftUpdateCheck = 0700;
|
LastSwiftUpdateCheck = 0700;
|
||||||
LastUpgradeCheck = 0630;
|
LastUpgradeCheck = 0630;
|
||||||
ORGANIZATIONNAME = "Aere Perennius";
|
ORGANIZATIONNAME = "Aere Perennius";
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Foundation
|
||||||
|
|
||||||
extension ACEView {
|
extension ACEView {
|
||||||
class func themeIdByName(themeName: String) -> ACETheme? {
|
class func themeIdByName(themeName: String) -> ACETheme? {
|
||||||
for (themeIdx, theme) in enumerate(ACEThemeNames.themeNames() as! [String]) {
|
for (themeIdx, theme) in (ACEThemeNames.themeNames() as! [String]).enumerate() {
|
||||||
if themeName == theme {
|
if themeName == theme {
|
||||||
return ACETheme(rawValue: UInt(themeIdx))
|
return ACETheme(rawValue: UInt(themeIdx))
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ extension ACEView {
|
||||||
}
|
}
|
||||||
|
|
||||||
class func handlerIdByName(handlerName: String) -> ACEKeyboardHandler? {
|
class func handlerIdByName(handlerName: String) -> ACEKeyboardHandler? {
|
||||||
for (handlerIdx, handler) in enumerate(ACEKeyboardHandlerNames.humanKeyboardHandlerNames() as! [String]) {
|
for (handlerIdx, handler) in (ACEKeyboardHandlerNames.humanKeyboardHandlerNames() as! [String]).enumerate() {
|
||||||
if handlerName == handler {
|
if handlerName == handler {
|
||||||
return ACEKeyboardHandler(rawValue: UInt(handlerIdx))!
|
return ACEKeyboardHandler(rawValue: UInt(handlerIdx))!
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,7 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
||||||
var examples = [String]()
|
var examples = [String]()
|
||||||
|
|
||||||
func hasDocument() -> Bool {
|
func hasDocument() -> Bool {
|
||||||
if let doc = NSDocumentController.sharedDocumentController().currentDocument as? NSDocument {
|
return NSDocumentController.sharedDocumentController().currentDocument != nil
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationWillFinishLaunching(notification: NSNotification) {
|
func applicationWillFinishLaunching(notification: NSNotification) {
|
||||||
|
@ -56,12 +52,12 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
||||||
}
|
}
|
||||||
func applicationDidFinishLaunching(aNotification: NSNotification) {
|
func applicationDidFinishLaunching(aNotification: NSNotification) {
|
||||||
themeMenu.removeAllItems()
|
themeMenu.removeAllItems()
|
||||||
for (index, theme) in enumerate(ACEThemeNames.humanThemeNames() as! [String]) {
|
for (index, theme) in (ACEThemeNames.humanThemeNames() as! [String]).enumerate() {
|
||||||
let menuItem = themeMenu.addItemWithTitle(theme, action: "changeTheme:", keyEquivalent: "")!
|
let menuItem = themeMenu.addItemWithTitle(theme, action: "changeTheme:", keyEquivalent: "")!
|
||||||
menuItem.tag = index
|
menuItem.tag = index
|
||||||
}
|
}
|
||||||
keyboardMenu.removeAllItems()
|
keyboardMenu.removeAllItems()
|
||||||
for (index, theme) in enumerate(ACEKeyboardHandlerNames.humanKeyboardHandlerNames() as! [String]) {
|
for (index, theme) in (ACEKeyboardHandlerNames.humanKeyboardHandlerNames() as! [String]).enumerate() {
|
||||||
let menuItem = keyboardMenu.addItemWithTitle(theme, action: "changeKeyboardHandler:", keyEquivalent: "")!
|
let menuItem = keyboardMenu.addItemWithTitle(theme, action: "changeKeyboardHandler:", keyEquivalent: "")!
|
||||||
menuItem.tag = index
|
menuItem.tag = index
|
||||||
}
|
}
|
||||||
|
@ -85,8 +81,8 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
||||||
case "Examples":
|
case "Examples":
|
||||||
menu.removeAllItems()
|
menu.removeAllItems()
|
||||||
examples = [String]()
|
examples = [String]()
|
||||||
if let arduinoPath = NSWorkspace.sharedWorkspace().URLForApplicationWithBundleIdentifier("cc.arduino.Arduino")?.path {
|
if let arduinoURL = NSWorkspace.sharedWorkspace().URLForApplicationWithBundleIdentifier("cc.arduino.Arduino") {
|
||||||
let examplePath = arduinoPath.stringByAppendingPathComponent("Contents/Resources/Java/examples")
|
let examplePath = arduinoURL.URLByAppendingPathComponent("Contents/Resources/Java/examples", isDirectory:true).path!
|
||||||
ASSketchBook.addSketches(menu, target: self, action: "openExample:", path: examplePath, sketches: &examples)
|
ASSketchBook.addSketches(menu, target: self, action: "openExample:", path: examplePath, sketches: &examples)
|
||||||
}
|
}
|
||||||
case "Import Standard Library":
|
case "Import Standard Library":
|
||||||
|
@ -100,7 +96,7 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
||||||
while menu.numberOfItems > 2 {
|
while menu.numberOfItems > 2 {
|
||||||
menu.removeItemAtIndex(2)
|
menu.removeItemAtIndex(2)
|
||||||
}
|
}
|
||||||
for port in ASSerial.ports() as! [String] {
|
for port in ASSerial.ports() {
|
||||||
menu.addItemWithTitle(port, action:"serialConnectMenu:", keyEquivalent:"")
|
menu.addItemWithTitle(port, action:"serialConnectMenu:", keyEquivalent:"")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -119,28 +115,26 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
||||||
let oldName = template.lastPathComponent!
|
let oldName = template.lastPathComponent!
|
||||||
let newName = saveTo.lastPathComponent!
|
let newName = saveTo.lastPathComponent!
|
||||||
let fileManager = NSFileManager.defaultManager()
|
let fileManager = NSFileManager.defaultManager()
|
||||||
fileManager.copyItemAtURL(template, toURL: saveTo, error: nil)
|
do {
|
||||||
|
try fileManager.copyItemAtURL(template, toURL: saveTo)
|
||||||
let contents = fileManager.enumeratorAtURL(saveTo,
|
let contents = fileManager.enumeratorAtURL(saveTo,
|
||||||
includingPropertiesForKeys: [NSURLNameKey, NSURLPathKey],
|
includingPropertiesForKeys: [NSURLNameKey, NSURLPathKey],
|
||||||
options: .SkipsHiddenFiles, errorHandler: nil)
|
options: .SkipsHiddenFiles, errorHandler: nil)
|
||||||
while let item = contents?.nextObject() as? NSURL {
|
while let item = contents?.nextObject() as? NSURL {
|
||||||
var renameItem = false
|
let itemBase = item.URLByDeletingPathExtension?.lastPathComponent!
|
||||||
var itemName = item.lastPathComponent!
|
if itemBase == oldName {
|
||||||
if itemName.stringByDeletingPathExtension == oldName {
|
let newItem = item.URLByDeletingLastPathComponent!.URLByAppendingPathComponent(
|
||||||
renameItem = true
|
newName).URLByAppendingPathExtension(item.pathExtension!)
|
||||||
itemName = newName.stringByAppendingPathExtension(itemName.pathExtension)!
|
try fileManager.moveItemAtURL(item, toURL: newItem)
|
||||||
}
|
}
|
||||||
if renameItem {
|
|
||||||
fileManager.moveItemAtURL(item,
|
|
||||||
toURL: item.URLByDeletingLastPathComponent!.URLByAppendingPathComponent(itemName),
|
|
||||||
error: nil)
|
|
||||||
}
|
}
|
||||||
|
} catch (_) {
|
||||||
}
|
}
|
||||||
let sketch = ASSketchBook.findSketch(saveTo.path!)
|
let sketch = ASSketchBook.findSketch(saveTo.path!)
|
||||||
switch sketch {
|
switch sketch {
|
||||||
case .Sketch(_, let path):
|
case .Sketch(_, let path):
|
||||||
let doc = NSDocumentController.sharedDocumentController() as! NSDocumentController
|
let doc = NSDocumentController.sharedDocumentController()
|
||||||
doc.openDocumentWithContentsOfURL(NSURL(fileURLWithPath: path)!, display: true) { (doc, alreadyOpen, error) -> Void in
|
doc.openDocumentWithContentsOfURL(NSURL(fileURLWithPath: path), display: true) { (doc, alreadyOpen, error) -> Void in
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
@ -149,39 +143,40 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func openSketch(item: NSMenuItem) {
|
@IBAction func openSketch(item: NSMenuItem) {
|
||||||
if let url = NSURL(fileURLWithPath: sketches[item.tag]) {
|
let url = NSURL(fileURLWithPath: sketches[item.tag])
|
||||||
let doc = NSDocumentController.sharedDocumentController() as! NSDocumentController
|
let doc = NSDocumentController.sharedDocumentController()
|
||||||
doc.openDocumentWithContentsOfURL(url, display: true) { (doc, alreadyOpen, error) -> Void in
|
doc.openDocumentWithContentsOfURL(url, display: true) { (doc, alreadyOpen, error) -> Void in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func openExample(item: NSMenuItem) {
|
@IBAction func openExample(item: NSMenuItem) {
|
||||||
if let url = NSURL(fileURLWithPath: examples[item.tag]) {
|
let url = NSURL(fileURLWithPath: examples[item.tag])
|
||||||
openTemplate(url.URLByDeletingLastPathComponent!)
|
openTemplate(url.URLByDeletingLastPathComponent!)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func createSketch(AnyObject) {
|
@IBAction func createSketch(_: AnyObject) {
|
||||||
ASApplication.newProjectLocation(nil,
|
ASApplication.newProjectLocation(nil,
|
||||||
message: "Create Project")
|
message: "Create Project")
|
||||||
{ (saveTo) -> Void in
|
{ (saveTo) -> Void in
|
||||||
let fileManager = NSFileManager.defaultManager()
|
let fileManager = NSFileManager.defaultManager()
|
||||||
fileManager.createDirectoryAtURL(saveTo, withIntermediateDirectories:false, attributes:nil, error:nil)
|
do {
|
||||||
|
try fileManager.createDirectoryAtURL(saveTo, withIntermediateDirectories:false, attributes:nil)
|
||||||
let proj = saveTo.URLByAppendingPathComponent(saveTo.lastPathComponent!+".avrsackproj")
|
let proj = saveTo.URLByAppendingPathComponent(saveTo.lastPathComponent!+".avrsackproj")
|
||||||
let docController = NSDocumentController.sharedDocumentController() as! NSDocumentController
|
let docController = NSDocumentController.sharedDocumentController()
|
||||||
if let doc = docController.openUntitledDocumentAndDisplay(true, error:nil) as? ASProjDoc {
|
if let doc = try docController.openUntitledDocumentAndDisplay(true) as? ASProjDoc {
|
||||||
doc.fileURL = proj
|
doc.fileURL = proj
|
||||||
doc.updateProjectURL()
|
doc.updateProjectURL()
|
||||||
doc.createFileAtURL(saveTo.URLByAppendingPathComponent(saveTo.lastPathComponent!+".ino"))
|
doc.createFileAtURL(saveTo.URLByAppendingPathComponent(saveTo.lastPathComponent!+".ino"))
|
||||||
doc.writeToURL(proj, ofType: "Project", forSaveOperation: .SaveAsOperation, originalContentsURL: nil, error: nil)
|
try doc.writeToURL(proj, ofType: "Project", forSaveOperation: .SaveAsOperation, originalContentsURL: nil)
|
||||||
|
}
|
||||||
|
} catch _ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class func newProjectLocation(documentWindow: NSWindow?, message: String, completion: (NSURL) -> ()) {
|
class func newProjectLocation(documentWindow: NSWindow?, message: String, completion: (NSURL) -> ()) {
|
||||||
let savePanel = NSSavePanel()
|
let savePanel = NSSavePanel()
|
||||||
savePanel.allowedFileTypes = [kUTTypeFolder]
|
savePanel.allowedFileTypes = [kUTTypeFolder as String]
|
||||||
savePanel.message = message
|
savePanel.message = message
|
||||||
if let window = documentWindow {
|
if let window = documentWindow {
|
||||||
savePanel.beginSheetModalForWindow(window, completionHandler: { (returnCode) -> Void in
|
savePanel.beginSheetModalForWindow(window, completionHandler: { (returnCode) -> Void in
|
||||||
|
|
|
@ -17,7 +17,7 @@ class ASBuilder {
|
||||||
init() {
|
init() {
|
||||||
termination = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification,
|
termination = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification,
|
||||||
object: nil, queue: nil, usingBlock:
|
object: nil, queue: nil, usingBlock:
|
||||||
{ (notification: NSNotification!) in
|
{ (notification: NSNotification) in
|
||||||
if notification.object as? NSTask == self.task {
|
if notification.object as? NSTask == self.task {
|
||||||
if self.task!.terminationStatus == 0 {
|
if self.task!.terminationStatus == 0 {
|
||||||
if let cont = self.continuation {
|
if let cont = self.continuation {
|
||||||
|
@ -44,7 +44,10 @@ class ASBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanProject() {
|
func cleanProject() {
|
||||||
NSFileManager.defaultManager().removeItemAtURL(dir.URLByAppendingPathComponent("build"), error: nil)
|
do {
|
||||||
|
try NSFileManager.defaultManager().removeItemAtURL(dir.URLByAppendingPathComponent("build"))
|
||||||
|
} catch _ {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildProject(board: String, files: ASFileTree) {
|
func buildProject(board: String, files: ASFileTree) {
|
||||||
|
@ -62,7 +65,7 @@ class ASBuilder {
|
||||||
}
|
}
|
||||||
let boardProp = ASHardware.instance().boards[board]!
|
let boardProp = ASHardware.instance().boards[board]!
|
||||||
let library = boardProp["library"]!
|
let library = boardProp["library"]!
|
||||||
var corePath = library+"/cores/"+boardProp["build.core"]!
|
let corePath = library+"/cores/"+boardProp["build.core"]!
|
||||||
var variantPath : String?
|
var variantPath : String?
|
||||||
if fileManager.fileExistsAtPath(corePath) {
|
if fileManager.fileExistsAtPath(corePath) {
|
||||||
if let variantName = boardProp["build.variant"] {
|
if let variantName = boardProp["build.variant"] {
|
||||||
|
@ -186,7 +189,7 @@ class ASBuilder {
|
||||||
task2.standardOutput = logOut
|
task2.standardOutput = logOut
|
||||||
task2.standardError = logOut
|
task2.standardError = logOut
|
||||||
continuation = {
|
continuation = {
|
||||||
let cmdLine = task2.launchPath+" "+(loaderArgs as NSArray).componentsJoinedByString(" ")+"\n"
|
let cmdLine = task2.launchPath!+" "+(loaderArgs as NSArray).componentsJoinedByString(" ")+"\n"
|
||||||
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
|
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
|
||||||
task2.launch()
|
task2.launch()
|
||||||
self.continuation = {
|
self.continuation = {
|
||||||
|
@ -226,12 +229,12 @@ class ASBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let cmdLine = task!.launchPath+" "+(args as NSArray).componentsJoinedByString(" ")+"\n"
|
let cmdLine = task!.launchPath!+" "+(args as NSArray).componentsJoinedByString(" ")+"\n"
|
||||||
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
|
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
|
||||||
task!.arguments = args;
|
task!.arguments = args;
|
||||||
task!.launch()
|
task!.launch()
|
||||||
if interactive {
|
if interactive {
|
||||||
let intSpeed = speed?.toInt() ?? 19200
|
let intSpeed = (speed != nil) ? Int(speed!) ?? 19200 : 19200
|
||||||
ASSerialWin.showWindowWithPort(port, task:task!, speed:intSpeed)
|
ASSerialWin.showWindowWithPort(port, task:task!, speed:intSpeed)
|
||||||
task = nil
|
task = nil
|
||||||
}
|
}
|
||||||
|
@ -253,7 +256,7 @@ class ASBuilder {
|
||||||
let showSource = NSUserDefaults.standardUserDefaults().boolForKey("ShowSourceInDisassembly")
|
let showSource = NSUserDefaults.standardUserDefaults().boolForKey("ShowSourceInDisassembly")
|
||||||
var args = showSource ? ["-S"] : []
|
var args = showSource ? ["-S"] : []
|
||||||
args += ["-d", "build/"+board+"/"+dir.lastPathComponent!+".elf"]
|
args += ["-d", "build/"+board+"/"+dir.lastPathComponent!+".elf"]
|
||||||
let cmdLine = task!.launchPath+" "+(args as NSArray).componentsJoinedByString(" ")+"\n"
|
let cmdLine = task!.launchPath!+" "+(args as NSArray).componentsJoinedByString(" ")+"\n"
|
||||||
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
|
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
|
||||||
task!.arguments = args;
|
task!.arguments = args;
|
||||||
task!.launch()
|
task!.launch()
|
||||||
|
|
|
@ -54,12 +54,7 @@ private let kNodeTypeGroup = "Group"
|
||||||
private let kNodeTypeFile = "File"
|
private let kNodeTypeFile = "File"
|
||||||
private let kNameKey = "Name"
|
private let kNameKey = "Name"
|
||||||
|
|
||||||
//
|
class ASFileNode {
|
||||||
// <rdar://problem/19787270> At the moment, Swift crashes at link time with an assertion
|
|
||||||
// if anything other than a value type or an @objc class is put into a container
|
|
||||||
// exposed to ObjC APIs. As a workaround, we declare this hierarchy @objc
|
|
||||||
//
|
|
||||||
@objc class ASFileNode {
|
|
||||||
var name : String
|
var name : String
|
||||||
|
|
||||||
init(name: String) {
|
init(name: String) {
|
||||||
|
@ -192,7 +187,7 @@ class ASFileItem : ASFileNode {
|
||||||
if let relativeURL = NSURL(string: prop[kPathKey] as! String, relativeToURL: rootURL) {
|
if let relativeURL = NSURL(string: prop[kPathKey] as! String, relativeToURL: rootURL) {
|
||||||
url = relativeURL.URLByStandardizingPath!
|
url = relativeURL.URLByStandardizingPath!
|
||||||
} else {
|
} else {
|
||||||
url = NSURL(fileURLWithPath:(prop[kPathKey] as! String))!.URLByStandardizingPath!
|
url = NSURL(fileURLWithPath:(prop[kPathKey] as! String)).URLByStandardizingPath!
|
||||||
}
|
}
|
||||||
if !url.checkResourceIsReachableAndReturnError(nil) {
|
if !url.checkResourceIsReachableAndReturnError(nil) {
|
||||||
//
|
//
|
||||||
|
@ -200,10 +195,11 @@ class ASFileItem : ASFileNode {
|
||||||
// yet reflected in the project file.
|
// yet reflected in the project file.
|
||||||
//
|
//
|
||||||
let urlDir = url.URLByDeletingLastPathComponent
|
let urlDir = url.URLByDeletingLastPathComponent
|
||||||
let newName = rootURL.lastPathComponent!.stringByAppendingPathExtension(url.pathExtension!)!
|
let newName = rootURL.URLByAppendingPathExtension(url.pathExtension!).lastPathComponent!
|
||||||
let altURL = urlDir?.URLByAppendingPathComponent(newName)
|
if let altURL = urlDir?.URLByAppendingPathComponent(newName) {
|
||||||
if altURL != nil && altURL!.checkResourceIsReachableAndReturnError(nil) {
|
if altURL.checkResourceIsReachableAndReturnError(nil) {
|
||||||
url = altURL!
|
url = altURL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.init(name:url.lastPathComponent!)
|
super.init(name:url.lastPathComponent!)
|
||||||
|
@ -213,7 +209,7 @@ class ASFileItem : ASFileNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
func relativePath(relativeTo: String) -> String {
|
func relativePath(relativeTo: String) -> String {
|
||||||
let path = url.path!.stringByResolvingSymlinksInPath
|
let path = (url.path! as NSString).stringByResolvingSymlinksInPath
|
||||||
let relComp = relativeTo.componentsSeparatedByString("/") as [String]
|
let relComp = relativeTo.componentsSeparatedByString("/") as [String]
|
||||||
let pathComp = path.componentsSeparatedByString("/") as [String]
|
let pathComp = path.componentsSeparatedByString("/") as [String]
|
||||||
let relCount = relComp.count
|
let relCount = relComp.count
|
||||||
|
@ -232,7 +228,7 @@ class ASFileItem : ASFileNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
let resComp = Array(count: relCount-matchComp, repeatedValue: "..")+pathComp[matchComp..<pathCount]
|
let resComp = Array(count: relCount-matchComp, repeatedValue: "..")+pathComp[matchComp..<pathCount]
|
||||||
return "/".join(resComp)
|
return resComp.joinWithSeparator("/")
|
||||||
}
|
}
|
||||||
override func propertyList(rootPath: String) -> AnyObject {
|
override func propertyList(rootPath: String) -> AnyObject {
|
||||||
return [kTypeKey: kNodeTypeFile, kKindKey: type.rawValue, kPathKey: relativePath(rootPath)]
|
return [kTypeKey: kNodeTypeFile, kKindKey: type.rawValue, kPathKey: relativePath(rootPath)]
|
||||||
|
@ -245,8 +241,12 @@ class ASFileItem : ASFileNode {
|
||||||
}
|
}
|
||||||
override func modDate() -> NSDate? {
|
override func modDate() -> NSDate? {
|
||||||
var date: AnyObject?
|
var date: AnyObject?
|
||||||
url.getResourceValue(&date, forKey: NSURLContentModificationDateKey, error: nil)
|
do {
|
||||||
|
try url.getResourceValue(&date, forKey: NSURLContentModificationDateKey)
|
||||||
return date as? NSDate
|
return date as? NSDate
|
||||||
|
} catch _ {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
override func revision() -> String? {
|
override func revision() -> String? {
|
||||||
let task = NSTask()
|
let task = NSTask()
|
||||||
|
@ -276,11 +276,11 @@ class ASFileTree : NSObject, NSOutlineViewDataSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func setProjectURL(url: NSURL) {
|
func setProjectURL(url: NSURL) {
|
||||||
root.name = url.lastPathComponent!.stringByDeletingPathExtension
|
root.name = url.URLByDeletingPathExtension!.lastPathComponent!
|
||||||
dir = url.URLByDeletingLastPathComponent!.URLByStandardizingPath!
|
dir = url.URLByDeletingLastPathComponent!.URLByStandardizingPath!
|
||||||
}
|
}
|
||||||
func projectPath() -> String {
|
func projectPath() -> String {
|
||||||
return dir.path!.stringByResolvingSymlinksInPath
|
return (dir.path! as NSString).stringByResolvingSymlinksInPath
|
||||||
}
|
}
|
||||||
func apply(closure: (ASFileNode) -> ()) {
|
func apply(closure: (ASFileNode) -> ()) {
|
||||||
root.apply(closure)
|
root.apply(closure)
|
||||||
|
|
|
@ -13,7 +13,7 @@ typealias ASProperties = [String: ASPropertyEntry]
|
||||||
|
|
||||||
extension NSMenu {
|
extension NSMenu {
|
||||||
func addSortedChoices(choices:[ASPropertyEntry], target: AnyObject, selector: Selector) {
|
func addSortedChoices(choices:[ASPropertyEntry], target: AnyObject, selector: Selector) {
|
||||||
for choice in choices.sorted({ $0["name"] < $1["name"] }) {
|
for choice in choices.sort({ $0["name"] < $1["name"] }) {
|
||||||
let item = self.addItemWithTitle(choice["name"]!, action: selector, keyEquivalent: "")
|
let item = self.addItemWithTitle(choice["name"]!, action: selector, keyEquivalent: "")
|
||||||
item?.target = target
|
item?.target = target
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ private func subdirectories(path: String) -> [String] {
|
||||||
let fileManager = NSFileManager.defaultManager()
|
let fileManager = NSFileManager.defaultManager()
|
||||||
var subDirs = [String]()
|
var subDirs = [String]()
|
||||||
var isDir : ObjCBool = false
|
var isDir : ObjCBool = false
|
||||||
if fileManager.fileExistsAtPath(path, isDirectory: &isDir) && isDir {
|
if let items = try? fileManager.contentsOfDirectoryAtPath(path) {
|
||||||
for item in fileManager.contentsOfDirectoryAtPath(path, error: nil) as! [String] {
|
for item in items {
|
||||||
let subPath = path+"/"+item
|
let subPath = path+"/"+item
|
||||||
if fileManager.fileExistsAtPath(subPath, isDirectory: &isDir) && isDir {
|
if fileManager.fileExistsAtPath(subPath, isDirectory: &isDir) && isDir {
|
||||||
subDirs.append(subPath)
|
subDirs.append(subPath)
|
||||||
|
@ -46,7 +46,6 @@ class ASHardware {
|
||||||
// Gather hardware directories
|
// Gather hardware directories
|
||||||
//
|
//
|
||||||
let userDefaults = NSUserDefaults.standardUserDefaults()
|
let userDefaults = NSUserDefaults.standardUserDefaults()
|
||||||
let fileManager = NSFileManager.defaultManager()
|
|
||||||
if let arduinoPath = userDefaults.stringForKey("Arduino") {
|
if let arduinoPath = userDefaults.stringForKey("Arduino") {
|
||||||
let arduinoHardwarePath = arduinoPath + "/Contents/Resources/Java/hardware"
|
let arduinoHardwarePath = arduinoPath + "/Contents/Resources/Java/hardware"
|
||||||
directories += subdirectories(arduinoHardwarePath)
|
directories += subdirectories(arduinoHardwarePath)
|
||||||
|
@ -55,20 +54,21 @@ class ASHardware {
|
||||||
let hardwarePath = sketchDir + "/hardware"
|
let hardwarePath = sketchDir + "/hardware"
|
||||||
directories += subdirectories(hardwarePath)
|
directories += subdirectories(hardwarePath)
|
||||||
}
|
}
|
||||||
let property = NSRegularExpression(pattern: "\\s*(\\w+)\\.(\\S+?)\\s*=\\s*(\\S.*\\S)\\s*", options: nil, error: nil)!
|
let property = try! NSRegularExpression(pattern: "\\s*(\\w+)\\.(\\S+?)\\s*=\\s*(\\S.*\\S)\\s*", options: [])
|
||||||
//
|
//
|
||||||
// Gather board declarations
|
// Gather board declarations
|
||||||
//
|
//
|
||||||
for dir in directories {
|
for dir in directories {
|
||||||
let boardsPath = dir+"/boards.txt"
|
let boardsPath = dir+"/boards.txt"
|
||||||
let provenience = dir.lastPathComponent
|
let provenience = (dir as NSString).lastPathComponent
|
||||||
if let boardsFile = NSString(contentsOfFile: boardsPath, usedEncoding: nil, error: nil) {
|
if let boardsFile = try? NSString(contentsOfFile: boardsPath, usedEncoding: nil) {
|
||||||
var seen = [String: Bool]()
|
var seen = [String: Bool]()
|
||||||
for line in boardsFile.componentsSeparatedByString("\n") as! [NSString] {
|
for line in boardsFile.componentsSeparatedByString("\n") {
|
||||||
if let match = property.firstMatchInString(line as String, options: .Anchored, range: NSMakeRange(0, line.length)) {
|
if let match = property.firstMatchInString(line, options: .Anchored, range: NSMakeRange(0, line.utf16.count)) {
|
||||||
let board = line.substringWithRange(match.rangeAtIndex(1)) as String
|
let nsline = line as NSString
|
||||||
let property = line.substringWithRange(match.rangeAtIndex(2)) as String
|
let board = nsline.substringWithRange(match.rangeAtIndex(1)) as String
|
||||||
let value = line.substringWithRange(match.rangeAtIndex(3)) as String
|
let property = nsline.substringWithRange(match.rangeAtIndex(2)) as String
|
||||||
|
let value = nsline.substringWithRange(match.rangeAtIndex(3)) as String
|
||||||
if seen.updateValue(true, forKey: board) == nil {
|
if seen.updateValue(true, forKey: board) == nil {
|
||||||
boards[board] = ASPropertyEntry()
|
boards[board] = ASPropertyEntry()
|
||||||
boards[board]!["provenience"] = provenience
|
boards[board]!["provenience"] = provenience
|
||||||
|
@ -85,14 +85,15 @@ class ASHardware {
|
||||||
//
|
//
|
||||||
for dir in directories {
|
for dir in directories {
|
||||||
let programmersPath = dir+"/programmers.txt"
|
let programmersPath = dir+"/programmers.txt"
|
||||||
let provenience = dir.lastPathComponent
|
let provenience = (dir as NSString).lastPathComponent
|
||||||
if let programmersFile = NSString(contentsOfFile: programmersPath, usedEncoding: nil, error: nil) {
|
if let programmersFile = try? NSString(contentsOfFile: programmersPath, usedEncoding: nil) {
|
||||||
var seen = [String: Bool]()
|
var seen = [String: Bool]()
|
||||||
for line in programmersFile.componentsSeparatedByString("\n") as! [NSString] {
|
for line in programmersFile.componentsSeparatedByString("\n") {
|
||||||
if let match = property.firstMatchInString(line as String, options: .Anchored, range: NSMakeRange(0, line.length)) {
|
if let match = property.firstMatchInString(line, options: .Anchored, range: NSMakeRange(0, line.utf16.count)) {
|
||||||
let programmer = line.substringWithRange(match.rangeAtIndex(1))
|
let nsline = line as NSString
|
||||||
let property = line.substringWithRange(match.rangeAtIndex(2))
|
let programmer = nsline.substringWithRange(match.rangeAtIndex(1))
|
||||||
let value = line.substringWithRange(match.rangeAtIndex(3))
|
let property = nsline.substringWithRange(match.rangeAtIndex(2))
|
||||||
|
let value = nsline.substringWithRange(match.rangeAtIndex(3))
|
||||||
if seen.updateValue(true, forKey: programmer) == nil {
|
if seen.updateValue(true, forKey: programmer) == nil {
|
||||||
programmers[programmer] = ASPropertyEntry()
|
programmers[programmer] = ASPropertyEntry()
|
||||||
programmers[programmer]!["provenience"] = provenience
|
programmers[programmer]!["provenience"] = provenience
|
||||||
|
@ -117,7 +118,7 @@ class ASHardware {
|
||||||
seen[prop["provenience"]!] = true
|
seen[prop["provenience"]!] = true
|
||||||
}
|
}
|
||||||
var sortedKeys = [String](seen.keys)
|
var sortedKeys = [String](seen.keys)
|
||||||
sortedKeys.sort { $0 < $1 }
|
sortedKeys.sortInPlace { $0 < $1 }
|
||||||
for provenience in sortedKeys {
|
for provenience in sortedKeys {
|
||||||
var subset = [ASPropertyEntry]()
|
var subset = [ASPropertyEntry]()
|
||||||
for prop in choices.values {
|
for prop in choices.values {
|
||||||
|
@ -155,7 +156,6 @@ class ASLibraries : NSObject {
|
||||||
// Gather hardware directories
|
// Gather hardware directories
|
||||||
//
|
//
|
||||||
let userDefaults = NSUserDefaults.standardUserDefaults()
|
let userDefaults = NSUserDefaults.standardUserDefaults()
|
||||||
let fileManager = NSFileManager.defaultManager()
|
|
||||||
for sketchDir in userDefaults.objectForKey("Sketchbooks") as! [String] {
|
for sketchDir in userDefaults.objectForKey("Sketchbooks") as! [String] {
|
||||||
let librariesPath = sketchDir + "/libraries"
|
let librariesPath = sketchDir + "/libraries"
|
||||||
let dirs = subdirectories(librariesPath)
|
let dirs = subdirectories(librariesPath)
|
||||||
|
@ -176,15 +176,15 @@ class ASLibraries : NSObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func addStandardLibrariesToMenu(menu: NSMenu) {
|
func addStandardLibrariesToMenu(menu: NSMenu) {
|
||||||
for (index,lib) in enumerate(standardLib) {
|
for (index,lib) in standardLib.enumerate() {
|
||||||
let menuItem = menu.addItemWithTitle(lib.lastPathComponent, action: "importStandardLibrary:", keyEquivalent: "")
|
let menuItem = menu.addItemWithTitle((lib as NSString).lastPathComponent, action: "importStandardLibrary:", keyEquivalent: "")
|
||||||
menuItem?.target = self
|
menuItem?.target = self
|
||||||
menuItem?.tag = index
|
menuItem?.tag = index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func addContribLibrariesToMenu(menu: NSMenu) {
|
func addContribLibrariesToMenu(menu: NSMenu) {
|
||||||
for (index,lib) in enumerate(contribLib) {
|
for (index,lib) in contribLib.enumerate() {
|
||||||
let menuItem = menu.addItemWithTitle(lib.lastPathComponent, action: "importContribLibrary:", keyEquivalent: "")
|
let menuItem = menu.addItemWithTitle((lib as NSString).lastPathComponent, action: "importContribLibrary:", keyEquivalent: "")
|
||||||
menuItem?.target = self
|
menuItem?.target = self
|
||||||
menuItem?.tag = index
|
menuItem?.tag = index
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ private var keyboardHandler : ACEKeyboardHandler = .Ace
|
||||||
func pushToFront(inout list: [String], front: String) {
|
func pushToFront(inout list: [String], front: String) {
|
||||||
let kMaxRecents = 8
|
let kMaxRecents = 8
|
||||||
|
|
||||||
if let existing = find(list, front) {
|
if let existing = list.indexOf(front) {
|
||||||
if existing == 0 {
|
if existing == 0 {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,7 +48,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
dynamic var port : String = ""
|
dynamic var port : String = ""
|
||||||
var recentBoards = [String]()
|
var recentBoards = [String]()
|
||||||
var recentProgrammers = [String]()
|
var recentProgrammers = [String]()
|
||||||
var logModified = NSDate.distantPast() as! NSDate
|
var logModified = NSDate.distantPast()
|
||||||
var logSize = 0
|
var logSize = 0
|
||||||
var updateLogTimer : NSTimer?
|
var updateLogTimer : NSTimer?
|
||||||
var printingDone : () -> () = {}
|
var printingDone : () -> () = {}
|
||||||
|
@ -93,7 +93,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
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()
|
let nc = NSNotificationCenter.defaultCenter()
|
||||||
themeObserver = nc.addObserverForName(kBindingsKey, object: nil, queue: nil, usingBlock: { (NSNotification) in
|
themeObserver = nc.addObserverForName(kBindingsKey, object: nil, queue: nil, usingBlock: { (NSNotification) in
|
||||||
self.editor?.setKeyboardHandler(keyboardHandler)
|
self.editor?.setKeyboardHandler(keyboardHandler)
|
||||||
})
|
})
|
||||||
|
@ -155,11 +155,14 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
|
|
||||||
func saveCurEditor() {
|
func saveCurEditor() {
|
||||||
if let file = (mainEditor as? ASFileItem) {
|
if let file = (mainEditor as? ASFileItem) {
|
||||||
editor.string().writeToURL(file.url, atomically: true, encoding: NSUTF8StringEncoding, error: nil)
|
do {
|
||||||
|
try editor.string().writeToURL(file.url, atomically: true, encoding: NSUTF8StringEncoding)
|
||||||
|
} catch _ {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func dataOfType(typeName: String, error outError: NSErrorPointer) -> NSData? {
|
override func dataOfType(typeName: String) throws -> NSData {
|
||||||
let data = [kVersionKey: kCurVersion,
|
let data = [kVersionKey: kCurVersion,
|
||||||
kThemeKey: ACEThemeNames.nameForTheme(currentTheme),
|
kThemeKey: ACEThemeNames.nameForTheme(currentTheme),
|
||||||
kFontSizeKey: fontSize,
|
kFontSizeKey: fontSize,
|
||||||
|
@ -170,7 +173,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
kRecentBoardsKey: recentBoards,
|
kRecentBoardsKey: recentBoards,
|
||||||
kRecentProgrammersKey: recentProgrammers
|
kRecentProgrammersKey: recentProgrammers
|
||||||
]
|
]
|
||||||
return NSPropertyListSerialization.dataWithPropertyList(data, format:.XMLFormat_v1_0, options:0, error:nil)
|
return try NSPropertyListSerialization.dataWithPropertyList(data, format:.XMLFormat_v1_0, options:0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateProjectURL() {
|
func updateProjectURL() {
|
||||||
|
@ -178,44 +181,40 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
builder.setProjectURL(fileURL!)
|
builder.setProjectURL(fileURL!)
|
||||||
}
|
}
|
||||||
|
|
||||||
func importProject(url: NSURL, error outError: NSErrorPointer) -> Bool {
|
func importProject(url: NSURL) throws {
|
||||||
let existingProject = url.URLByAppendingPathComponent(url.lastPathComponent!+".avrsackproj")
|
let existingProject = url.URLByAppendingPathComponent(url.lastPathComponent!+".avrsackproj")
|
||||||
if existingProject.checkResourceIsReachableAndReturnError(nil) {
|
if existingProject.checkResourceIsReachableAndReturnError(nil) {
|
||||||
fileURL = existingProject
|
fileURL = existingProject
|
||||||
return readFromURL(existingProject, ofType:"Project", error:outError)
|
try readFromURL(existingProject, ofType:"Project")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
let filesInProject =
|
let filesInProject =
|
||||||
NSFileManager.defaultManager().contentsOfDirectoryAtURL(url, includingPropertiesForKeys: nil,
|
(try NSFileManager.defaultManager().contentsOfDirectoryAtURL(url, includingPropertiesForKeys: nil,
|
||||||
options: .SkipsHiddenFiles, error: nil) as! [NSURL]
|
options: .SkipsHiddenFiles))
|
||||||
updateProjectURL()
|
updateProjectURL()
|
||||||
for file in filesInProject {
|
for file in filesInProject {
|
||||||
files.addFileURL(file)
|
files.addFileURL(file)
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func readFromURL(url: NSURL, ofType typeName: String, error outError: NSErrorPointer) -> Bool {
|
override func readFromURL(url: NSURL, ofType typeName: String) throws {
|
||||||
var success : Bool = false
|
|
||||||
if typeName == "Arduino Source File" {
|
if typeName == "Arduino Source File" {
|
||||||
let projectURL = url.URLByDeletingPathExtension!.URLByAppendingPathExtension("avrsackproj")
|
let projectURL = url.URLByDeletingPathExtension!.URLByAppendingPathExtension("avrsackproj")
|
||||||
success = importProject(url.URLByDeletingLastPathComponent!, error: outError)
|
try importProject(url.URLByDeletingLastPathComponent!)
|
||||||
if success {
|
|
||||||
fileURL = projectURL
|
fileURL = projectURL
|
||||||
success = writeToURL(projectURL, ofType: "Project", forSaveOperation: .SaveAsOperation, originalContentsURL: nil, error: outError)
|
try writeToURL(projectURL, ofType: "Project", forSaveOperation: .SaveAsOperation, originalContentsURL: nil)
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fileURL = url
|
fileURL = url
|
||||||
success = super.readFromURL(url, ofType: typeName, error: outError)
|
try super.readFromURL(url, ofType: typeName)
|
||||||
}
|
}
|
||||||
return success
|
|
||||||
}
|
}
|
||||||
override func readFromData(data: NSData, ofType typeName: String, error outError: NSErrorPointer) -> Bool {
|
override func readFromData(data: NSData, ofType typeName: String) throws {
|
||||||
if typeName != ("Project" as String) {
|
if typeName != ("Project" as String) {
|
||||||
return false
|
throw NSError(domain: "AVRSack", code: 0, userInfo: nil)
|
||||||
}
|
}
|
||||||
updateProjectURL()
|
updateProjectURL()
|
||||||
let projectData =
|
let projectData =
|
||||||
NSPropertyListSerialization.propertyListWithData(data, options:0, format:nil, error:nil) as! NSDictionary
|
(try NSPropertyListSerialization.propertyListWithData(data, options:[], format:nil)) as! NSDictionary
|
||||||
let projectVersion = projectData[kVersionKey] as! Double
|
let projectVersion = projectData[kVersionKey] as! Double
|
||||||
assert(projectVersion <= floor(kCurVersion+1.0), "Project version too new for this app")
|
assert(projectVersion <= floor(kCurVersion+1.0), "Project version too new for this app")
|
||||||
if let themeName = projectData[kThemeKey] as? String {
|
if let themeName = projectData[kThemeKey] as? String {
|
||||||
|
@ -233,8 +232,6 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
recentBoards = (projectData[kRecentBoardsKey] as? [String]) ?? recentBoards
|
recentBoards = (projectData[kRecentBoardsKey] as? [String]) ?? recentBoards
|
||||||
recentProgrammers = (projectData[kRecentProgrammersKey] as? [String]) ?? recentProgrammers
|
recentProgrammers = (projectData[kRecentProgrammersKey] as? [String]) ?? recentProgrammers
|
||||||
updateChangeCount(.ChangeCleared)
|
updateChangeCount(.ChangeCleared)
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func duplicateDocument(sender: AnyObject?) {
|
override func duplicateDocument(sender: AnyObject?) {
|
||||||
|
@ -242,7 +239,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
app.openTemplate(fileURL!.URLByDeletingLastPathComponent!)
|
app.openTemplate(fileURL!.URLByDeletingLastPathComponent!)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateLog(AnyObject?) {
|
func updateLog(_: AnyObject?) {
|
||||||
if let logNode = mainEditor as? ASLogNode {
|
if let logNode = mainEditor as? ASLogNode {
|
||||||
let url = fileURL?.URLByDeletingLastPathComponent?.URLByAppendingPathComponent(logNode.path)
|
let url = fileURL?.URLByDeletingLastPathComponent?.URLByAppendingPathComponent(logNode.path)
|
||||||
if url == nil {
|
if url == nil {
|
||||||
|
@ -250,16 +247,16 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
}
|
}
|
||||||
var modified : AnyObject?
|
var modified : AnyObject?
|
||||||
var size : AnyObject?
|
var size : AnyObject?
|
||||||
if (!url!.getResourceValue(&modified, forKey:NSURLAttributeModificationDateKey, error:nil)) {
|
do {
|
||||||
return
|
try url!.getResourceValue(&modified, forKey:NSURLAttributeModificationDateKey)
|
||||||
}
|
try url!.getResourceValue(&size, forKey:NSURLFileSizeKey)
|
||||||
if (!url!.getResourceValue(&size, forKey:NSURLFileSizeKey, error:nil)) {
|
} catch (_) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modified as! NSDate).compare(logModified) == .OrderedDescending || (size as! Int) != logSize {
|
if (modified as! NSDate).compare(logModified) == .OrderedDescending || (size as! Int) != logSize {
|
||||||
var enc : UInt = 0
|
var enc : UInt = 0
|
||||||
let newText = NSString(contentsOfURL:url!, usedEncoding:&enc, error:nil)
|
let newText = try? NSString(contentsOfURL:url!, usedEncoding:&enc)
|
||||||
editor.setString((newText as? String) ?? "")
|
editor.setString((newText as? String) ?? "")
|
||||||
editor.gotoLine(1000000000, column: 0, animated: true)
|
editor.gotoLine(1000000000, column: 0, animated: true)
|
||||||
logModified = modified as! NSDate
|
logModified = modified as! NSDate
|
||||||
|
@ -274,15 +271,16 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
}
|
}
|
||||||
if let file = (selection as? ASFileItem) {
|
if let file = (selection as? ASFileItem) {
|
||||||
var enc : UInt = 0
|
var enc : UInt = 0
|
||||||
editor.setString(NSString(contentsOfURL:file.url, usedEncoding:&enc, error:nil) as? String ?? "")
|
let contents = try? NSString(contentsOfURL:file.url, usedEncoding:&enc)
|
||||||
|
editor.setString(contents as? String ?? "")
|
||||||
editor.setMode(file.type.aceMode)
|
editor.setMode(file.type.aceMode)
|
||||||
editor.alphaValue = 1.0
|
editor.alphaValue = 1.0
|
||||||
mainEditor = selection
|
mainEditor = selection
|
||||||
} else if let log = (selection as? ASLogNode) {
|
} else if selection is ASLogNode {
|
||||||
editor.setString("")
|
editor.setString("")
|
||||||
editor.setMode(.Text)
|
editor.setMode(.Text)
|
||||||
editor.alphaValue = 0.8
|
editor.alphaValue = 0.8
|
||||||
logModified = NSDate.distantPast() as! NSDate
|
logModified = NSDate.distantPast()
|
||||||
logSize = -1
|
logSize = -1
|
||||||
mainEditor = selection
|
mainEditor = selection
|
||||||
updateLog(nil)
|
updateLog(nil)
|
||||||
|
@ -306,18 +304,20 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
|
|
||||||
// MARK: Printing
|
// MARK: Printing
|
||||||
|
|
||||||
override func printDocumentWithSettings(printSettings: [NSObject : AnyObject], showPrintPanel: Bool, delegate: AnyObject?, didPrintSelector: Selector, contextInfo: UnsafeMutablePointer<Void>) {
|
override func printDocumentWithSettings(printSettings: [String : AnyObject], showPrintPanel: Bool, delegate: AnyObject?, didPrintSelector: Selector, contextInfo: UnsafeMutablePointer<Void>) {
|
||||||
printingDone =
|
printingDone =
|
||||||
{ () -> () in
|
{ () -> () in
|
||||||
InvokeCallback(delegate, didPrintSelector, contextInfo);
|
InvokeCallback(delegate, didPrintSelector, contextInfo);
|
||||||
}
|
}
|
||||||
if let logNode = mainEditor as? ASLogNode {
|
if let logNode = mainEditor as? ASLogNode {
|
||||||
let url = fileURL!.URLByDeletingLastPathComponent?.URLByAppendingPathComponent(logNode.path)
|
|
||||||
var modified : AnyObject?
|
|
||||||
if url?.getResourceValue(&modified, forKey:NSURLAttributeModificationDateKey, error:nil) != nil {
|
|
||||||
printModDate = modified as? NSDate
|
|
||||||
} else {
|
|
||||||
printModDate = nil
|
printModDate = nil
|
||||||
|
if let url = fileURL?.URLByDeletingLastPathComponent?.URLByAppendingPathComponent(logNode.path) {
|
||||||
|
do {
|
||||||
|
var modified : AnyObject?
|
||||||
|
try url.getResourceValue(&modified, forKey:NSURLAttributeModificationDateKey)
|
||||||
|
printModDate = modified as? NSDate
|
||||||
|
} catch (_) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printModDate = mainEditor?.modDate()
|
printModDate = mainEditor?.modDate()
|
||||||
|
@ -329,7 +329,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
}
|
}
|
||||||
|
|
||||||
func printInformation() -> NSPrintInfo! {
|
func printInformation() -> NSPrintInfo! {
|
||||||
var info = printInfo.copy() as! NSPrintInfo
|
let info = printInfo.copy() as! NSPrintInfo
|
||||||
|
|
||||||
//
|
//
|
||||||
// Minimize margins
|
// Minimize margins
|
||||||
|
@ -358,9 +358,13 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
}
|
}
|
||||||
|
|
||||||
func startPrintOperation(printOp: NSPrintOperation) {
|
func startPrintOperation(printOp: NSPrintOperation) {
|
||||||
printOp.jobTitle = mainEditor?.name ??
|
if let editorName = mainEditor?.name {
|
||||||
fileURL?.lastPathComponent?.stringByDeletingPathExtension ??
|
printOp.jobTitle = editorName
|
||||||
"Untitled"
|
} else if let fileName = fileURL?.lastPathComponent {
|
||||||
|
printOp.jobTitle = (fileName as NSString).stringByDeletingLastPathComponent
|
||||||
|
} else {
|
||||||
|
printOp.jobTitle = "Untitled"
|
||||||
|
}
|
||||||
printOp.showsPrintPanel = printShowPanel
|
printOp.showsPrintPanel = printShowPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,10 +418,11 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
if let fileNameStr = mainEditor?.name {
|
if let fileNameStr = mainEditor?.name {
|
||||||
fileNameStr.drawAtPoint(titleAt, withAttributes:titleAttr)
|
fileNameStr.drawAtPoint(titleAt, withAttributes:titleAttr)
|
||||||
}
|
}
|
||||||
if let projectNameStr = fileURL?.lastPathComponent?.stringByDeletingPathExtension {
|
if let projectNameStr = fileURL?.lastPathComponent {
|
||||||
let projectNameSize = projectNameStr.sizeWithAttributes(titleAttr)
|
let projectNameTrimmed = (projectNameStr as NSString).stringByDeletingPathExtension
|
||||||
|
let projectNameSize = projectNameTrimmed.sizeWithAttributes(titleAttr)
|
||||||
titleAt.x = wideBox.origin.x+wideBox.size.width-projectNameSize.width-kXOffset
|
titleAt.x = wideBox.origin.x+wideBox.size.width-projectNameSize.width-kXOffset
|
||||||
projectNameStr.drawAtPoint(titleAt, withAttributes:titleAttr)
|
projectNameTrimmed.drawAtPoint(titleAt, withAttributes:titleAttr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +499,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
|
|
||||||
// MARK: File manipulation
|
// MARK: File manipulation
|
||||||
|
|
||||||
@IBAction func delete(AnyObject) {
|
@IBAction func delete(_: AnyObject) {
|
||||||
let selection = selectedFiles()
|
let selection = selectedFiles()
|
||||||
var name : String
|
var name : String
|
||||||
var ref : String
|
var ref : String
|
||||||
|
@ -511,8 +516,8 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
alert.addButtonWithTitle("Move to Trash")
|
alert.addButtonWithTitle("Move to Trash")
|
||||||
alert.addButtonWithTitle(selection.count == 1 ? "Remove Reference" : "Remove References")
|
alert.addButtonWithTitle(selection.count == 1 ? "Remove Reference" : "Remove References")
|
||||||
alert.addButtonWithTitle("Cancel")
|
alert.addButtonWithTitle("Cancel")
|
||||||
(alert.buttons[0] as! NSButton).keyEquivalent = ""
|
alert.buttons[0].keyEquivalent = ""
|
||||||
(alert.buttons[1] as! NSButton).keyEquivalent = "\r"
|
alert.buttons[1].keyEquivalent = "\r"
|
||||||
alert.beginSheetModalForWindow(outline.window!) { (response) in
|
alert.beginSheetModalForWindow(outline.window!) { (response) in
|
||||||
if response != NSAlertThirdButtonReturn {
|
if response != NSAlertThirdButtonReturn {
|
||||||
if response == NSAlertFirstButtonReturn {
|
if response == NSAlertFirstButtonReturn {
|
||||||
|
@ -521,7 +526,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
self.files.apply { (node) in
|
self.files.apply { (node) in
|
||||||
if let group = node as? ASFileGroup {
|
if let group = node as? ASFileGroup {
|
||||||
for file in selection {
|
for file in selection {
|
||||||
for (groupIdx, groupItem) in enumerate(group.children) {
|
for (groupIdx, groupItem) in group.children.enumerate() {
|
||||||
if file as ASFileNode === groupItem {
|
if file as ASFileNode === groupItem {
|
||||||
group.children.removeAtIndex(groupIdx)
|
group.children.removeAtIndex(groupIdx)
|
||||||
break
|
break
|
||||||
|
@ -537,7 +542,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func add(AnyObject) {
|
@IBAction func add(_: AnyObject) {
|
||||||
let panel = NSOpenPanel()
|
let panel = NSOpenPanel()
|
||||||
panel.canChooseFiles = true
|
panel.canChooseFiles = true
|
||||||
panel.canChooseDirectories = false
|
panel.canChooseDirectories = false
|
||||||
|
@ -546,7 +551,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
panel.delegate = self
|
panel.delegate = self
|
||||||
panel.beginSheetModalForWindow(outline.window!, completionHandler: { (returnCode: Int) -> Void in
|
panel.beginSheetModalForWindow(outline.window!, completionHandler: { (returnCode: Int) -> Void in
|
||||||
if returnCode == NSFileHandlingPanelOKButton {
|
if returnCode == NSFileHandlingPanelOKButton {
|
||||||
for url in panel.URLs as! [NSURL] {
|
for url in panel.URLs {
|
||||||
self.files.addFileURL(url)
|
self.files.addFileURL(url)
|
||||||
}
|
}
|
||||||
self.outline.deselectAll(self)
|
self.outline.deselectAll(self)
|
||||||
|
@ -560,16 +565,19 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
func panel(panel:AnyObject, shouldEnableURL url:NSURL) -> Bool {
|
func panel(panel:AnyObject, shouldEnableURL url:NSURL) -> Bool {
|
||||||
var shouldEnable = true
|
var shouldEnable = true
|
||||||
var resourceID : AnyObject?
|
var resourceID : AnyObject?
|
||||||
url.getResourceValue(&resourceID, forKey:NSURLFileResourceIdentifierKey, error:nil)
|
guard ((try? url.getResourceValue(&resourceID, forKey:NSURLFileResourceIdentifierKey)) != nil) else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
files.apply {(node) in
|
files.apply {(node) in
|
||||||
if let file = node as? ASFileItem {
|
if let file = node as? ASFileItem {
|
||||||
var thisID : AnyObject?
|
var thisID : AnyObject?
|
||||||
file.url.getResourceValue(&thisID, forKey:NSURLFileResourceIdentifierKey, error:nil)
|
if (try? file.url.getResourceValue(&thisID, forKey:NSURLFileResourceIdentifierKey)) != nil {
|
||||||
if thisID != nil && resourceID!.isEqual(thisID!) {
|
if thisID != nil && resourceID!.isEqual(thisID!) {
|
||||||
shouldEnable = false
|
shouldEnable = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return shouldEnable
|
return shouldEnable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,15 +622,18 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
prefix + " Created: " + dateFmt.stringFromDate(NSDate()) + "\n" +
|
prefix + " Created: " + dateFmt.stringFromDate(NSDate()) + "\n" +
|
||||||
lastPfx + "\n\n"
|
lastPfx + "\n\n"
|
||||||
}
|
}
|
||||||
header.writeToURL(url, atomically: true, encoding: NSUTF8StringEncoding, error: nil)
|
do {
|
||||||
|
try header.writeToURL(url, atomically: true, encoding: NSUTF8StringEncoding)
|
||||||
|
} catch _ {
|
||||||
|
}
|
||||||
files.addFileURL(url)
|
files.addFileURL(url)
|
||||||
outline.reloadData()
|
outline.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func createFile(AnyObject) {
|
@IBAction func createFile(_: AnyObject) {
|
||||||
let savePanel = NSSavePanel()
|
let savePanel = NSSavePanel()
|
||||||
savePanel.allowedFileTypes =
|
savePanel.allowedFileTypes =
|
||||||
[kUTTypeCSource, kUTTypeCHeader, kUTTypeCPlusPlusSource, kUTTypeCSource,
|
[kUTTypeCSource as String, kUTTypeCHeader as String, kUTTypeCPlusPlusSource as String, kUTTypeAssemblyLanguageSource as String,
|
||||||
"public.assembly-source", "net.daringfireball.markdown"]
|
"public.assembly-source", "net.daringfireball.markdown"]
|
||||||
savePanel.beginSheetModalForWindow(outline.window!, completionHandler: { (returnCode) -> Void in
|
savePanel.beginSheetModalForWindow(outline.window!, completionHandler: { (returnCode) -> Void in
|
||||||
if returnCode == NSFileHandlingPanelOKButton {
|
if returnCode == NSFileHandlingPanelOKButton {
|
||||||
|
@ -634,14 +645,16 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
func importLibrary(lib: String) {
|
func importLibrary(lib: String) {
|
||||||
var includes = ""
|
var includes = ""
|
||||||
let fileManager = NSFileManager.defaultManager()
|
let fileManager = NSFileManager.defaultManager()
|
||||||
for file in fileManager.contentsOfDirectoryAtPath(lib, error: nil) as! [String] {
|
if let files = try? fileManager.contentsOfDirectoryAtPath(lib) {
|
||||||
|
for file in files {
|
||||||
if file.hasSuffix(".h") {
|
if file.hasSuffix(".h") {
|
||||||
includes += "#include <\(file)>\n"
|
includes += "#include <\(file)>\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var text = editor.string() as NSString
|
}
|
||||||
|
let text = editor.string() as NSString
|
||||||
var insert = NSMakeRange(text.length, 0)
|
var insert = NSMakeRange(text.length, 0)
|
||||||
let postHeaderComments = NSRegularExpression(pattern: "((?:\\s+|/\\*.*?\\*/|//.*?\\n)*)(.*?\\n)", options: .DotMatchesLineSeparators, error: nil)!
|
let postHeaderComments = try! NSRegularExpression(pattern: "((?:\\s+|/\\*.*?\\*/|//.*?\\n)*)(.*?\\n)", options: .DotMatchesLineSeparators)
|
||||||
if let match = postHeaderComments.firstMatchInString(text as String, options:.Anchored, range:NSMakeRange(0, text.length)) {
|
if let match = postHeaderComments.firstMatchInString(text as String, options:.Anchored, range:NSMakeRange(0, text.length)) {
|
||||||
let range = match.rangeAtIndex(2)
|
let range = match.rangeAtIndex(2)
|
||||||
insert.location = range.location
|
insert.location = range.location
|
||||||
|
@ -691,12 +704,12 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
return super.validateUserInterfaceItem(anItem)
|
return super.validateUserInterfaceItem(anItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func makeTextLarger(AnyObject) {
|
@IBAction func makeTextLarger(_: AnyObject) {
|
||||||
fontSize += 1
|
fontSize += 1
|
||||||
editor.setFontSize(fontSize)
|
editor.setFontSize(fontSize)
|
||||||
updateChangeCount(.ChangeDone)
|
updateChangeCount(.ChangeDone)
|
||||||
}
|
}
|
||||||
@IBAction func makeTextSmaller(AnyObject) {
|
@IBAction func makeTextSmaller(_: AnyObject) {
|
||||||
if fontSize > 6 {
|
if fontSize > 6 {
|
||||||
fontSize -= 1
|
fontSize -= 1
|
||||||
editor.setFontSize(fontSize)
|
editor.setFontSize(fontSize)
|
||||||
|
@ -715,44 +728,47 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var enc : UInt = 0
|
var enc : UInt = 0
|
||||||
auxEdit.setString(NSString(contentsOfURL:url!, usedEncoding:&enc, error:nil) as? String ?? "")
|
let contents = try? NSString(contentsOfURL:url!, usedEncoding:&enc)
|
||||||
|
auxEdit.setString(contents as? String ?? "")
|
||||||
editor.setMode(.Text)
|
editor.setMode(.Text)
|
||||||
editor.alphaValue = 1.0
|
editor.alphaValue = 1.0
|
||||||
}
|
}
|
||||||
let buildLog = auxEdit.string().componentsSeparatedByString("\n")
|
let buildLog = auxEdit.string().componentsSeparatedByString("\n")
|
||||||
let issueRe = NSRegularExpression(pattern: "(\\S+?):(\\d+):.*", options: nil, error: nil)!
|
let issueRe = try! NSRegularExpression(pattern: "(\\S+?):(\\d+):.*", options: [])
|
||||||
|
|
||||||
currentIssueLine += direction
|
currentIssueLine += direction
|
||||||
while currentIssueLine > -1 && currentIssueLine < buildLog.count {
|
while currentIssueLine > -1 && currentIssueLine < buildLog.count {
|
||||||
let line = buildLog[currentIssueLine]
|
let line = buildLog[currentIssueLine]
|
||||||
let range = NSMakeRange(0, count(line.utf16))
|
let range = NSMakeRange(0, line.utf16.count)
|
||||||
if let match = issueRe.firstMatchInString(line, options:.Anchored, range:range) {
|
if let match = issueRe.firstMatchInString(line, options:.Anchored, range:range) {
|
||||||
let file = match.rangeAtIndex(1)
|
let file = match.rangeAtIndex(1)
|
||||||
let lineTxt = match.rangeAtIndex(2)
|
let lineTxt = match.rangeAtIndex(2)
|
||||||
let nsline = line as NSString
|
let nsline = line as NSString
|
||||||
let lineNo = nsline.substringWithRange(lineTxt).toInt()!
|
let lineNo = Int(nsline.substringWithRange(lineTxt))!
|
||||||
let fileName = nsline.substringWithRange(file) as NSString
|
let fileName = nsline.substringWithRange(file) as NSString
|
||||||
let fileURL : NSURL
|
let fileURL : NSURL
|
||||||
|
|
||||||
if fileName.hasPrefix("../../") {
|
if fileName.hasPrefix("../../") {
|
||||||
fileURL = files.dir.URLByAppendingPathComponent(fileName.substringFromIndex(6))
|
fileURL = files.dir.URLByAppendingPathComponent(fileName.substringFromIndex(6))
|
||||||
} else {
|
} else {
|
||||||
fileURL = NSURL(fileURLWithPath:fileName as String)!.URLByStandardizingPath!
|
fileURL = NSURL(fileURLWithPath:fileName as String).URLByStandardizingPath!
|
||||||
}
|
}
|
||||||
|
|
||||||
jumpingToIssue = true
|
jumpingToIssue = true
|
||||||
var resourceID : AnyObject?
|
var resourceID : AnyObject?
|
||||||
fileURL.getResourceValue(&resourceID, forKey:NSURLFileResourceIdentifierKey, error:nil)
|
if (try? fileURL.getResourceValue(&resourceID, forKey:NSURLFileResourceIdentifierKey)) != nil && resourceID != nil {
|
||||||
files.apply {(node) in
|
files.apply {(node) in
|
||||||
if let file = node as? ASFileItem {
|
if let file = node as? ASFileItem {
|
||||||
var thisID : AnyObject?
|
var thisID : AnyObject?
|
||||||
file.url.getResourceValue(&thisID, forKey:NSURLFileResourceIdentifierKey, error:nil)
|
if (try? file.url.getResourceValue(&thisID, forKey:NSURLFileResourceIdentifierKey)) != nil {
|
||||||
if thisID != nil && resourceID!.isEqual(thisID!) {
|
if thisID != nil && resourceID!.isEqual(thisID!) {
|
||||||
self.selectNodeInOutline(node)
|
self.selectNodeInOutline(node)
|
||||||
self.editor.gotoLine(lineNo, column:0, animated:true)
|
self.editor.gotoLine(lineNo, column:0, animated:true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
jumpingToIssue = false
|
jumpingToIssue = false
|
||||||
|
|
||||||
auxEdit.gotoLine(currentIssueLine+1, column:0, animated: true)
|
auxEdit.gotoLine(currentIssueLine+1, column:0, animated: true)
|
||||||
|
@ -764,12 +780,12 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
|
|
||||||
// MARK: Build / Upload
|
// MARK: Build / Upload
|
||||||
|
|
||||||
@IBAction func buildProject(AnyObject) {
|
@IBAction func buildProject(_: AnyObject) {
|
||||||
selectNodeInOutline(files.buildLog)
|
selectNodeInOutline(files.buildLog)
|
||||||
builder.buildProject(board, files: files)
|
builder.buildProject(board, files: files)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func cleanProject(AnyObject) {
|
@IBAction func cleanProject(_: AnyObject) {
|
||||||
builder.cleanProject()
|
builder.cleanProject()
|
||||||
selectNodeInOutline(files.buildLog)
|
selectNodeInOutline(files.buildLog)
|
||||||
}
|
}
|
||||||
|
@ -808,11 +824,11 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
if prop["name"] == newBoard {
|
if prop["name"] == newBoard {
|
||||||
board = ident
|
board = ident
|
||||||
|
|
||||||
pushToFront(&recentBoards, board)
|
pushToFront(&recentBoards, front: board)
|
||||||
|
|
||||||
let userDefaults = NSUserDefaults.standardUserDefaults()
|
let userDefaults = NSUserDefaults.standardUserDefaults()
|
||||||
var globalBoards = userDefaults.objectForKey(kRecentBoardsKey) as! [String]
|
var globalBoards = userDefaults.objectForKey(kRecentBoardsKey) as! [String]
|
||||||
pushToFront(&globalBoards, board)
|
pushToFront(&globalBoards, front: board)
|
||||||
userDefaults.setObject(globalBoards, forKey: kRecentBoardsKey)
|
userDefaults.setObject(globalBoards, forKey: kRecentBoardsKey)
|
||||||
|
|
||||||
updateChangeCount(.ChangeDone)
|
updateChangeCount(.ChangeDone)
|
||||||
|
@ -838,11 +854,11 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
if prop["name"] == newProg {
|
if prop["name"] == newProg {
|
||||||
programmer = ident
|
programmer = ident
|
||||||
|
|
||||||
pushToFront(&recentProgrammers, programmer)
|
pushToFront(&recentProgrammers, front: programmer)
|
||||||
|
|
||||||
let userDefaults = NSUserDefaults.standardUserDefaults()
|
let userDefaults = NSUserDefaults.standardUserDefaults()
|
||||||
var globalProgs = userDefaults.objectForKey(kRecentProgrammersKey) as! [String]
|
var globalProgs = userDefaults.objectForKey(kRecentProgrammersKey) as! [String]
|
||||||
pushToFront(&globalProgs, programmer)
|
pushToFront(&globalProgs, front: programmer)
|
||||||
userDefaults.setObject(globalProgs, forKey: kRecentProgrammersKey)
|
userDefaults.setObject(globalProgs, forKey: kRecentProgrammersKey)
|
||||||
|
|
||||||
updateChangeCount(.ChangeDone)
|
updateChangeCount(.ChangeDone)
|
||||||
|
@ -879,7 +895,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
|
|
||||||
var hasValidPort : Bool {
|
var hasValidPort : Bool {
|
||||||
get {
|
get {
|
||||||
return contains(ASSerial.ports() as! [String], port)
|
return ASSerial.ports().contains(port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class func keyPathsForValuesAffectingHasValidPort() -> NSSet {
|
class func keyPathsForValuesAffectingHasValidPort() -> NSSet {
|
||||||
|
|
|
@ -19,7 +19,7 @@ extern NSString * kASSerialPortsChanged;
|
||||||
@interface ASSerial : NSObject
|
@interface ASSerial : NSObject
|
||||||
|
|
||||||
+ (NSString *) fileNameForPort:(NSString *)port;
|
+ (NSString *) fileNameForPort:(NSString *)port;
|
||||||
+ (NSArray *) ports;
|
+ (NSArray<NSString *> *) ports;
|
||||||
+ (NSFileHandle *)openPort:(NSString *) port withSpeed:(int)speed;
|
+ (NSFileHandle *)openPort:(NSString *) port withSpeed:(int)speed;
|
||||||
+ (void)restorePort:(int)fileDescriptor;
|
+ (void)restorePort:(int)fileDescriptor;
|
||||||
+ (void)closePort:(int)fileDescriptor;
|
+ (void)closePort:(int)fileDescriptor;
|
||||||
|
|
|
@ -42,7 +42,7 @@ NSString * kASSerialPortsChanged = @"PortsChanged";
|
||||||
dispatch_resume(watchSlashDev);
|
dispatch_resume(watchSlashDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)ports {
|
+ (NSArray<NSString *> *)ports {
|
||||||
NSMutableArray * cuPorts = [NSMutableArray array];
|
NSMutableArray * cuPorts = [NSMutableArray array];
|
||||||
for (NSString * port in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/dev" error: nil]) {
|
for (NSString * port in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/dev" error: nil]) {
|
||||||
if ([[port substringToIndex:2] isEqualToString:@"cu"])
|
if ([[port substringToIndex:2] isEqualToString:@"cu"])
|
||||||
|
|
|
@ -103,7 +103,7 @@ class ASSerialWin: NSWindowController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var nc = NSNotificationCenter.defaultCenter()
|
let nc = NSNotificationCenter.defaultCenter()
|
||||||
serialObserver = nc.addObserverForName(kASSerialPortsChanged, object: nil, queue: nil, usingBlock: { (NSNotification) in
|
serialObserver = nc.addObserverForName(kASSerialPortsChanged, object: nil, queue: nil, usingBlock: { (NSNotification) in
|
||||||
self.willChangeValueForKey("hasValidPort")
|
self.willChangeValueForKey("hasValidPort")
|
||||||
self.didChangeValueForKey("hasValidPort")
|
self.didChangeValueForKey("hasValidPort")
|
||||||
|
@ -118,7 +118,7 @@ class ASSerialWin: NSWindowController {
|
||||||
})
|
})
|
||||||
termination = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification,
|
termination = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification,
|
||||||
object: nil, queue: nil, usingBlock:
|
object: nil, queue: nil, usingBlock:
|
||||||
{ (notification: NSNotification!) in
|
{ (notification: NSNotification) in
|
||||||
if notification.object as? NSTask == self.task {
|
if notification.object as? NSTask == self.task {
|
||||||
self.task = nil
|
self.task = nil
|
||||||
self.portHandle = nil
|
self.portHandle = nil
|
||||||
|
@ -174,7 +174,7 @@ class ASSerialWin: NSWindowController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func sendInput(AnyObject) {
|
@IBAction func sendInput(_: AnyObject) {
|
||||||
let line = inputLine.stringValue + (sendCR ? "\r" : "") + (sendLF ? "\n" : "")
|
let line = inputLine.stringValue + (sendCR ? "\r" : "") + (sendLF ? "\n" : "")
|
||||||
let data = line.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!
|
let data = line.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!
|
||||||
portHandle?.writeData(data)
|
portHandle?.writeData(data)
|
||||||
|
@ -191,7 +191,7 @@ class ASSerialWin: NSWindowController {
|
||||||
installReader((task.standardOutput as? NSPipe)?.fileHandleForReading)
|
installReader((task.standardOutput as? NSPipe)?.fileHandleForReading)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func connect(AnyObject) {
|
@IBAction func connect(_: AnyObject) {
|
||||||
shouldReconnect = false
|
shouldReconnect = false
|
||||||
if task != nil {
|
if task != nil {
|
||||||
task!.interrupt()
|
task!.interrupt()
|
||||||
|
@ -227,7 +227,7 @@ class ASSerialWin: NSWindowController {
|
||||||
}
|
}
|
||||||
var hasValidPort : Bool {
|
var hasValidPort : Bool {
|
||||||
get {
|
get {
|
||||||
return contains(ASSerial.ports() as! [String], port)
|
return ASSerial.ports().contains(port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,13 +262,13 @@ class ASSerialWin: NSWindowController {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func makeTextLarger(AnyObject) {
|
@IBAction func makeTextLarger(_: AnyObject) {
|
||||||
fontSize += 1
|
fontSize += 1
|
||||||
logView.setFontSize(fontSize)
|
logView.setFontSize(fontSize)
|
||||||
portDefaults["FontSize"] = fontSize
|
portDefaults["FontSize"] = fontSize
|
||||||
updatePortDefaults()
|
updatePortDefaults()
|
||||||
}
|
}
|
||||||
@IBAction func makeTextSmaller(AnyObject) {
|
@IBAction func makeTextSmaller(_: AnyObject) {
|
||||||
if fontSize > 6 {
|
if fontSize > 6 {
|
||||||
fontSize -= 1
|
fontSize -= 1
|
||||||
logView.setFontSize(fontSize)
|
logView.setFontSize(fontSize)
|
||||||
|
@ -285,14 +285,17 @@ class ASSerialWin: NSWindowController {
|
||||||
userDefaults.setObject(serialDefaults, forKey:"SerialDefaults")
|
userDefaults.setObject(serialDefaults, forKey:"SerialDefaults")
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func saveDocument(AnyObject) {
|
@IBAction func saveDocument(_: AnyObject) {
|
||||||
let savePanel = NSSavePanel()
|
let savePanel = NSSavePanel()
|
||||||
savePanel.allowedFileTypes = ["log"]
|
savePanel.allowedFileTypes = ["log"]
|
||||||
savePanel.allowsOtherFileTypes = true
|
savePanel.allowsOtherFileTypes = true
|
||||||
savePanel.extensionHidden = false
|
savePanel.extensionHidden = false
|
||||||
savePanel.beginSheetModalForWindow(window!, completionHandler: { (returnCode) -> Void in
|
savePanel.beginSheetModalForWindow(window!, completionHandler: { (returnCode) -> Void in
|
||||||
if returnCode == NSFileHandlingPanelOKButton {
|
if returnCode == NSFileHandlingPanelOKButton {
|
||||||
self.serialData.writeToURL(savePanel.URL!, atomically:false, encoding:NSUTF8StringEncoding, error:nil)
|
do {
|
||||||
|
try self.serialData.writeToURL(savePanel.URL!, atomically:false, encoding:NSUTF8StringEncoding)
|
||||||
|
} catch _ {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,14 @@ class ASSketchBook {
|
||||||
class func findSketch(path: String) -> SketchBookItem {
|
class func findSketch(path: String) -> SketchBookItem {
|
||||||
let fileManager = NSFileManager.defaultManager()
|
let fileManager = NSFileManager.defaultManager()
|
||||||
var inoSketch = SketchBookItem.Nothing
|
var inoSketch = SketchBookItem.Nothing
|
||||||
let contents = fileManager.contentsOfDirectoryAtPath(path, error: nil) as! [String]
|
let contents = (try! fileManager.contentsOfDirectoryAtPath(path))
|
||||||
|
let nspath = path as NSString
|
||||||
for item in contents {
|
for item in contents {
|
||||||
switch item.pathExtension {
|
switch (item as NSString).pathExtension {
|
||||||
case "avrsackproj":
|
case "avrsackproj":
|
||||||
return .Sketch(path.lastPathComponent, path.stringByAppendingPathComponent(item))
|
return .Sketch(nspath.lastPathComponent, nspath.stringByAppendingPathComponent(item))
|
||||||
case "ino":
|
case "ino":
|
||||||
inoSketch = .Sketch(path.lastPathComponent, path.stringByAppendingPathComponent(item))
|
inoSketch = .Sketch(nspath.lastPathComponent, nspath.stringByAppendingPathComponent(item))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -34,7 +35,8 @@ class ASSketchBook {
|
||||||
|
|
||||||
private class func enumerateSketches(path: String) -> SketchBookItem {
|
private class func enumerateSketches(path: String) -> SketchBookItem {
|
||||||
let fileManager = NSFileManager.defaultManager()
|
let fileManager = NSFileManager.defaultManager()
|
||||||
let contents = fileManager.contentsOfDirectoryAtPath(path, error: nil) as! [String]
|
let contents = (try! fileManager.contentsOfDirectoryAtPath(path))
|
||||||
|
let nspath = path as NSString
|
||||||
let sketch = findSketch(path)
|
let sketch = findSketch(path)
|
||||||
switch sketch {
|
switch sketch {
|
||||||
case .Sketch:
|
case .Sketch:
|
||||||
|
@ -44,7 +46,7 @@ class ASSketchBook {
|
||||||
}
|
}
|
||||||
var sketches = [SketchBookItem]()
|
var sketches = [SketchBookItem]()
|
||||||
for item in contents {
|
for item in contents {
|
||||||
let subpath = path.stringByAppendingPathComponent(item)
|
let subpath = nspath.stringByAppendingPathComponent(item)
|
||||||
var isDir : ObjCBool = false
|
var isDir : ObjCBool = false
|
||||||
if fileManager.fileExistsAtPath(subpath, isDirectory: &isDir) && isDir {
|
if fileManager.fileExistsAtPath(subpath, isDirectory: &isDir) && isDir {
|
||||||
let subEnum = enumerateSketches(subpath)
|
let subEnum = enumerateSketches(subpath)
|
||||||
|
@ -56,7 +58,7 @@ class ASSketchBook {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sketches.sort({ (a: SketchBookItem, b: SketchBookItem) -> Bool in
|
sketches.sortInPlace({ (a: SketchBookItem, b: SketchBookItem) -> Bool in
|
||||||
var itemA : String = ""
|
var itemA : String = ""
|
||||||
switch a {
|
switch a {
|
||||||
case .Sketch(let item, _):
|
case .Sketch(let item, _):
|
||||||
|
@ -75,7 +77,7 @@ class ASSketchBook {
|
||||||
return itemA < ""
|
return itemA < ""
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return sketches.count > 0 ? .SketchDir(path.lastPathComponent, sketches) : .Nothing
|
return sketches.count > 0 ? .SketchDir(nspath.lastPathComponent, sketches) : .Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
class func appendSketchesToMenu(menu: NSMenu, target: AnyObject, action: Selector, sketchList: [SketchBookItem], inout sketches: [String]) {
|
class func appendSketchesToMenu(menu: NSMenu, target: AnyObject, action: Selector, sketchList: [SketchBookItem], inout sketches: [String]) {
|
||||||
|
@ -100,7 +102,7 @@ class ASSketchBook {
|
||||||
|
|
||||||
class func addSketches(menu: NSMenu, target: AnyObject, action: Selector, path: String, inout sketches: [String]) {
|
class func addSketches(menu: NSMenu, target: AnyObject, action: Selector, path: String, inout sketches: [String]) {
|
||||||
switch enumerateSketches(path) {
|
switch enumerateSketches(path) {
|
||||||
case .SketchDir(let item, let sketchList):
|
case .SketchDir(_, let sketchList):
|
||||||
appendSketchesToMenu(menu, target: target, action: action, sketchList: sketchList, sketches: &sketches)
|
appendSketchesToMenu(menu, target: target, action: action, sketchList: sketchList, sketches: &sketches)
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|
Loading…
Reference in New Issue
Block a user