Address simple Fix-it's

This commit is contained in:
Matthias Neeracher 2016-11-13 12:03:51 +01:00 committed by Matthias Neeracher
parent b013142cac
commit 25f904b606
15 changed files with 453 additions and 433 deletions

View File

@ -24,6 +24,7 @@
95539B681A3E7EAF00D8595C /* ASSerial.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95539B671A3E7EAF00D8595C /* ASSerial.mm */; }; 95539B681A3E7EAF00D8595C /* ASSerial.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95539B671A3E7EAF00D8595C /* ASSerial.mm */; };
955EFECB1AFF1A8400D34967 /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 955EFEC91AFF1A8400D34967 /* Help */; }; 955EFECB1AFF1A8400D34967 /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 955EFEC91AFF1A8400D34967 /* Help */; };
956005F41A4EF79D00327007 /* ASSerialWin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 956005F21A4EF79D00327007 /* ASSerialWin.swift */; }; 956005F41A4EF79D00327007 /* ASSerialWin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 956005F21A4EF79D00327007 /* ASSerialWin.swift */; };
95A1814B1DD86D6A00E9127B /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95A1814A1DD86D6A00E9127B /* WebKit.framework */; };
95A7C6401A38914300EF1963 /* ASPreferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 95A7C63E1A38914300EF1963 /* ASPreferences.xib */; }; 95A7C6401A38914300EF1963 /* ASPreferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 95A7C63E1A38914300EF1963 /* ASPreferences.xib */; };
95A7C6461A3894C900EF1963 /* ASPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A7C6451A3894C900EF1963 /* ASPreferences.swift */; }; 95A7C6461A3894C900EF1963 /* ASPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A7C6451A3894C900EF1963 /* ASPreferences.swift */; };
95B83FCE1BF9724100B46A87 /* ACEView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95B83FC91BF9715D00B46A87 /* ACEView.framework */; }; 95B83FCE1BF9724100B46A87 /* ACEView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95B83FC91BF9715D00B46A87 /* ACEView.framework */; };
@ -109,6 +110,7 @@
955EFECA1AFF1A8400D34967 /* Base */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Base; path = Base.lproj/Help; sourceTree = "<group>"; }; 955EFECA1AFF1A8400D34967 /* Base */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Base; path = Base.lproj/Help; sourceTree = "<group>"; };
956005F21A4EF79D00327007 /* ASSerialWin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASSerialWin.swift; sourceTree = "<group>"; }; 956005F21A4EF79D00327007 /* ASSerialWin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASSerialWin.swift; sourceTree = "<group>"; };
958D76811A17DA1C00917D96 /* AVRsack-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AVRsack-Bridging-Header.h"; sourceTree = "<group>"; }; 958D76811A17DA1C00917D96 /* AVRsack-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AVRsack-Bridging-Header.h"; sourceTree = "<group>"; };
95A1814A1DD86D6A00E9127B /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = ../../../../System/Library/Frameworks/WebKit.framework; sourceTree = "<group>"; };
95A7C63F1A38914300EF1963 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ASPreferences.xib; sourceTree = "<group>"; }; 95A7C63F1A38914300EF1963 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ASPreferences.xib; sourceTree = "<group>"; };
95A7C6451A3894C900EF1963 /* ASPreferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASPreferences.swift; sourceTree = "<group>"; }; 95A7C6451A3894C900EF1963 /* ASPreferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASPreferences.swift; sourceTree = "<group>"; };
95BF80EA1A185C9E0004A693 /* ASFileTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASFileTree.swift; sourceTree = "<group>"; }; 95BF80EA1A185C9E0004A693 /* ASFileTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASFileTree.swift; sourceTree = "<group>"; };
@ -130,6 +132,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
95A1814B1DD86D6A00E9127B /* WebKit.framework in Frameworks */,
95B83FCE1BF9724100B46A87 /* ACEView.framework in Frameworks */, 95B83FCE1BF9724100B46A87 /* ACEView.framework in Frameworks */,
95EA32651A17BA8C00F66EB0 /* Cocoa.framework in Frameworks */, 95EA32651A17BA8C00F66EB0 /* Cocoa.framework in Frameworks */,
); );
@ -152,6 +155,7 @@
9501D7FE1A17025C0034C530 /* AVRsack */, 9501D7FE1A17025C0034C530 /* AVRsack */,
9501D8141A17025C0034C530 /* AVRsackTests */, 9501D8141A17025C0034C530 /* AVRsackTests */,
9501D7FD1A17025C0034C530 /* Products */, 9501D7FD1A17025C0034C530 /* Products */,
95A181491DD86D6A00E9127B /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -223,6 +227,14 @@
name = Source; name = Source;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
95A181491DD86D6A00E9127B /* Frameworks */ = {
isa = PBXGroup;
children = (
95A1814A1DD86D6A00E9127B /* WebKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
95B83FC31BF9715C00B46A87 /* Products */ = { 95B83FC31BF9715C00B46A87 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -310,7 +322,7 @@
attributes = { attributes = {
LastSwiftMigration = 0710; LastSwiftMigration = 0710;
LastSwiftUpdateCheck = 0700; LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0630; LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Aere Perennius"; ORGANIZATIONNAME = "Aere Perennius";
TargetAttributes = { TargetAttributes = {
9501D7FB1A17025C0034C530 = { 9501D7FB1A17025C0034C530 = {
@ -500,15 +512,19 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1", "DEBUG=1",
@ -521,7 +537,6 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
@ -542,8 +557,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
@ -552,13 +569,13 @@
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
}; };
@ -573,11 +590,11 @@
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
INFOPLIST_FILE = AVRsack/Info.plist; INFOPLIST_FILE = AVRsack/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.aereperennius.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx10.11;
SWIFT_OBJC_BRIDGING_HEADER = "AVRsack/AVRsack-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "AVRsack/AVRsack-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 2.3; SWIFT_VERSION = 3.0;
}; };
name = Debug; name = Debug;
}; };
@ -590,10 +607,11 @@
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
INFOPLIST_FILE = AVRsack/Info.plist; INFOPLIST_FILE = AVRsack/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.aereperennius.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx10.11;
SWIFT_OBJC_BRIDGING_HEADER = "AVRsack/AVRsack-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "AVRsack/AVRsack-Bridging-Header.h";
SWIFT_VERSION = 2.3; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
}; };
name = Release; name = Release;
}; };
@ -612,8 +630,9 @@
); );
INFOPLIST_FILE = AVRsackTests/Info.plist; INFOPLIST_FILE = AVRsackTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.aereperennius.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 2.3; SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AVRsack.app/Contents/MacOS/AVRsack"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AVRsack.app/Contents/MacOS/AVRsack";
}; };
name = Debug; name = Debug;
@ -629,8 +648,10 @@
); );
INFOPLIST_FILE = AVRsackTests/Info.plist; INFOPLIST_FILE = AVRsackTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.aereperennius.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 2.3; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AVRsack.app/Contents/MacOS/AVRsack"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AVRsack.app/Contents/MacOS/AVRsack";
}; };
name = Release; name = Release;

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0700" LastUpgradeVersion = "0800"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@ -11,8 +11,7 @@
buildForRunning = "YES" buildForRunning = "YES"
buildForProfiling = "YES" buildForProfiling = "YES"
buildForArchiving = "YES" buildForArchiving = "YES"
buildForAnalyzing = "YES" buildForAnalyzing = "YES">
hideIssues = "NO">
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "9501D7FB1A17025C0034C530" BlueprintIdentifier = "9501D7FB1A17025C0034C530"
@ -26,8 +25,7 @@
buildForRunning = "YES" buildForRunning = "YES"
buildForProfiling = "NO" buildForProfiling = "NO"
buildForArchiving = "NO" buildForArchiving = "NO"
buildForAnalyzing = "YES" buildForAnalyzing = "YES">
hideIssues = "NO">
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "9501D8101A17025C0034C530" BlueprintIdentifier = "9501D8101A17025C0034C530"

View File

@ -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 ACEThemeNames.themeNames() .enumerate() { for (themeIdx, theme) in ACEThemeNames.themeNames() .enumerated() {
if themeName == theme { if themeName == theme {
return ACETheme(rawValue: UInt(themeIdx)) return ACETheme(rawValue: UInt(themeIdx))
} }
@ -19,11 +19,11 @@ extension ACEView {
} }
class func handlerIdByName(handlerName: String) -> ACEKeyboardHandler? { class func handlerIdByName(handlerName: String) -> ACEKeyboardHandler? {
for (handlerIdx, handler) in ACEKeyboardHandlerNames.humanKeyboardHandlerNames().enumerate() { for (handlerIdx, handler) in ACEKeyboardHandlerNames.humanKeyboardHandlerNames().enumerated() {
if handlerName == handler { if handlerName == handler {
return ACEKeyboardHandler(rawValue: UInt(handlerIdx))! return ACEKeyboardHandler(rawValue: UInt(handlerIdx))!
} }
} }
return nil return nil
} }
} }

View File

@ -18,86 +18,86 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
var examples = [String]() var examples = [String]()
func hasDocument() -> Bool { func hasDocument() -> Bool {
return NSDocumentController.sharedDocumentController().currentDocument != nil return NSDocumentController.shared().currentDocument != nil
} }
func applicationWillFinishLaunching(notification: NSNotification) { func applicationWillFinishLaunching(_ notification: Notification) {
// //
// Retrieve static app defaults // Retrieve static app defaults
// //
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
let workSpace = NSWorkspace.sharedWorkspace() let workSpace = NSWorkspace.shared()
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
let appDefaultsURL = NSBundle.mainBundle().URLForResource("Defaults", withExtension: "plist")! let appDefaultsURL = Bundle.main.url(forResource: "Defaults", withExtension: "plist")!
var appDefaults = NSDictionary(contentsOfURL: appDefaultsURL) as! [String: AnyObject] var appDefaults = NSDictionary(contentsOfURL: appDefaultsURL) as! [String: AnyObject]
// //
// Add dynamic app defaults // Add dynamic app defaults
// //
if let arduinoPath = workSpace.URLForApplicationWithBundleIdentifier("cc.arduino.Arduino")?.path { if let arduinoPath = workSpace.urlForApplication(withBundleIdentifier: "cc.arduino.Arduino")?.path {
appDefaults["Arduino"] = arduinoPath appDefaults["Arduino"] = arduinoPath
} }
var sketchbooks = [NSString]() var sketchbooks = [NSString]()
for doc in fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) { for doc in fileManager.urls(for: .documentDirectory, in: .userDomainMask) {
sketchbooks.append(doc.URLByAppendingPathComponent("Arduino").path!) sketchbooks.append(doc.URLByAppendingPathComponent("Arduino").path!)
sketchbooks.append(doc.URLByAppendingPathComponent("AVRSack").path!) sketchbooks.append(doc.URLByAppendingPathComponent("AVRSack").path!)
} }
appDefaults["Sketchbooks"] = sketchbooks appDefaults["Sketchbooks"] = sketchbooks
if fileManager.fileExistsAtPath("/usr/local/CrossPack-AVR") { if fileManager.fileExists(atPath: "/usr/local/CrossPack-AVR") {
appDefaults["Toolchain"] = "/usr/local/CrossPack-AVR" appDefaults["Toolchain"] = "/usr/local/CrossPack-AVR"
} else { } else {
appDefaults["Toolchain"] = "" appDefaults["Toolchain"] = ""
} }
userDefaults.registerDefaults(appDefaults) userDefaults.register(defaults: appDefaults)
} }
func applicationDidFinishLaunching(aNotification: NSNotification) { func applicationDidFinishLaunching(aNotification: NSNotification) {
themeMenu.removeAllItems() themeMenu.removeAllItems()
for (index, theme) in ACEThemeNames.humanThemeNames().enumerate() { for (index, theme) in ACEThemeNames.humanThemeNames().enumerated() {
let menuItem = themeMenu.addItemWithTitle(theme, action: "changeTheme:", keyEquivalent: "")! let menuItem = themeMenu.addItem(withTitle: theme, action: Selector(("changeTheme:")), keyEquivalent: "")
menuItem.tag = index menuItem.tag = index
} }
keyboardMenu.removeAllItems() keyboardMenu.removeAllItems()
for (index, theme) in ACEKeyboardHandlerNames.humanKeyboardHandlerNames().enumerate() { for (index, theme) in ACEKeyboardHandlerNames.humanKeyboardHandlerNames().enumerated() {
let menuItem = keyboardMenu.addItemWithTitle(theme, action: "changeKeyboardHandler:", keyEquivalent: "")! let menuItem = keyboardMenu.addItem(withTitle: theme, action: Selector(("changeKeyboardHandler:")), keyEquivalent: "")
menuItem.tag = index menuItem.tag = index
} }
} }
func applicationShouldOpenUntitledFile(sender: NSApplication) -> Bool { func applicationShouldOpenUntitledFile(_ sender: NSApplication) -> Bool {
return false return false
} }
func applicationWillTerminate(aNotification: NSNotification) { func applicationWillTerminate(aNotification: NSNotification) {
} }
func menuNeedsUpdate(menu: NSMenu) { func menuNeedsUpdate(_ menu: NSMenu) {
switch menu.title { switch menu.title {
case "Sketchbook": case "Sketchbook":
menu.removeAllItems() menu.removeAllItems()
sketches = [String]() sketches = [String]()
for sketchBook in NSUserDefaults.standardUserDefaults().objectForKey("Sketchbooks") as! [String] { for sketchBook in UserDefaults.standard.object(forKey:"Sketchbooks") as! [String] {
if NSFileManager.defaultManager().fileExistsAtPath(sketchBook) { if FileManager.default.fileExists(atPath: sketchBook) {
ASSketchBook.addSketches(menu, target: self, action: "openSketch:", path: sketchBook, sketches: &sketches) ASSketchBook.addSketches(menu: menu, target: self, action: Selector(("openSketch:")), path: sketchBook, sketches: &sketches)
} }
} }
case "Examples": case "Examples":
menu.removeAllItems() menu.removeAllItems()
examples = [String]() examples = [String]()
if let arduinoURL = NSWorkspace.sharedWorkspace().URLForApplicationWithBundleIdentifier("cc.arduino.Arduino") { if let arduinoURL = NSWorkspace.shared().urlForApplication(withBundleIdentifier: "cc.arduino.Arduino") {
let examplePath = arduinoURL.URLByAppendingPathComponent("Contents/Resources/Java/examples", isDirectory:true).path! 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":
menu.removeAllItems() menu.removeAllItems()
ASLibraries.instance().addStandardLibrariesToMenu(menu) ASLibraries.instance().addStandardLibrariesToMenu(menu: menu)
case "Import Contributed Library": case "Import Contributed Library":
menu.removeAllItems() menu.removeAllItems()
ASLibraries.instance().addContribLibrariesToMenu(menu) ASLibraries.instance().addContribLibrariesToMenu(menu: menu)
case "Serial Monitor": case "Serial Monitor":
menu.itemAtIndex(0)?.hidden = !hasDocument() menu.item(at: 0)?.isHidden = !hasDocument()
while menu.numberOfItems > 2 { while menu.numberOfItems > 2 {
menu.removeItemAtIndex(2) menu.removeItem(at: 2)
} }
for port in ASSerial.ports() { for port in ASSerial.ports() {
menu.addItemWithTitle(port, action:"serialConnectMenu:", keyEquivalent:"") menu.addItem(withTitle: port, action:Selector(("serialConnectMenu:")), keyEquivalent:"")
} }
default: default:
break break
@ -105,7 +105,7 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
} }
@IBAction func serialConnectMenu(port: NSMenuItem) { @IBAction func serialConnectMenu(port: NSMenuItem) {
ASSerialWin.showWindowWithPort(port.title) ASSerialWin.showWindowWithPort(port: port.title)
} }
func openTemplate(template: NSURL, fromReadOnly: Bool) { func openTemplate(template: NSURL, fromReadOnly: Bool) {
@ -115,16 +115,16 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
} else { } else {
editable = "" editable = ""
} }
ASApplication.newProjectLocation(nil, ASApplication.newProjectLocation(documentWindow: nil,
message: "Save \(editable)copy of project \(template.lastPathComponent!)") message: "Save \(editable)copy of project \(template.lastPathComponent!)")
{ (saveTo) -> Void in { (saveTo) -> Void in
let oldName = template.lastPathComponent! let oldName = template.lastPathComponent!
let newName = saveTo.lastPathComponent! let newName = saveTo.lastPathComponent!
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
do { do {
try fileManager.copyItemAtURL(template, toURL: saveTo) try fileManager.copyItemAtURL(template, toURL: saveTo)
let contents = fileManager.enumeratorAtURL(saveTo, let contents = fileManager.enumeratorAtURL(saveTo,
includingPropertiesForKeys: [NSURLNameKey, NSURLPathKey], includingPropertiesForKeys: [URLResourceKey.nameKey, URLResourceKey.pathKey],
options: .SkipsHiddenFiles, errorHandler: nil) options: .SkipsHiddenFiles, errorHandler: nil)
while let item = contents?.nextObject() as? NSURL { while let item = contents?.nextObject() as? NSURL {
let itemBase = item.URLByDeletingPathExtension?.lastPathComponent! let itemBase = item.URLByDeletingPathExtension?.lastPathComponent!
@ -136,10 +136,10 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
} }
} catch (_) { } catch (_) {
} }
let sketch = ASSketchBook.findSketch(saveTo.path!) let sketch = ASSketchBook.findSketch(path: saveTo.path!)
switch sketch { switch sketch {
case .Sketch(_, let path): case .Sketch(_, let path):
let doc = NSDocumentController.sharedDocumentController() let doc = NSDocumentController.shared()
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:
@ -150,29 +150,29 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
@IBAction func openSketch(item: NSMenuItem) { @IBAction func openSketch(item: NSMenuItem) {
let url = NSURL(fileURLWithPath: sketches[item.tag]) let url = NSURL(fileURLWithPath: sketches[item.tag])
let doc = NSDocumentController.sharedDocumentController() let doc = NSDocumentController.shared()
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) {
let url = NSURL(fileURLWithPath: examples[item.tag]) let url = NSURL(fileURLWithPath: examples[item.tag])
openTemplate(url.URLByDeletingLastPathComponent!, fromReadOnly:true) openTemplate(template: url.deletingLastPathComponent!, fromReadOnly:true)
} }
@IBAction func createSketch(_: AnyObject) { @IBAction func createSketch(_: AnyObject) {
ASApplication.newProjectLocation(nil, ASApplication.newProjectLocation(documentWindow: nil,
message: "Create Project") message: "Create Project")
{ (saveTo) -> Void in { (saveTo) -> Void in
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.defaultManager()
do { do {
try fileManager.createDirectoryAtURL(saveTo, withIntermediateDirectories:false, attributes:nil) try fileManager.createDirectoryAtURL(saveTo, withIntermediateDirectories:false, attributes:nil)
let proj = saveTo.URLByAppendingPathComponent(saveTo.lastPathComponent!+".avrsackproj") let proj = saveTo.appendingPathComponent(saveTo.lastPathComponent!+".avrsackproj")
let docController = NSDocumentController.sharedDocumentController() let docController = NSDocumentController.shared()
if let doc = try docController.openUntitledDocumentAndDisplay(true) 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(url: saveTo.URLByAppendingPathComponent(saveTo.lastPathComponent!+".ino"))
try doc.writeToURL(proj, ofType: "Project", forSaveOperation: .SaveAsOperation, originalContentsURL: nil) try doc.writeToURL(proj, ofType: "Project", forSaveOperation: .SaveAsOperation, originalContentsURL: nil)
} }
} catch _ { } catch _ {
@ -185,15 +185,15 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
savePanel.allowedFileTypes = [kUTTypeFolder as String] 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.beginSheetModal(for: window, completionHandler: { (returnCode) -> Void in
if returnCode == NSFileHandlingPanelOKButton { if returnCode == NSFileHandlingPanelOKButton {
completion(savePanel.URL!) completion(savePanel.url!)
} }
}) })
} else { } else {
savePanel.beginWithCompletionHandler({ (returnCode) -> Void in savePanel.begin(completionHandler: { (returnCode) -> Void in
if returnCode == NSFileHandlingPanelOKButton { if returnCode == NSFileHandlingPanelOKButton {
completion(savePanel.URL!) completion(savePanel.url!)
} }
}) })
} }
@ -201,19 +201,19 @@ class ASApplication: NSObject, NSApplicationDelegate, NSMenuDelegate {
@IBAction func goToHelpPage(sender: AnyObject) { @IBAction func goToHelpPage(sender: AnyObject) {
let helpString: String let helpString: String
switch sender.tag() { switch sender.tag {
case 0: case 0:
helpString = "license.html" helpString = "license.html"
default: default:
abort() abort()
} }
let locBookName = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleHelpBookName") as! String let locBookName = Bundle.main.object(forInfoDictionaryKey: "CFBundleHelpBookName") as! String
AHGotoPage(locBookName, helpString, nil) AHGotoPage(locBookName, helpString, nil)
} }
@IBAction func goToHelpURL(sender: AnyObject) { @IBAction func goToHelpURL(sender: AnyObject) {
let helpString: String let helpString: String
switch sender.tag() { switch sender.tag {
case 0: case 0:
helpString = "https://github.com/microtherion/AVRsack/issues" helpString = "https://github.com/microtherion/AVRsack/issues"
default: default:

View File

@ -10,12 +10,12 @@ import Foundation
class ASBuilder { class ASBuilder {
var dir = NSURL() var dir = NSURL()
var task : NSTask? var task : Task?
var continuation: (()->())? var continuation: (()->())?
var termination : AnyObject? var termination : AnyObject?
init() { init() {
termination = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification, termination = NotificationCenter.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 {
@ -31,7 +31,7 @@ class ASBuilder {
}) })
} }
func finalize() { func finalize() {
NSNotificationCenter.defaultCenter().removeObserver(termination!) NotificationCenter.default.removeObserver(termination!)
} }
func setProjectURL(url: NSURL) { func setProjectURL(url: NSURL) {
@ -45,19 +45,19 @@ class ASBuilder {
func cleanProject() { func cleanProject() {
do { do {
try NSFileManager.defaultManager().removeItemAtURL(dir.URLByAppendingPathComponent("build")) try FileManager.default.removeItem(at: dir.appendingPathComponent("build")!)
} catch _ { } catch _ {
} }
} }
func buildProject(board: String, files: ASFileTree) { func buildProject(board: String, files: ASFileTree) {
let toolChain = (NSApplication.sharedApplication().delegate as! ASApplication).preferences.toolchainPath let toolChain = (NSApplication.shared().delegate as! ASApplication).preferences.toolchainPath
task = NSTask() task = Task()
task!.currentDirectoryPath = dir.path! task!.currentDirectoryPath = dir.path!
task!.launchPath = NSBundle.mainBundle().pathForResource("BuildProject", ofType: "")! task!.launchPath = Bundle.main.path(forResource: "BuildProject", ofType: "")!
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
let libPath = (ASLibraries.instance().directories as NSArray).componentsJoinedByString(":") let libPath = (ASLibraries.instance().directories as NSArray).componentsJoined(by: ":")
var args = [String]() var args = [String]()
if ASHardware.instance().boards[board] == nil { if ASHardware.instance().boards[board] == nil {
NSLog("Unable to find board %s\n", board); NSLog("Unable to find board %s\n", board);
@ -67,10 +67,10 @@ class ASBuilder {
let library = boardProp["library"]! let library = boardProp["library"]!
let 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.fileExists(atPath: corePath) {
if let variantName = boardProp["build.variant"] { if let variantName = boardProp["build.variant"] {
variantPath = library+"/variants/"+variantName variantPath = library+"/variants/"+variantName
if fileManager.fileExistsAtPath(variantPath!) { if fileManager.fileExists(atPath: variantPath!) {
args.append("variant="+variantName) args.append("variant="+variantName)
} else { } else {
variantPath = nil variantPath = nil
@ -109,26 +109,26 @@ class ASBuilder {
func uploadProject(board: String, programmer: String, port: String, mode: Mode = .Upload) { func uploadProject(board: String, programmer: String, port: String, mode: Mode = .Upload) {
let useProgrammer = mode != .Upload let useProgrammer = mode != .Upload
let interactive = mode == .Interactive let interactive = mode == .Interactive
let portPath = ASSerial.fileNameForPort(port) let portPath = ASSerial.fileName(forPort: port)
let toolChain = (NSApplication.sharedApplication().delegate as! ASApplication).preferences.toolchainPath let toolChain = (NSApplication.shared().delegate as! ASApplication).preferences.toolchainPath
task = NSTask() task = Task()
task!.currentDirectoryPath = dir.path! task!.currentDirectoryPath = dir.path!
task!.launchPath = toolChain+"/bin/avrdude" task!.launchPath = toolChain+"/bin/avrdude"
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
var logOut : NSFileHandle var logOut : FileHandle
if interactive { if interactive {
let inputPipe = NSPipe() let inputPipe = Pipe()
let outputPipe = NSPipe() let outputPipe = Pipe()
logOut = outputPipe.fileHandleForWriting logOut = outputPipe.fileHandleForWriting
task!.standardInput = inputPipe task!.standardInput = inputPipe
task!.standardOutput = outputPipe task!.standardOutput = outputPipe
task!.standardError = outputPipe task!.standardError = outputPipe
} else { } else {
ASSerialWin.portNeededForUpload(port) ASSerialWin.portNeededForUpload(port: port)
let logURL = dir.URLByAppendingPathComponent("build/upload.log") let logURL = dir.appendingPathComponent("build/upload.log")
fileManager.createFileAtPath(logURL.path!, contents: NSData(), attributes: nil) fileManager.createFileAtPath(logURL.path, contents: NSData(), attributes: nil)
logOut = NSFileHandle(forWritingAtPath: logURL.path!)! logOut = FileHandle(forWritingAtPath: logURL.path!)!
task!.standardOutput = logOut task!.standardOutput = logOut
task!.standardError = logOut task!.standardError = logOut
} }
@ -143,8 +143,8 @@ class ASBuilder {
let leonardish = hasBootloader && (boardProp["bootloader.path"] ?? "").hasPrefix("caterina") let leonardish = hasBootloader && (boardProp["bootloader.path"] ?? "").hasPrefix("caterina")
let proto = hasBootloader ? boardProp["upload.protocol"] : progProp?["protocol"] let proto = hasBootloader ? boardProp["upload.protocol"] : progProp?["protocol"]
let speed = hasBootloader ? boardProp["upload.speed"] : progProp?["speed"] let speed = hasBootloader ? boardProp["upload.speed"] : progProp?["speed"]
let verbosity = NSUserDefaults.standardUserDefaults().integerForKey("UploadVerbosity") let verbosity = UserDefaults.standard.integer(forKey: "UploadVerbosity")
var args = Array<String>(count: verbosity, repeatedValue: "-v") var args = Array<String>(repeating: "-v", count: verbosity)
args += [ args += [
"-C", toolChain+"/etc/avrdude.conf", "-C", toolChain+"/etc/avrdude.conf",
"-p", boardProp["build.mcu"]!, "-c", proto!, "-P", portPath] "-p", boardProp["build.mcu"]!, "-c", proto!, "-P", portPath]
@ -182,15 +182,15 @@ class ASBuilder {
needPhase2 = true needPhase2 = true
} }
if needPhase2 { if needPhase2 {
let task2 = NSTask() let task2 = Task()
task2.currentDirectoryPath = dir.path! task2.currentDirectoryPath = dir.path!
task2.launchPath = toolChain+"/bin/avrdude" task2.launchPath = toolChain+"/bin/avrdude"
task2.arguments = loaderArgs task2.arguments = loaderArgs
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).componentsJoined(by: " ")+"\n"
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!) logOut.write(cmdLine.data(using: String.Encoding.utf8, allowLossyConversion: true)!)
task2.launch() task2.launch()
self.continuation = { self.continuation = {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2*NSEC_PER_SEC)), dispatch_get_main_queue(), { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2*NSEC_PER_SEC)), dispatch_get_main_queue(), {
@ -212,53 +212,53 @@ class ASBuilder {
// //
if leonardish { if leonardish {
if verbosity > 0 { if verbosity > 0 {
logOut.writeData("Opening port \(port) at 1200 baud\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!) logOut.write("Opening port \(port) at 1200 baud\n".data(using: String.Encoding.utf8, allowLossyConversion: true)!)
} }
if let dummyConnection = ASSerial.openPort(portPath, withSpeed: 1200) { if let dummyConnection = ASSerial.openPort(portPath, withSpeed: 1200) {
usleep(50000) usleep(50000)
ASSerial.closePort(dummyConnection.fileDescriptor) ASSerial.closePort(dummyConnection.fileDescriptor)
sleep(1) sleep(1)
for (var retry=0; retry < 40; ++retry) { for retry in 0 ..< 40 {
usleep(250000) usleep(250000)
if (fileManager.fileExistsAtPath(portPath)) { if (fileManager.fileExistsAtPath(portPath)) {
if verbosity > 0 { if verbosity > 0 {
logOut.writeData("Found port \(port) after \(retry) attempts.\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!) logOut.write("Found port \(port) after \(retry) attempts.\n".data(using: String.Encoding.utf8, allowLossyConversion: true)!)
} }
break; break;
} }
} }
} }
} }
let cmdLine = task!.launchPath!+" "+(args as NSArray).componentsJoinedByString(" ")+"\n" let cmdLine = task!.launchPath!+" "+(args as NSArray).componentsJoined(by: " ")+"\n"
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!) logOut.write(cmdLine.data(using: String.Encoding.utf8, allowLossyConversion: true)!)
task!.arguments = args; task!.arguments = args;
task!.launch() task!.launch()
if interactive { if interactive {
let intSpeed = (speed != nil) ? Int(speed!) ?? 19200 : 19200 let intSpeed = (speed != nil) ? Int(speed!) ?? 19200 : 19200
ASSerialWin.showWindowWithPort(port, task:task!, speed:intSpeed) ASSerialWin.showWindowWithPort(port: port, task:task!, speed:intSpeed)
task = nil task = nil
} }
} }
func disassembleProject(board: String) { func disassembleProject(board: String) {
let toolChain = (NSApplication.sharedApplication().delegate as! ASApplication).preferences.toolchainPath let toolChain = (NSApplication.shared().delegate as! ASApplication).preferences.toolchainPath
task = NSTask() task = Task()
task!.currentDirectoryPath = dir.path! task!.currentDirectoryPath = dir.path!
task!.launchPath = toolChain+"/bin/avr-objdump" task!.launchPath = toolChain+"/bin/avr-objdump"
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
let logURL = dir.URLByAppendingPathComponent("build/disasm.log") let logURL = dir.appendingPathComponent("build/disasm.log")
fileManager.createFileAtPath(logURL.path!, contents: NSData(), attributes: nil) fileManager.createFileAtPath(logURL.path!, contents: NSData(), attributes: nil)
let logOut = NSFileHandle(forWritingAtPath: logURL.path!)! let logOut = FileHandle(forWritingAtPath: logURL.path!)!
task!.standardOutput = logOut task!.standardOutput = logOut
task!.standardError = logOut task!.standardError = logOut
let showSource = NSUserDefaults.standardUserDefaults().boolForKey("ShowSourceInDisassembly") let showSource = UserDefaults.standard.bool(forKey: "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).componentsJoined(by: " ")+"\n"
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!) logOut.writeData(cmdLine.dataUsingEncoding(String.Encoding.utf8, allowLossyConversion: true)!)
task!.arguments = args; task!.arguments = args;
task!.launch() task!.launch()
} }
} }

View File

@ -18,7 +18,7 @@ enum ASFileType : String {
case Markdown = "doc.md" case Markdown = "doc.md"
static func guessForURL(url: NSURL) -> ASFileType { static func guessForURL(url: NSURL) -> ASFileType {
switch url.pathExtension!.lowercaseString { switch url.pathExtension!.lowercased {
case "hpp", "hh", "h": case "hpp", "hh", "h":
return .Header return .Header
case "c": case "c":
@ -41,9 +41,9 @@ enum ASFileType : String {
case .Header,.CFile,.CppFile,.Arduino: case .Header,.CFile,.CppFile,.Arduino:
return .CPP return .CPP
case .Markdown: case .Markdown:
return .Markdown return .markdown
default: default:
return .Text return .text
} }
} }
} }
@ -130,7 +130,7 @@ class ASFileGroup : ASFileNode {
expanded = prop[kExpandedKey] as! Bool expanded = prop[kExpandedKey] as! Bool
children = [] children = []
for child in (prop[kChildrenKey] as! [NSDictionary]) { for child in (prop[kChildrenKey] as! [NSDictionary]) {
children.append(ASFileNode.readPropertyList(child, rootURL: rootURL)) children.append(ASFileNode.readPropertyList(prop: child, rootURL: rootURL))
} }
super.init(name: prop[kNameKey] as! String) super.init(name: prop[kNameKey] as! String)
} }
@ -138,13 +138,13 @@ class ASFileGroup : ASFileNode {
return (expanded ? "📂" : "📁")+" "+name return (expanded ? "📂" : "📁")+" "+name
} }
override func apply(closure: (ASFileNode) -> ()) { override func apply(closure: (ASFileNode) -> ()) {
super.apply(closure) super.apply(closure: closure)
for child in children { for child in children {
child.apply(closure) child.apply(closure: closure)
} }
} }
func childrenPropertyList(rootPath: String) -> [AnyObject] { func childrenPropertyList(rootPath: String) -> [AnyObject] {
return children.map() { (node) in node.propertyList(rootPath) } return children.map() { (node) in node.propertyList(rootPath: rootPath) }
} }
override func propertyList(rootPath: String) -> AnyObject { override func propertyList(rootPath: String) -> AnyObject {
return [kTypeKey: kNodeType, kNameKey: name, kExpandedKey: expanded, return [kTypeKey: kNodeType, kNameKey: name, kExpandedKey: expanded,
@ -153,7 +153,7 @@ class ASFileGroup : ASFileNode {
override func paths(rootPath: String) -> [String] { override func paths(rootPath: String) -> [String] {
var allPaths = [String]() var allPaths = [String]()
for child in children { for child in children {
allPaths += child.paths(rootPath) allPaths += child.paths(rootPath: rootPath)
} }
return allPaths return allPaths
} }
@ -191,14 +191,14 @@ 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)).standardizingPath!
} }
if !url.checkResourceIsReachableAndReturnError(nil) { if !url.checkResourceIsReachableAndReturnError(nil) {
// //
// When projects get moved, .ino files get renamed but that fact is not // When projects get moved, .ino files get renamed but that fact is not
// yet reflected in the project file. // yet reflected in the project file.
// //
let urlDir = url.URLByDeletingLastPathComponent let urlDir = url.deletingLastPathComponent
let newName = rootURL.URLByAppendingPathExtension(url.pathExtension!).lastPathComponent! let newName = rootURL.URLByAppendingPathExtension(url.pathExtension!).lastPathComponent!
if let altURL = urlDir?.URLByAppendingPathComponent(newName) { if let altURL = urlDir?.URLByAppendingPathComponent(newName) {
if altURL.checkResourceIsReachableAndReturnError(nil) { if altURL.checkResourceIsReachableAndReturnError(nil) {
@ -213,7 +213,7 @@ class ASFileItem : ASFileNode {
} }
func relativePath(relativeTo: String) -> String { func relativePath(relativeTo: String) -> String {
let path = (url.path! as NSString).stringByResolvingSymlinksInPath let path = (url.path! as NSString).resolvingSymlinksInPath
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
@ -222,7 +222,7 @@ class ASFileItem : ASFileNode {
var matchComp = 0 var matchComp = 0
while (matchComp < relCount && matchComp < pathCount) { while (matchComp < relCount && matchComp < pathCount) {
if pathComp[matchComp] == relComp[matchComp] { if pathComp[matchComp] == relComp[matchComp] {
++matchComp matchComp += 1
} else { } else {
break break
} }
@ -238,7 +238,7 @@ class ASFileItem : ASFileNode {
return [kTypeKey: kNodeTypeFile, kKindKey: type.rawValue, kPathKey: relativePath(rootPath)] return [kTypeKey: kNodeTypeFile, kKindKey: type.rawValue, kPathKey: relativePath(rootPath)]
} }
override func paths(rootPath: String) -> [String] { override func paths(rootPath: String) -> [String] {
return [relativePath(rootPath)] return [relativePath(relativeTo: rootPath)]
} }
override func exists() -> Bool { override func exists() -> Bool {
return url.checkResourceIsReachableAndReturnError(nil) return url.checkResourceIsReachableAndReturnError(nil)
@ -246,23 +246,23 @@ class ASFileItem : ASFileNode {
override func modDate() -> NSDate? { override func modDate() -> NSDate? {
var date: AnyObject? var date: AnyObject?
do { do {
try url.getResourceValue(&date, forKey: NSURLContentModificationDateKey) try url.getResourceValue(&date, forKey: URLResourceKey.contentModificationDateKey)
return date as? NSDate return date as? NSDate
} catch _ { } catch _ {
return nil return nil
} }
} }
override func revision() -> String? { override func revision() -> String? {
let task = NSTask() let task = Task()
task.launchPath = NSBundle.mainBundle().pathForResource("FileRevision", ofType: "")! task.launchPath = Bundle.main.path(forResource: "FileRevision", ofType: "")!
let outputPipe = NSPipe() let outputPipe = Pipe()
task.standardOutput = outputPipe task.standardOutput = outputPipe
task.standardError = NSFileHandle.fileHandleWithNullDevice() task.standardError = FileHandle.nullDevice
task.arguments = [url.path!] task.arguments = [url.path!]
task.launch() task.launch()
return NSString(data: outputPipe.fileHandleForReading.readDataToEndOfFile(), return NSString(data: outputPipe.fileHandleForReading.readDataToEndOfFile(),
encoding: NSUTF8StringEncoding) as? String encoding: String.Encoding.utf8) as? String
} }
} }
@ -275,40 +275,40 @@ class ASFileTree : NSObject, NSOutlineViewDataSource {
var dragged = [ASFileNode]() var dragged = [ASFileNode]()
func addFileURL(url: NSURL, omitUnknown: Bool = true) { func addFileURL(url: NSURL, omitUnknown: Bool = true) {
let type = ASFileType.guessForURL(url) let type = ASFileType.guessForURL(url: url)
if !omitUnknown || type != .Unknown { if !omitUnknown || type != .Unknown {
root.children.append(ASFileItem(url: url.URLByStandardizingPath!, type: type)) root.children.append(ASFileItem(url: url.standardizingPath!, type: type))
} }
} }
func setProjectURL(url: NSURL) { func setProjectURL(url: NSURL) {
root.name = url.URLByDeletingPathExtension!.lastPathComponent! root.name = url.deletingPathExtension!.lastPathComponent
dir = url.URLByDeletingLastPathComponent!.URLByStandardizingPath! dir = url.URLByDeletingLastPathComponent!.URLByStandardizingPath!
} }
func projectPath() -> String { func projectPath() -> String {
return (dir.path! as NSString).stringByResolvingSymlinksInPath return (dir.path! as NSString).resolvingSymlinksInPath
} }
func apply(closure: (ASFileNode) -> ()) { func apply(closure: (ASFileNode) -> ()) {
root.apply(closure) root.apply(closure: closure)
} }
func propertyList() -> AnyObject { func propertyList() -> AnyObject {
return root.propertyList(projectPath()) return root.propertyList(rootPath: projectPath())
} }
func readPropertyList(prop: NSDictionary) { func readPropertyList(prop: NSDictionary) {
root = ASFileNode.readPropertyList(prop, rootURL:dir) as! ASProject root = ASFileNode.readPropertyList(prop: prop, rootURL:dir) as! ASProject
} }
var paths : [String] { var paths : [String] {
return root.paths(projectPath()) return root.paths(rootPath: projectPath())
} }
// MARK: Outline Data Source // MARK: Outline Data Source
func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int { func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int {
if item == nil { if item == nil {
return 4 return 4
} else { } else {
return (item as! ASFileGroup).children.count return (item as! ASFileGroup).children.count
} }
} }
func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject { func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject {
if item == nil { if item == nil {
switch index { switch index {
case 1: case 1:
@ -325,15 +325,15 @@ class ASFileTree : NSObject, NSOutlineViewDataSource {
return group.children[index] return group.children[index]
} }
} }
func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool { func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool {
return item is ASFileGroup return item is ASFileGroup
} }
func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? { func outlineView(_ outlineView: NSOutlineView, objectValueFor tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? {
return (item as! ASFileNode).nodeName() return (item as! ASFileNode).nodeName()
} }
let kLocalReorderPasteboardType = "ASFilePasteboardType" let kLocalReorderPasteboardType = "ASFilePasteboardType"
func outlineView(outlineView: NSOutlineView, writeItems items: [AnyObject], toPasteboard pasteboard: NSPasteboard) -> Bool { func outlineView(_ outlineView: NSOutlineView, writeItems items: [AnyObject], to pasteboard: NSPasteboard) -> Bool {
dragged = items as! [ASFileNode] dragged = items as! [ASFileNode]
pasteboard.declareTypes([kLocalReorderPasteboardType], owner: self) pasteboard.declareTypes([kLocalReorderPasteboardType], owner: self)
pasteboard.setData(NSData(), forType: kLocalReorderPasteboardType) pasteboard.setData(NSData(), forType: kLocalReorderPasteboardType)
@ -346,52 +346,53 @@ class ASFileTree : NSObject, NSOutlineViewDataSource {
} else if item is ASProject { } else if item is ASProject {
return false return false
} else { } else {
return itemIsDescendentOfDrag(outlineView, item: outlineView.parentForItem(item) as! ASFileNode) return itemIsDescendentOfDrag(outlineView: outlineView, item: outlineView.parent(forItem: item) as! ASFileNode)
} }
} }
func outlineView(outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: AnyObject?, proposedChildIndex index: Int) -> NSDragOperation { func outlineView(_ outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: AnyObject?, proposedChildIndex index: Int) -> NSDragOperation {
if info.draggingPasteboard().availableTypeFromArray([kLocalReorderPasteboardType]) == nil { if info.draggingPasteboard().availableType(from: [kLocalReorderPasteboardType]) == nil {
return NSDragOperation.None // Only allow reordering drags return [] // Only allow reordering drags
} }
for drag in dragged { for drag in dragged {
switch (drag) { switch (drag) {
case is ASProject, is ASLogNode: case is ASProject, is ASLogNode:
return NSDragOperation.None // Don't allow root or log nodes to be dragged return [] // Don't allow root or log nodes to be dragged
default: default:
break break
} }
} }
switch (item) { switch (item) {
case is ASProject, is ASFileGroup: case is ASProject, is ASFileGroup:
if itemIsDescendentOfDrag(outlineView, item: item as! ASFileNode) { if itemIsDescendentOfDrag(outlineView: outlineView, item: item as! ASFileNode) {
return NSDragOperation.None // Don't allow drag on member of dragged items or a descendent thereof return [] // Don't allow drag on member of dragged items or a descendent thereof
} }
default: default:
return NSDragOperation.None // Don't allow drag onto leaf return [] // Don't allow drag onto leaf
} }
return NSDragOperation.Generic return NSDragOperation.generic
} }
func outlineView(outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: AnyObject?, var childIndex insertAtIndex: Int) -> Bool { func outlineView(_ outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: AnyObject?, childIndex insertAtIndex: Int) -> Bool {
var insertAtIndex = insertAtIndex
let parent : ASFileGroup = (item as? ASFileGroup) ?? root let parent : ASFileGroup = (item as? ASFileGroup) ?? root
if insertAtIndex == NSOutlineViewDropOnItemIndex { if insertAtIndex == NSOutlineViewDropOnItemIndex {
insertAtIndex = parent.children.count insertAtIndex = parent.children.count
} }
outlineView.beginUpdates() outlineView.beginUpdates()
for item in dragged { for item in dragged {
let origParent = outlineView.parentForItem(item) as! ASFileGroup let origParent = outlineView.parent(forItem: item) as! ASFileGroup
let origIndex = origParent.children.indexOf(item)! let origIndex = origParent.children.index(of: item)!
origParent.children.removeAtIndex(origIndex) origParent.children.remove(at: origIndex)
outlineView.removeItemsAtIndexes(NSIndexSet(index:origIndex), inParent:origParent, withAnimation:NSTableViewAnimationOptions.EffectNone) outlineView.removeItemsAtIndexes(NSIndexSet(index:origIndex), inParent:origParent, withAnimation:NSTableViewAnimationOptions.EffectNone)
if origParent == parent && insertAtIndex > origIndex { if origParent == parent && insertAtIndex > origIndex {
insertAtIndex -= 1 insertAtIndex -= 1
} }
parent.children.insert(item, atIndex:insertAtIndex) parent.children.insert(item, at:insertAtIndex)
outlineView.insertItemsAtIndexes(NSIndexSet(index:insertAtIndex), inParent: parent, withAnimation:NSTableViewAnimationOptions.EffectGap) outlineView.insertItemsAtIndexes(NSIndexSet(index:insertAtIndex), inParent: parent, withAnimation:NSTableViewAnimationOptions.EffectGap)
insertAtIndex += 1 insertAtIndex += 1
} }
outlineView.endUpdates() outlineView.endUpdates()
(outlineView.delegate() as! ASProjDoc).updateChangeCount(NSDocumentChangeType.ChangeDone) (outlineView.delegate as! ASProjDoc).updateChangeCount(NSDocumentChangeType.changeDone)
return true return true
} }
} }

View File

@ -13,21 +13,21 @@ 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.sort({ $0["name"] < $1["name"] }) { for choice in choices.sorted(by: { $0["name"] < $1["name"] }) {
let item = self.addItemWithTitle(choice["name"]!, action: selector, keyEquivalent: "") let item = self.addItem(withTitle: choice["name"]!, action: selector, keyEquivalent: "")
item?.target = target item.target = target
} }
} }
} }
private func subdirectories(path: String) -> [String] { private func subdirectories(path: String) -> [String] {
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
var subDirs = [String]() var subDirs = [String]()
var isDir : ObjCBool = false var isDir : ObjCBool = false
if let items = try? fileManager.contentsOfDirectoryAtPath(path) { if let items = try? fileManager.contentsOfDirectory(atPath: path) {
for item in items { for item in items {
let subPath = path+"/"+item let subPath = path+"/"+item
if fileManager.fileExistsAtPath(subPath, isDirectory: &isDir) && isDir { if fileManager.fileExists(atPath: subPath, isDirectory: &isDir) && isDir.boolValue {
subDirs.append(subPath) subDirs.append(subPath)
} }
} }
@ -45,14 +45,14 @@ class ASHardware {
// //
// Gather hardware directories // Gather hardware directories
// //
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
if let arduinoPath = userDefaults.stringForKey("Arduino") { if let arduinoPath = userDefaults.string(forKey: "Arduino") {
let arduinoHardwarePath = arduinoPath + "/Contents/Resources/Java/hardware" let arduinoHardwarePath = arduinoPath + "/Contents/Resources/Java/hardware"
directories += subdirectories(arduinoHardwarePath) directories += subdirectories(path: arduinoHardwarePath)
} }
for sketchDir in userDefaults.objectForKey("Sketchbooks") as! [String] { for sketchDir in userDefaults.object(forKey: "Sketchbooks") as! [String] {
let hardwarePath = sketchDir + "/hardware" let hardwarePath = sketchDir + "/hardware"
directories += subdirectories(hardwarePath) directories += subdirectories(path: hardwarePath)
} }
let property = try! NSRegularExpression(pattern: "\\s*(\\w+)\\.(\\S+?)\\s*=\\s*(\\S.*\\S)\\s*", options: []) let property = try! NSRegularExpression(pattern: "\\s*(\\w+)\\.(\\S+?)\\s*=\\s*(\\S.*\\S)\\s*", options: [])
// //
@ -63,12 +63,12 @@ class ASHardware {
let provenience = (dir as NSString).lastPathComponent let provenience = (dir as NSString).lastPathComponent
if let boardsFile = try? NSString(contentsOfFile: boardsPath, usedEncoding: nil) { if let boardsFile = try? NSString(contentsOfFile: boardsPath, usedEncoding: nil) {
var seen = [String: Bool]() var seen = [String: Bool]()
for line in boardsFile.componentsSeparatedByString("\n") { for line in boardsFile.components(separatedBy: "\n") {
if let match = property.firstMatchInString(line, options: .Anchored, range: NSMakeRange(0, line.utf16.count)) { if let match = property.firstMatch(in: line, options: .anchored, range: NSMakeRange(0, line.utf16.count)) {
let nsline = line as NSString let nsline = line as NSString
let board = nsline.substringWithRange(match.rangeAtIndex(1)) as String let board = nsline.substring(with: match.rangeAt(1)) as String
let property = nsline.substringWithRange(match.rangeAtIndex(2)) as String let property = nsline.substring(with: match.rangeAt(2)) as String
let value = nsline.substringWithRange(match.rangeAtIndex(3)) as String let value = nsline.substring(with: match.rangeAt(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
@ -88,12 +88,12 @@ class ASHardware {
let provenience = (dir as NSString).lastPathComponent let provenience = (dir as NSString).lastPathComponent
if let programmersFile = try? NSString(contentsOfFile: programmersPath, usedEncoding: nil) { if let programmersFile = try? NSString(contentsOfFile: programmersPath, usedEncoding: nil) {
var seen = [String: Bool]() var seen = [String: Bool]()
for line in programmersFile.componentsSeparatedByString("\n") { for line in programmersFile.components(separatedBy: "\n") {
if let match = property.firstMatchInString(line, options: .Anchored, range: NSMakeRange(0, line.utf16.count)) { if let match = property.firstMatch(in: line, options: .anchored, range: NSMakeRange(0, line.utf16.count)) {
let nsline = line as NSString let nsline = line as NSString
let programmer = nsline.substringWithRange(match.rangeAtIndex(1)) let programmer = nsline.substring(with: match.rangeAt(1))
let property = nsline.substringWithRange(match.rangeAtIndex(2)) let property = nsline.substring(with: match.rangeAt(2))
let value = nsline.substringWithRange(match.rangeAtIndex(3)) let value = nsline.substring(with: match.rangeAt(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
@ -107,18 +107,18 @@ class ASHardware {
func buildMenu(menu:NSMenu, choices:ASProperties, recentChoices:[String], target: AnyObject, selector: Selector) { func buildMenu(menu:NSMenu, choices:ASProperties, recentChoices:[String], target: AnyObject, selector: Selector) {
menu.removeAllItems() menu.removeAllItems()
menu.addItemWithTitle("Title", action: "", keyEquivalent: "") menu.addItem(withTitle: "Title", action: nil, keyEquivalent: "")
if choices.count <= 10 { if choices.count <= 10 {
menu.addSortedChoices([ASPropertyEntry](choices.values), target: target, selector: selector) menu.addSortedChoices(choices: [ASPropertyEntry](choices.values), target: target, selector: selector)
} else { } else {
menu.addSortedChoices(recentChoices.flatMap({ (recent: String) in choices[recent] }), target: target, selector: selector) menu.addSortedChoices(choices: recentChoices.flatMap({ (recent: String) in choices[recent] }), target: target, selector: selector)
menu.addItem(NSMenuItem.separatorItem()) menu.addItem(NSMenuItem.separator())
var seen = [String: Bool]() var seen = [String: Bool]()
for prop in choices.values { for prop in choices.values {
seen[prop["provenience"]!] = true seen[prop["provenience"]!] = true
} }
var sortedKeys = [String](seen.keys) var sortedKeys = [String](seen.keys)
sortedKeys.sortInPlace { $0 < $1 } sortedKeys.sort { $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 {
@ -126,21 +126,21 @@ class ASHardware {
subset.append(prop) subset.append(prop)
} }
} }
let item = menu.addItemWithTitle(provenience, action: nil, keyEquivalent: "")! let item = menu.addItem(withTitle: provenience, action: nil, keyEquivalent: "")
let submenu = NSMenu() let submenu = NSMenu()
submenu.autoenablesItems = false submenu.autoenablesItems = false
submenu.addSortedChoices(subset, target: target, selector: selector) submenu.addSortedChoices(choices: subset, target: target, selector: selector)
menu.setSubmenu(submenu, forItem: item) menu.setSubmenu(submenu, for: item)
} }
} }
} }
func buildBoardsMenu(menu:NSMenu, recentBoards:[String], target: AnyObject, selector: Selector) { func buildBoardsMenu(menu:NSMenu, recentBoards:[String], target: AnyObject, selector: Selector) {
buildMenu(menu, choices:boards, recentChoices:recentBoards, target: target, selector: selector) buildMenu(menu: menu, choices:boards, recentChoices:recentBoards, target: target, selector: selector)
} }
func buildProgrammersMenu(menu:NSMenu, recentProgrammers:[String], target: AnyObject, selector: Selector) { func buildProgrammersMenu(menu:NSMenu, recentProgrammers:[String], target: AnyObject, selector: Selector) {
buildMenu(menu, choices:programmers, recentChoices:recentProgrammers, target: target, selector: selector) buildMenu(menu: menu, choices:programmers, recentChoices:recentProgrammers, target: target, selector: selector)
} }
} }
@ -155,19 +155,19 @@ class ASLibraries : NSObject {
// //
// Gather hardware directories // Gather hardware directories
// //
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
for sketchDir in userDefaults.objectForKey("Sketchbooks") as! [String] { for sketchDir in userDefaults.object(forKey: "Sketchbooks") as! [String] {
let librariesPath = sketchDir + "/libraries" let librariesPath = sketchDir + "/libraries"
let dirs = subdirectories(librariesPath) let dirs = subdirectories(path: librariesPath)
if dirs.count > 0 { if dirs.count > 0 {
directories.append(librariesPath) directories.append(librariesPath)
libraries += dirs libraries += dirs
contribLib += dirs contribLib += dirs
} }
} }
if let arduinoPath = userDefaults.stringForKey("Arduino") { if let arduinoPath = userDefaults.string(forKey: "Arduino") {
let arduinoLibrariesPath = arduinoPath + "/Contents/Resources/Java/libraries" let arduinoLibrariesPath = arduinoPath + "/Contents/Resources/Java/libraries"
let dirs = subdirectories(arduinoLibrariesPath) let dirs = subdirectories(path: arduinoLibrariesPath)
if dirs.count > 0 { if dirs.count > 0 {
directories.append(arduinoLibrariesPath) directories.append(arduinoLibrariesPath)
libraries += dirs libraries += dirs
@ -176,32 +176,32 @@ class ASLibraries : NSObject {
} }
} }
func addStandardLibrariesToMenu(menu: NSMenu) { func addStandardLibrariesToMenu(menu: NSMenu) {
for (index,lib) in standardLib.enumerate() { for (index,lib) in standardLib.enumerated() {
let menuItem = menu.addItemWithTitle((lib as NSString).lastPathComponent, action: "importStandardLibrary:", keyEquivalent: "") let menuItem = menu.addItem(withTitle: (lib as NSString).lastPathComponent, action: #selector(ASLibraries.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 contribLib.enumerate() { for (index,lib) in contribLib.enumerated() {
let menuItem = menu.addItemWithTitle((lib as NSString).lastPathComponent, action: "importContribLibrary:", keyEquivalent: "") let menuItem = menu.addItem(withTitle: (lib as NSString).lastPathComponent, action: #selector(ASLibraries.importContribLibrary(_:)), keyEquivalent: "")
menuItem?.target = self menuItem.target = self
menuItem?.tag = index menuItem.tag = index
} }
} }
@IBAction func importStandardLibrary(menuItem: AnyObject) { @IBAction func importStandardLibrary(_ menuItem: AnyObject) {
if let tag = (menuItem as? NSMenuItem)?.tag { if let tag = (menuItem as? NSMenuItem)?.tag {
NSApplication.sharedApplication().sendAction("importLibrary:", to: nil, from: standardLib[tag]) NSApplication.shared().sendAction(#selector(ASProjDoc.importLibrary(_:)), to: nil, from: standardLib[tag])
} }
} }
@IBAction func importContribLibrary(menuItem: AnyObject) { @IBAction func importContribLibrary(_ menuItem: AnyObject) {
if let tag = (menuItem as? NSMenuItem)?.tag { if let tag = (menuItem as? NSMenuItem)?.tag {
NSApplication.sharedApplication().sendAction("importLibrary:", to: nil, from: contribLib[tag]) NSApplication.shared().sendAction(#selector(ASProjDoc.importLibrary(_:)), to: nil, from: contribLib[tag])
} }
} }
func validateUserInterfaceItem(anItem: NSValidatedUserInterfaceItem) -> Bool { func validateUserInterfaceItem(anItem: NSValidatedUserInterfaceItem) -> Bool {
if let validator = NSApplication.sharedApplication().targetForAction("importLibrary:") as? NSUserInterfaceValidations { if let validator = NSApplication.shared().target(forAction: #selector(ASProjDoc.importLibrary(_:))) as? NSUserInterfaceValidations {
return validator.validateUserInterfaceItem(anItem) return validator.validateUserInterfaceItem(anItem)
} }
return false return false

View File

@ -15,10 +15,10 @@ private let kASToolchainOther = 2
class ASPreferences: NSWindowController, NSOpenSavePanelDelegate { class ASPreferences: NSWindowController, NSOpenSavePanelDelegate {
var toolchainPref : String { var toolchainPref : String {
get { get {
return NSUserDefaults.standardUserDefaults().objectForKey("Toolchain") as! String return UserDefaults.standard.object(forKey: "Toolchain") as! String
} }
set(newToolchain) { set(newToolchain) {
NSUserDefaults.standardUserDefaults().setObject(newToolchain, forKey: "Toolchain") UserDefaults.standard.set(newToolchain, forKey: "Toolchain")
} }
} }
var toolchainType : Int { var toolchainType : Int {
@ -53,7 +53,7 @@ class ASPreferences: NSWindowController, NSOpenSavePanelDelegate {
if toolchainPref != ("" as String) { if toolchainPref != ("" as String) {
return toolchainPref return toolchainPref
} else { } else {
return NSWorkspace.sharedWorkspace().URLForApplicationWithBundleIdentifier("cc.arduino.Arduino")!.path! + return NSWorkspace.shared().urlForApplication(withBundleIdentifier: "cc.arduino.Arduino")!.path +
"/Contents/Resources/Java/hardware/tools/avr" "/Contents/Resources/Java/hardware/tools/avr"
} }
} }
@ -68,7 +68,7 @@ class ASPreferences: NSWindowController, NSOpenSavePanelDelegate {
var hasCrossPackAVR : Bool { var hasCrossPackAVR : Bool {
get { get {
return NSFileManager.defaultManager().fileExistsAtPath("/usr/local/CrossPack-AVR/bin") return FileManager.default.fileExists(atPath: "/usr/local/CrossPack-AVR/bin")
} }
} }
@ -79,15 +79,15 @@ class ASPreferences: NSWindowController, NSOpenSavePanelDelegate {
openPanel.canChooseDirectories = true openPanel.canChooseDirectories = true
openPanel.allowsMultipleSelection = false openPanel.allowsMultipleSelection = false
openPanel.resolvesAliases = true openPanel.resolvesAliases = true
openPanel.beginSheetModalForWindow(window!, completionHandler: { (returnCode: Int) -> Void in openPanel.beginSheetModal(for: window!, completionHandler: { (returnCode: Int) -> Void in
if returnCode == NSFileHandlingPanelOKButton { if returnCode == NSFileHandlingPanelOKButton {
self.toolchainPref = openPanel.URL!.path! self.toolchainPref = openPanel.url!.path
} }
}) })
} }
func panel(sender: AnyObject, shouldEnableURL url: NSURL) -> Bool { func panel(_ sender: AnyObject, shouldEnable url: URL) -> Bool {
let gccPath = url.URLByAppendingPathComponent("bin/avr-gcc") let gccPath = url.URLByAppendingPathComponent("bin/avr-gcc")
return NSFileManager.defaultManager().fileExistsAtPath(gccPath.path!) return FileManager.defaultManager().fileExistsAtPath(gccPath.path!)
} }
} }

View File

@ -9,21 +9,21 @@
import Swift import Swift
import Cocoa import Cocoa
private var keyboardHandler : ACEKeyboardHandler = .Ace private var keyboardHandler : ACEKeyboardHandler = .ace
func pushToFront(inout list: [String], front: String) { func pushToFront( list: inout [String], front: String) {
let kMaxRecents = 8 let kMaxRecents = 8
if let existing = list.indexOf(front) { if let existing = list.index(of: front) {
if existing == 0 { if existing == 0 {
return return
} else { } else {
list.removeAtIndex(existing) list.remove(at: existing)
} }
} else if list.count >= kMaxRecents { } else if list.count >= kMaxRecents {
list.removeLast() list.removeLast()
} }
list.insert(front, atIndex: 0) list.insert(front, at: 0)
} }
class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePanelDelegate, ACEViewDelegate { class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePanelDelegate, ACEViewDelegate {
@ -39,7 +39,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
let files = ASFileTree() let files = ASFileTree()
let builder = ASBuilder() let builder = ASBuilder()
var mainEditor : ASFileNode? var mainEditor : ASFileNode?
var currentTheme : ACETheme = .Xcode var currentTheme : ACETheme = .xcode
var fontSize : UInt = 12 var fontSize : UInt = 12
var themeObserver : AnyObject! var themeObserver : AnyObject!
var serialObserver : AnyObject! var serialObserver : AnyObject!
@ -48,9 +48,9 @@ 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() var logModified = NSDate.distantPast
var logSize = 0 var logSize = 0
var updateLogTimer : NSTimer? var updateLogTimer : Timer?
var printingDone : () -> () = {} var printingDone : () -> () = {}
var printModDate : NSDate? var printModDate : NSDate?
var printRevision : String? var printRevision : String?
@ -74,26 +74,26 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
override init() { override init() {
super.init() super.init()
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
if let themeName = userDefaults.stringForKey(kThemeKey) { if let themeName = userDefaults.string(forKey: kThemeKey) {
if let themeId = ACEView.themeIdByName(themeName) { if let themeId = ACEView.themeIdByName(themeName: themeName) {
currentTheme = themeId currentTheme = themeId
} }
} }
if let handlerName = userDefaults.stringForKey(kBindingsKey) { if let handlerName = userDefaults.string(forKey: kBindingsKey) {
if let handlerId = ACEView.handlerIdByName(handlerName) { if let handlerId = ACEView.handlerIdByName(handlerName: handlerName) {
keyboardHandler = handlerId keyboardHandler = handlerId
} }
} }
fontSize = UInt(userDefaults.integerForKey(kFontSizeKey)) fontSize = UInt(userDefaults.integer(forKey: kFontSizeKey))
board = userDefaults.stringForKey(kBoardKey)! board = userDefaults.string(forKey: kBoardKey)!
programmer = userDefaults.stringForKey(kProgrammerKey)! programmer = userDefaults.string(forKey: kProgrammerKey)!
port = userDefaults.stringForKey(kPortKey)! port = userDefaults.string(forKey: kPortKey)!
recentBoards = userDefaults.objectForKey(kRecentBoardsKey) as! [String] recentBoards = userDefaults.object(forKey: kRecentBoardsKey) as! [String]
recentProgrammers = userDefaults.objectForKey(kRecentProgrammersKey) as! [String] recentProgrammers = userDefaults.object(forKey: kRecentProgrammersKey) as! [String]
let nc = NSNotificationCenter.defaultCenter() let nc = NotificationCenter.default
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)
}) })
@ -103,15 +103,15 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
} }
}) })
updateLogTimer = updateLogTimer =
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "updateLog:", userInfo: nil, repeats: true) Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ASProjDoc.updateLog(_:)), userInfo: nil, repeats: true)
} }
override func finalize() { override func finalize() {
saveCurEditor() saveCurEditor()
NSNotificationCenter.defaultCenter().removeObserver(themeObserver) NotificationCenter.default.removeObserver(themeObserver)
NSNotificationCenter.defaultCenter().removeObserver(serialObserver) NotificationCenter.default.removeObserver(serialObserver)
} }
override func windowControllerDidLoadNib(aController: NSWindowController) { override func windowControllerDidLoadNib(_ aController: NSWindowController) {
super.windowControllerDidLoadNib(aController) super.windowControllerDidLoadNib(aController)
editor.setShowPrintMargin(false) editor.setShowPrintMargin(false)
editor.setTheme(currentTheme) editor.setTheme(currentTheme)
@ -124,11 +124,11 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
auxEdit.setKeyboardHandler(keyboardHandler) auxEdit.setKeyboardHandler(keyboardHandler)
auxEdit.setFontSize(fontSize) auxEdit.setFontSize(fontSize)
editors.setViews([editor], inGravity: .Top) editors.setViews([editor], in: .top)
outline.registerForDraggedTypes([files.kLocalReorderPasteboardType]) outline.register(forDraggedTypes: [files.kLocalReorderPasteboardType])
outline.setDraggingSourceOperationMask(NSDragOperation.Every, forLocal: true) outline.setDraggingSourceOperationMask(NSDragOperation.every, forLocal: true)
outline.setDraggingSourceOperationMask(NSDragOperation.None, forLocal: false) outline.setDraggingSourceOperationMask([], forLocal: false)
outline.setDataSource(files) outline.setDataSource(files)
files.apply() { node in files.apply() { node in
@ -142,7 +142,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
menuNeedsUpdate(boardTool.menu!) menuNeedsUpdate(boardTool.menu!)
menuNeedsUpdate(progTool.menu!) menuNeedsUpdate(progTool.menu!)
rebuildPortMenu() rebuildPortMenu()
updateChangeCount(.ChangeCleared) updateChangeCount(.changeCleared)
} }
override class func autosavesInPlace() -> Bool { override class func autosavesInPlace() -> Bool {
@ -160,7 +160,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
func saveCurEditor() { func saveCurEditor() {
if let file = (mainEditor as? ASFileItem) { if let file = (mainEditor as? ASFileItem) {
do { do {
try editor.string().writeToURL(file.url, atomically: true, encoding: NSUTF8StringEncoding) try editor.string().writeToURL(file.url, atomically: true, encoding: String.Encoding.utf8)
} catch _ { } catch _ {
} }
} }
@ -168,7 +168,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
override func dataOfType(typeName: String) throws -> NSData { override func dataOfType(typeName: String) throws -> NSData {
let data = [kVersionKey: kCurVersion, let data = [kVersionKey: kCurVersion,
kThemeKey: ACEThemeNames.nameForTheme(currentTheme), kThemeKey: ACEThemeNames.name(for: currentTheme),
kFontSizeKey: fontSize, kFontSizeKey: fontSize,
kFilesKey: files.propertyList(), kFilesKey: files.propertyList(),
kBoardKey: board, kBoardKey: board,
@ -177,23 +177,23 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
kRecentBoardsKey: recentBoards, kRecentBoardsKey: recentBoards,
kRecentProgrammersKey: recentProgrammers kRecentProgrammersKey: recentProgrammers
] ]
return try NSPropertyListSerialization.dataWithPropertyList(data, format:.XMLFormat_v1_0, options:0) return try PropertyListSerialization.dataWithPropertyList(data, format:.XMLFormat_v1_0, options:0)
} }
func updateProjectURL() { func updateProjectURL() {
files.setProjectURL(fileURL!) files.setProjectURL(url: fileURL!)
builder.setProjectURL(fileURL!) builder.setProjectURL(url: fileURL!)
} }
func importProject(url: NSURL) throws { func importProject(url: NSURL) throws {
let existingProject = url.URLByAppendingPathComponent(url.lastPathComponent!+".avrsackproj") let existingProject = url.appendingPathComponent(url.lastPathComponent!+".avrsackproj")
if existingProject.checkResourceIsReachableAndReturnError(nil) { if existingProject.checkResourceIsReachableAndReturnError(nil) {
fileURL = existingProject fileURL = existingProject
try readFromURL(existingProject, ofType:"Project") try readFromURL(url: existingProject, ofType:"Project")
return return
} }
let filesInProject = let filesInProject =
(try NSFileManager.defaultManager().contentsOfDirectoryAtURL(url, includingPropertiesForKeys: nil, (try FileManagerefaultManager().contentsOfDirectoryAtURL(url, includingPropertiesForKeys: nil,
options: .SkipsHiddenFiles)) options: .SkipsHiddenFiles))
updateProjectURL() updateProjectURL()
for file in filesInProject { for file in filesInProject {
@ -204,7 +204,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
override func readFromURL(url: NSURL, ofType typeName: String) throws { override func readFromURL(url: NSURL, ofType typeName: String) throws {
if typeName == "Arduino Source File" { if typeName == "Arduino Source File" {
let projectURL = url.URLByDeletingPathExtension!.URLByAppendingPathExtension("avrsackproj") let projectURL = url.URLByDeletingPathExtension!.URLByAppendingPathExtension("avrsackproj")
try importProject(url.URLByDeletingLastPathComponent!) try importProject(url: url.deletingLastPathComponent!)
fileURL = projectURL fileURL = projectURL
try writeToURL(projectURL, ofType: "Project", forSaveOperation: .SaveAsOperation, originalContentsURL: nil) try writeToURL(projectURL, ofType: "Project", forSaveOperation: .SaveAsOperation, originalContentsURL: nil)
} else { } else {
@ -218,7 +218,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
} }
updateProjectURL() updateProjectURL()
let projectData = let projectData =
(try NSPropertyListSerialization.propertyListWithData(data, options:[], format:nil)) as! NSDictionary (try PropertyListSerialization.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 {
@ -235,11 +235,11 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
port = (projectData[kPortKey] as? String) ?? port port = (projectData[kPortKey] as? String) ?? port
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)
} }
override func duplicateDocument(sender: AnyObject?) { override func duplicate(_ sender: AnyObject?) {
let app = NSApplication.sharedApplication().delegate as! ASApplication let app = NSApplication.shared().delegate as! ASApplication
app.openTemplate(fileURL!.URLByDeletingLastPathComponent!, fromReadOnly:false) app.openTemplate(fileURL!.URLByDeletingLastPathComponent!, fromReadOnly:false)
} }
@ -258,7 +258,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
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 = try? NSString(contentsOfURL:url!, usedEncoding:&enc) let newText = try? NSString(contentsOfURL:url!, usedEncoding:&enc)
editor.setString((newText as? String) ?? "") editor.setString((newText as? String) ?? "")
@ -282,9 +282,9 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
mainEditor = selection mainEditor = selection
} else if selection is 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() logModified = NSDate.distantPast
logSize = -1 logSize = -1
mainEditor = selection mainEditor = selection
updateLog(nil) updateLog(nil)
@ -293,7 +293,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
} }
} }
func selectNodeInOutline(selection: ASFileNode) { func selectNodeInOutline(selection: ASFileNode) {
let selectedIndexes = NSIndexSet(index: outline.rowForItem(selection)) let selectedIndexes = NSIndexSet(index: outline.row(forItem: selection))
outline.selectRowIndexes(selectedIndexes, byExtendingSelection: false) outline.selectRowIndexes(selectedIndexes, byExtendingSelection: false)
} }
func selectedFiles() -> [ASFileItem] { func selectedFiles() -> [ASFileItem] {
@ -308,7 +308,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
// MARK: Printing // MARK: Printing
override func printDocumentWithSettings(printSettings: [String : AnyObject], showPrintPanel: Bool, delegate: AnyObject?, didPrintSelector: Selector, contextInfo: UnsafeMutablePointer<Void>) { override func print(withSettings printSettings: [String : AnyObject], showPrintPanel: Bool, delegate: AnyObject?, didPrint didPrintSelector: Selector?, contextInfo: UnsafeMutablePointer<Void>) {
printingDone = printingDone =
{ () -> () in { () -> () in
InvokeCallback(delegate, didPrintSelector, contextInfo); InvokeCallback(delegate, didPrintSelector, contextInfo);
@ -365,7 +365,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
if let editorName = mainEditor?.name { if let editorName = mainEditor?.name {
printOp.jobTitle = editorName printOp.jobTitle = editorName
} else if let fileName = fileURL?.lastPathComponent { } else if let fileName = fileURL?.lastPathComponent {
printOp.jobTitle = (fileName as NSString).stringByDeletingLastPathComponent printOp.jobTitle = (fileName as NSString).deletingLastPathComponent
} else { } else {
printOp.jobTitle = "Untitled" printOp.jobTitle = "Untitled"
} }
@ -380,12 +380,12 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
return 20.0 return 20.0
} }
func drawPrintHeaderForPage(pageNo: Int32, inRect r: NSRect) { func drawPrintHeader(forPage pageNo: Int32, in r: NSRect) {
var rect = r var rect = r
rect.origin.y += 5.0 rect.origin.y += 5.0
rect.size.height -= 5.0 rect.size.height -= 5.0
let ctx = NSGraphicsContext.currentContext()! let ctx = NSGraphicsContext.current()!
ctx.saveGraphicsState() ctx.saveGraphicsState()
NSColor(white: 0.95, alpha: 1.0).setFill() NSColor(white: 0.95, alpha: 1.0).setFill()
var wideBox = rect var wideBox = rect
@ -400,59 +400,59 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
NSRectFill(pageNoBox) NSRectFill(pageNoBox)
ctx.restoreGraphicsState() ctx.restoreGraphicsState()
let pageNoFont = NSFont.userFixedPitchFontOfSize(25.0)! let pageNoFont = NSFont.userFixedPitchFont(ofSize: 25.0)!
let pageNoAttr = [ let pageNoAttr = [
NSFontAttributeName: pageNoFont, NSFontAttributeName: pageNoFont,
NSForegroundColorAttributeName: NSColor.whiteColor(), NSForegroundColorAttributeName: NSColor.white,
NSStrokeWidthAttributeName: -5.0] NSStrokeWidthAttributeName: -5.0]
let pageNoStr = "\(pageNo)" let pageNoStr = "\(pageNo)"
let pageNoSize = pageNoStr.sizeWithAttributes(pageNoAttr) let pageNoSize = pageNoStr.size(withAttributes: pageNoAttr)
let pageNoAt = NSPoint( let pageNoAt = NSPoint(
x: pageNoBox.origin.x+0.5*(pageNoBox.size.width-pageNoSize.width), x: pageNoBox.origin.x+0.5*(pageNoBox.size.width-pageNoSize.width),
y: pageNoBox.origin.y+3.5) y: pageNoBox.origin.y+3.5)
pageNoStr.drawAtPoint(pageNoAt, withAttributes:pageNoAttr) pageNoStr.draw(at: pageNoAt, withAttributes:pageNoAttr)
let kXOffset : CGFloat = 5.0 let kXOffset : CGFloat = 5.0
let titleFont = NSFont.userFontOfSize(12.0)! let titleFont = NSFont.userFont(ofSize: 12.0)!
let titleAttr = [NSFontAttributeName:titleFont] let titleAttr = [NSFontAttributeName:titleFont]
var titleAt = NSPoint( var titleAt = NSPoint(
x: wideBox.origin.x+kXOffset, x: wideBox.origin.x+kXOffset,
y: wideBox.origin.y+0.5*(wideBox.size.height-titleFont.ascender+titleFont.descender)) y: wideBox.origin.y+0.5*(wideBox.size.height-titleFont.ascender+titleFont.descender))
if let fileNameStr = mainEditor?.name { if let fileNameStr = mainEditor?.name {
fileNameStr.drawAtPoint(titleAt, withAttributes:titleAttr) fileNameStr.draw(at: titleAt, withAttributes:titleAttr)
} }
if let projectNameStr = fileURL?.lastPathComponent { if let projectNameStr = fileURL?.lastPathComponent {
let projectNameTrimmed = (projectNameStr as NSString).stringByDeletingPathExtension let projectNameTrimmed = (projectNameStr as NSString).deletingPathExtension
let projectNameSize = projectNameTrimmed.sizeWithAttributes(titleAttr) let projectNameSize = projectNameTrimmed.size(withAttributes: titleAttr)
titleAt.x = wideBox.origin.x+wideBox.size.width-projectNameSize.width-kXOffset titleAt.x = wideBox.origin.x+wideBox.size.width-projectNameSize.width-kXOffset
projectNameTrimmed.drawAtPoint(titleAt, withAttributes:titleAttr) projectNameTrimmed.draw(at: titleAt, withAttributes:titleAttr)
} }
} }
func drawPrintFooterForPage(pageNo: Int32, inRect r: NSRect) { func drawPrintFooter(forPage pageNo: Int32, in r: NSRect) {
var rect = r var rect = r
rect.size.height -= 5.0 rect.size.height -= 5.0
let ctx = NSGraphicsContext.currentContext()! let ctx = NSGraphicsContext.current()!
ctx.saveGraphicsState() ctx.saveGraphicsState()
NSColor(white: 0.95, alpha: 1.0).setFill() NSColor(white: 0.95, alpha: 1.0).setFill()
NSRectFill(rect) NSRectFill(rect)
ctx.restoreGraphicsState() ctx.restoreGraphicsState()
let kXOffset : CGFloat = 5.0 let kXOffset : CGFloat = 5.0
let footFont = NSFont.userFixedPitchFontOfSize(10.0)! let footFont = NSFont.userFixedPitchFont(ofSize: 10.0)!
let footAttr = [NSFontAttributeName:footFont] let footAttr = [NSFontAttributeName:footFont]
var footAt = NSPoint( var footAt = NSPoint(
x: rect.origin.x+kXOffset, x: rect.origin.x+kXOffset,
y: rect.origin.y+0.5*(rect.size.height-footFont.ascender+footFont.descender)) y: rect.origin.y+0.5*(rect.size.height-footFont.ascender+footFont.descender))
if let revisionStr = printRevision { if let revisionStr = printRevision {
revisionStr.drawAtPoint(footAt, withAttributes:footAttr) revisionStr.draw(at: footAt, withAttributes:footAttr)
} }
if let modDate = printModDate if let modDate = printModDate
{ {
let dateFormatter = NSDateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm" dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let modDateStr = dateFormatter.stringFromDate(modDate) let modDateStr = dateFormatter.stringFromDate(modDate)
let modDateSize = modDateStr.sizeWithAttributes(footAttr) let modDateSize = modDateStr.sizeWithAttributes(footAttr)
@ -467,41 +467,41 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
// MARK: Outline View Delegate // MARK: Outline View Delegate
func outlineViewSelectionDidChange(notification: NSNotification) { func outlineViewSelectionDidChange(_ notification: Notification) {
willChangeValueForKey("hasSelection") willChangeValue(forKey: "hasSelection")
if !jumpingToIssue { if !jumpingToIssue {
editors.setViews([], inGravity: .Bottom) editors.setViews([], in: .bottom)
} }
if outline.numberOfSelectedRows < 2 { if outline.numberOfSelectedRows < 2 {
selectNode(outline.itemAtRow(outline.selectedRow) as! ASFileNode?) selectNode(selection: outline.item(atRow: outline.selectedRow) as! ASFileNode?)
} }
didChangeValueForKey("hasSelection") didChangeValue(forKey: "hasSelection")
} }
func outlineViewItemDidExpand(notification: NSNotification) { func outlineViewItemDidExpand(_ notification: Notification) {
let group = notification.userInfo!["NSObject"] as! ASFileGroup let group = notification.userInfo!["NSObject"] as! ASFileGroup
group.expanded = true group.expanded = true
updateChangeCount(.ChangeDone) updateChangeCount(.changeDone)
} }
func outlineViewItemDidCollapse(notification: NSNotification) { func outlineViewItemDidCollapse(_ notification: Notification) {
let group = notification.userInfo!["NSObject"] as! ASFileGroup let group = notification.userInfo!["NSObject"] as! ASFileGroup
group.expanded = false group.expanded = false
updateChangeCount(.ChangeDone) updateChangeCount(.changeDone)
} }
func outlineView(outlineView: NSOutlineView, willDisplayCell cell: AnyObject, forTableColumn tableColumn: NSTableColumn?, item: AnyObject) { func outlineView(_ outlineView: NSOutlineView, willDisplayCell cell: AnyObject, for tableColumn: NSTableColumn?, item: AnyObject) {
if let textCell = cell as? NSTextFieldCell { if let textCell = cell as? NSTextFieldCell {
textCell.textColor = NSColor.blackColor() textCell.textColor = NSColor.blackColor
if item === files.root || item === files.buildLog || item === files.uploadLog || item === files.disassembly { if item === files.root || item === files.buildLog || item === files.uploadLog || item === files.disassembly {
textCell.font = NSFont.boldSystemFontOfSize(13.0) textCell.font = NSFont.boldSystemFont(ofSize: 13.0)
} else { } else {
textCell.font = NSFont.systemFontOfSize(13.0) textCell.font = NSFont.systemFont(ofSize: 13.0)
if !(item as! ASFileNode).exists() { if !(item as! ASFileNode).exists() {
textCell.textColor = NSColor.redColor() textCell.textColor = NSColor.redColor
} }
} }
} }
} }
func outlineView(outlineView: NSOutlineView, shouldTrackCell cell: NSCell, forTableColumn tableColumn: NSTableColumn?, item: AnyObject) -> Bool { func outlineView(_ outlineView: NSOutlineView, shouldTrackCell cell: NSCell, for tableColumn: NSTableColumn?, item: AnyObject) -> Bool {
return outlineView.isRowSelected(outlineView.rowForItem(item)) return outlineView.isRowSelected(outlineView.row(forItem: item))
} }
// MARK: File manipulation // MARK: File manipulation
@ -519,12 +519,12 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
let alert = NSAlert() let alert = NSAlert()
alert.messageText = alert.messageText =
"Do you want to move the \(name) to the Trash, or only remove the \(ref)?" "Do you want to move the \(name) to the Trash, or only remove the \(ref)?"
alert.addButtonWithTitle("Move to Trash") alert.addButton(withTitle: "Move to Trash")
alert.addButtonWithTitle(selection.count == 1 ? "Remove Reference" : "Remove References") alert.addButton(withTitle: selection.count == 1 ? "Remove Reference" : "Remove References")
alert.addButtonWithTitle("Cancel") alert.addButton(withTitle: "Cancel")
alert.buttons[0].keyEquivalent = "" alert.buttons[0].keyEquivalent = ""
alert.buttons[1].keyEquivalent = "\r" alert.buttons[1].keyEquivalent = "\r"
alert.beginSheetModalForWindow(outline.window!) { (response) in alert.beginSheetModal(for: outline.window!) { (response) in
if response != NSAlertThirdButtonReturn { if response != NSAlertThirdButtonReturn {
if response == NSAlertFirstButtonReturn { if response == NSAlertFirstButtonReturn {
NSWorkspace.sharedWorkspace().recycleURLs(selection.map {$0.url}, completionHandler:nil) NSWorkspace.sharedWorkspace().recycleURLs(selection.map {$0.url}, completionHandler:nil)
@ -532,9 +532,9 @@ 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 group.children.enumerate() { for (groupIdx, groupItem) in group.children.enumerated() {
if file as ASFileNode === groupItem { if file as ASFileNode === groupItem {
group.children.removeAtIndex(groupIdx) group.children.remove(at: groupIdx)
break break
} }
} }
@ -543,7 +543,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
} }
self.outline.deselectAll(self) self.outline.deselectAll(self)
self.outline.reloadData() self.outline.reloadData()
self.updateChangeCount(.ChangeDone) self.updateChangeCount(.changeDone)
} }
} }
} }
@ -555,20 +555,20 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
panel.allowsMultipleSelection = true panel.allowsMultipleSelection = true
panel.allowedFileTypes = ["h", "hpp", "hh", "c", "cxx", "c++", "cpp", "cc", "ino", "s", "md"] panel.allowedFileTypes = ["h", "hpp", "hh", "c", "cxx", "c++", "cpp", "cc", "ino", "s", "md"]
panel.delegate = self panel.delegate = self
panel.beginSheetModalForWindow(outline.window!, completionHandler: { (returnCode: Int) -> Void in panel.beginSheetModal(for: outline.window!, completionHandler: { (returnCode: Int) -> Void in
if returnCode == NSFileHandlingPanelOKButton { if returnCode == NSFileHandlingPanelOKButton {
for url in panel.URLs { for url in panel.urls {
self.files.addFileURL(url) self.files.addFileURL(url: url)
} }
self.outline.deselectAll(self) self.outline.deselectAll(self)
self.outline.reloadData() self.outline.reloadData()
self.updateChangeCount(.ChangeDone) self.updateChangeCount(.changeDone)
} }
}) })
} }
func panel(panel:AnyObject, shouldEnableURL url:NSURL) -> Bool { func panel(_ panel:AnyObject, shouldEnable url:URL) -> Bool {
var shouldEnable = true var shouldEnable = true
var resourceID : AnyObject? var resourceID : AnyObject?
guard ((try? url.getResourceValue(&resourceID, forKey:NSURLFileResourceIdentifierKey)) != nil) else { guard ((try? url.getResourceValue(&resourceID, forKey:NSURLFileResourceIdentifierKey)) != nil) else {
@ -577,7 +577,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
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?
if (try? file.url.getResourceValue(&thisID, forKey:NSURLFileResourceIdentifierKey)) != nil { if (try? file.url.getResourceValue(&thisID, forKey:URLResourceKey.fileResourceIdentifierKey)) != nil {
if thisID != nil && resourceID!.isEqual(thisID!) { if thisID != nil && resourceID!.isEqual(thisID!) {
shouldEnable = false shouldEnable = false
} }
@ -592,7 +592,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
} }
func createFileAtURL(url:NSURL) { func createFileAtURL(url:NSURL) {
let type = ASFileType.guessForURL(url) let type = ASFileType.guessForURL(url: url)
var firstPfx = "" var firstPfx = ""
var prefix = "" var prefix = ""
var lastPfx = "" var lastPfx = ""
@ -620,7 +620,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
if lastPfx == "" { if lastPfx == "" {
lastPfx = prefix lastPfx = prefix
} }
let dateFmt = NSDateFormatter() let dateFmt = DateFormatter()
dateFmt.dateFormat = "yyyy-MM-dd" dateFmt.dateFormat = "yyyy-MM-dd"
header = firstPfx + "\n" + header = firstPfx + "\n" +
prefix + " Project: " + fileURL!.URLByDeletingLastPathComponent!.lastPathComponent! + "\n" + prefix + " Project: " + fileURL!.URLByDeletingLastPathComponent!.lastPathComponent! + "\n" +
@ -629,10 +629,10 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
lastPfx + "\n\n" lastPfx + "\n\n"
} }
do { do {
try header.writeToURL(url, atomically: true, encoding: NSUTF8StringEncoding) try header.writeToURL(url, atomically: true, encoding: String.Encoding.utf8)
} catch _ { } catch _ {
} }
files.addFileURL(url) files.addFileURL(url: url)
outline.reloadData() outline.reloadData()
} }
@ -641,17 +641,17 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
savePanel.allowedFileTypes = savePanel.allowedFileTypes =
[kUTTypeCSource as String, kUTTypeCHeader as String, kUTTypeCPlusPlusSource as String, kUTTypeAssemblyLanguageSource as String, [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.beginSheetModal(for: outline.window!, completionHandler: { (returnCode) -> Void in
if returnCode == NSFileHandlingPanelOKButton { if returnCode == NSFileHandlingPanelOKButton {
self.createFileAtURL(savePanel.URL!) self.createFileAtURL(url: savePanel.url!)
} }
}) })
} }
func importLibrary(lib: String) { func importLibrary(_ lib: String) {
var includes = "" var includes = ""
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
if let files = try? fileManager.contentsOfDirectoryAtPath(lib) { if let files = try? fileManager.contentsOfDirectory(atPath: lib) {
for file in files { for file in files {
if file.hasSuffix(".h") { if file.hasSuffix(".h") {
includes += "#include <\(file)>\n" includes += "#include <\(file)>\n"
@ -660,36 +660,36 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
} }
let 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 = try! NSRegularExpression(pattern: "((?:\\s+|/\\*.*?\\*/|//.*?\\n)*)(.*?\\n)", options: .DotMatchesLineSeparators) 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.firstMatch(in: text as String, options:.anchored, range:NSMakeRange(0, text.length)) {
let range = match.rangeAtIndex(2) let range = match.rangeAt(2)
insert.location = range.location insert.location = range.location
let content = text.substringWithRange(range) let content = text.substring(with: range)
if !content.hasPrefix("#include") { if !content.hasPrefix("#include") {
includes += "\n" includes += "\n"
} }
} }
editor.setString(text.stringByReplacingCharactersInRange(insert, withString: includes)) editor.setString(text.replacingCharacters(in: insert, with: includes))
} }
// MARK: Editor configuration // MARK: Editor configuration
@IBAction func changeTheme(item: NSMenuItem) { @IBAction func changeTheme(item: NSMenuItem) {
currentTheme = ACETheme(rawValue: UInt(item.tag)) ?? .Xcode currentTheme = ACETheme(rawValue: UInt(item.tag)) ?? .xcode
editor.setTheme(currentTheme) editor.setTheme(currentTheme)
NSUserDefaults.standardUserDefaults().setObject( UserDefaults.standard.set(
ACEThemeNames.humanNameForTheme(currentTheme), forKey: kThemeKey) ACEThemeNames.humanName(for: currentTheme), forKey: kThemeKey)
updateChangeCount(.ChangeDone) updateChangeCount(.changeDone)
} }
@IBAction func changeKeyboardHandler(item: NSMenuItem) { @IBAction func changeKeyboardHandler(item: NSMenuItem) {
keyboardHandler = ACEKeyboardHandler(rawValue: UInt(item.tag))! keyboardHandler = ACEKeyboardHandler(rawValue: UInt(item.tag))!
NSUserDefaults.standardUserDefaults().setObject( UserDefaults.standard.set(
ACEKeyboardHandlerNames.humanNameForKeyboardHandler(keyboardHandler), forKey: kBindingsKey) ACEKeyboardHandlerNames.humanName(for: keyboardHandler), forKey: kBindingsKey)
NSNotificationCenter.defaultCenter().postNotificationName(kBindingsKey, object: item) NotificationCenter.defaultCenter.postNotificationName(kBindingsKey, object: item)
} }
override func validateUserInterfaceItem(anItem: NSValidatedUserInterfaceItem) -> Bool { override func validateUserInterfaceItem(_ anItem: NSValidatedUserInterfaceItem) -> Bool {
if let menuItem = anItem as? NSMenuItem { if let menuItem = anItem as? NSMenuItem {
if menuItem.action == "changeTheme:" { if menuItem.action == "changeTheme:" {
menuItem.state = (UInt(menuItem.tag) == currentTheme.rawValue ? NSOnState : NSOffState) menuItem.state = (UInt(menuItem.tag) == currentTheme.rawValue ? NSOnState : NSOffState)
@ -713,21 +713,21 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
@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)
updateChangeCount(.ChangeDone) updateChangeCount(.changeDone)
} }
} }
// MARK: Issues // MARK: Issues
@IBAction func jumpToIssue(sender: AnyObject) { @IBAction func jumpToIssue(sender: AnyObject) {
let direction : Int = (sender as! NSMenuItem).tag let direction : Int = (sender as! NSMenuItem).tag
if editors.viewsInGravity(.Bottom).count == 0 { if editors.views(in: .bottom).count == 0 {
editors.addView(auxEdit, inGravity: .Bottom) editors.addView(auxEdit, in: .bottom)
let url = fileURL?.URLByDeletingLastPathComponent?.URLByAppendingPathComponent(files.buildLog.path) let url = fileURL?.URLByDeletingLastPathComponent?.URLByAppendingPathComponent(files.buildLog.path)
if url == nil { if url == nil {
@ -736,7 +736,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
var enc : UInt = 0 var enc : UInt = 0
let contents = try? NSString(contentsOfURL:url!, usedEncoding:&enc) let contents = try? NSString(contentsOfURL:url!, usedEncoding:&enc)
auxEdit.setString(contents as? String ?? "") 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")
@ -762,13 +762,13 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
jumpingToIssue = true jumpingToIssue = true
var resourceID : AnyObject? var resourceID : AnyObject?
if (try? fileURL.getResourceValue(&resourceID, forKey:NSURLFileResourceIdentifierKey)) != nil && resourceID != nil { if (try? fileURL.getResourceValue(&resourceID, forKey:URLResourceKey.fileResourceIdentifierKey)) != 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?
if (try? file.url.getResourceValue(&thisID, forKey:NSURLFileResourceIdentifierKey)) != nil { if (try? file.url.getResourceValue(&thisID, forKey:URLResourceKey.fileResourceIdentifierKey)) != nil {
if thisID != nil && resourceID!.isEqual(thisID!) { if thisID != nil && resourceID!.isEqual(thisID!) {
self.selectNodeInOutline(node) self.selectNodeInOutline(selection: node)
self.editor.gotoLine(lineNo, column:0, animated:true) self.editor.gotoLine(lineNo, column:0, animated:true)
} }
} }
@ -787,32 +787,32 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
// MARK: Build / Upload // MARK: Build / Upload
@IBAction func buildProject(_: AnyObject) { @IBAction func buildProject(_: AnyObject) {
selectNodeInOutline(files.buildLog) selectNodeInOutline(selection: files.buildLog)
builder.buildProject(board, files: files) builder.buildProject(board: board, files: files)
} }
@IBAction func cleanProject(_: AnyObject) { @IBAction func cleanProject(_: AnyObject) {
builder.cleanProject() builder.cleanProject()
selectNodeInOutline(files.buildLog) selectNodeInOutline(selection: files.buildLog)
} }
func rebuildPortMenu() { func rebuildPortMenu() {
willChangeValueForKey("hasValidPort") willChangeValue(forKey: "hasValidPort")
portTool.removeAllItems() portTool.removeAllItems()
portTool.addItemWithTitle("Title") portTool.addItem(withTitle: "Title")
portTool.addItemsWithTitles(ASSerial.ports()) portTool.addItems(withTitles: ASSerial.ports())
portTool.setTitle(port) portTool.setTitle(port)
didChangeValueForKey("hasValidPort") didChangeValue(forKey: "hasValidPort")
} }
func menuNeedsUpdate(menu: NSMenu) { func menuNeedsUpdate(_ menu: NSMenu) {
switch menu.title { switch menu.title {
case "Boards": case "Boards":
ASHardware.instance().buildBoardsMenu(menu, recentBoards: recentBoards, ASHardware.instance().buildBoardsMenu(menu: menu, recentBoards: recentBoards,
target: self, selector: "selectBoard:") target: self, selector: "selectBoard:")
boardTool.setTitle(selectedBoard) boardTool.setTitle(selectedBoard)
case "Programmers": case "Programmers":
ASHardware.instance().buildProgrammersMenu(menu, recentProgrammers: recentProgrammers, ASHardware.instance().buildProgrammersMenu(menu: menu, recentProgrammers: recentProgrammers,
target: self, selector: "selectProgrammer:") target: self, selector: "selectProgrammer:")
progTool.setTitle(selectedProgrammer) progTool.setTitle(selectedProgrammer)
default: default:
@ -830,14 +830,14 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
if prop["name"] == newBoard { if prop["name"] == newBoard {
board = ident board = ident
pushToFront(&recentBoards, front: board) pushToFront(list: &recentBoards, front: board)
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
var globalBoards = userDefaults.objectForKey(kRecentBoardsKey) as! [String] var globalBoards = userDefaults.object(forKey:kRecentBoardsKey) as! [String]
pushToFront(&globalBoards, front: board) pushToFront(list: &globalBoards, front: board)
userDefaults.setObject(globalBoards, forKey: kRecentBoardsKey) userDefaults.set(globalBoards, forKey: kRecentBoardsKey)
updateChangeCount(.ChangeDone) updateChangeCount(.changeDone)
menuNeedsUpdate(boardTool.menu!) menuNeedsUpdate(boardTool.menu!)
break break
@ -860,14 +860,14 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
if prop["name"] == newProg { if prop["name"] == newProg {
programmer = ident programmer = ident
pushToFront(&recentProgrammers, front: programmer) pushToFront(list: &recentProgrammers, front: programmer)
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
var globalProgs = userDefaults.objectForKey(kRecentProgrammersKey) as! [String] var globalProgs = userDefaults.object(forKey:kRecentProgrammersKey) as! [String]
pushToFront(&globalProgs, front: programmer) pushToFront(list: &globalProgs, front: programmer)
userDefaults.setObject(globalProgs, forKey: kRecentProgrammersKey) userDefaults.set(globalProgs, forKey: kRecentProgrammersKey)
updateChangeCount(.ChangeDone) updateChangeCount(.changeDone)
progTool.setTitle(newProg) progTool.setTitle(newProg)
menuNeedsUpdate(progTool.menu!) menuNeedsUpdate(progTool.menu!)
@ -919,33 +919,33 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
@IBAction func uploadProject(sender: AnyObject) { @IBAction func uploadProject(sender: AnyObject) {
builder.continuation = { builder.continuation = {
self.selectNodeInOutline(self.files.uploadLog) self.selectNodeInOutline(selection: self.files.uploadLog)
dispatch_async(dispatch_get_main_queue(), { dispatch_async(dispatch_get_main_queue(), {
self.builder.uploadProject(self.board, programmer:self.programmer, port:self.port) self.builder.uploadProject(board: self.board, programmer:self.programmer, port:self.port)
}) })
} }
buildProject(sender) buildProject(sender)
} }
@IBAction func uploadTerminal(sender: AnyObject) { @IBAction func uploadTerminal(sender: AnyObject) {
builder.uploadProject(board, programmer:programmer, port:port, mode:.Interactive) builder.uploadProject(board: board, programmer:programmer, port:port, mode:.Interactive)
} }
@IBAction func burnBootloader(sender: AnyObject) { @IBAction func burnBootloader(sender: AnyObject) {
self.selectNodeInOutline(self.files.uploadLog) self.selectNodeInOutline(selection: self.files.uploadLog)
builder.uploadProject(board, programmer:programmer, port:port, mode:.BurnBootloader) builder.uploadProject(board: board, programmer:programmer, port:port, mode:.BurnBootloader)
} }
@IBAction func disassembleProject(sender: AnyObject) { @IBAction func disassembleProject(sender: AnyObject) {
builder.continuation = { builder.continuation = {
self.selectNodeInOutline(self.files.disassembly) self.selectNodeInOutline(selection: self.files.disassembly)
self.builder.disassembleProject(self.board) self.builder.disassembleProject(board: self.board)
} }
buildProject(sender) buildProject(sender)
} }
@IBAction func serialConnect(sender: AnyObject) { @IBAction func serialConnect(sender: AnyObject) {
ASSerialWin.showWindowWithPort(port) ASSerialWin.showWindowWithPort(port: port)
} }
} }

View File

@ -37,14 +37,14 @@ NSString * kASSerialPortsChanged = @"PortsChanged";
watchSlashDev = watchSlashDev =
dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, DISPATCH_VNODE_WRITE, dispatch_get_main_queue()); dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, DISPATCH_VNODE_WRITE, dispatch_get_main_queue());
dispatch_source_set_event_handler(watchSlashDev, ^{ dispatch_source_set_event_handler(watchSlashDev, ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kASSerialPortsChanged object: nil]; [[NotificationCenter defaultCenter] postNotificationName:kASSerialPortsChanged object: nil];
}); });
dispatch_resume(watchSlashDev); dispatch_resume(watchSlashDev);
} }
+ (NSArray<NSString *> *)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 [[FileManager defaultManager] contentsOfDirectoryAtPath:@"/dev" error: nil]) {
if ([[port substringToIndex:2] isEqualToString:@"cu"]) if ([[port substringToIndex:2] isEqualToString:@"cu"])
[cuPorts addObject:[port substringFromIndex:3]]; [cuPorts addObject:[port substringFromIndex:3]];
} }

View File

@ -9,7 +9,7 @@
import Cocoa import Cocoa
private var serialInstances = [String : ASSerialWin]() private var serialInstances = [String : ASSerialWin]()
private var keyboardHandler : ACEKeyboardHandler = .Ace private var keyboardHandler : ACEKeyboardHandler = .ace
class ASSerialWin: NSWindowController { class ASSerialWin: NSWindowController {
@IBOutlet weak var inputLine : NSTextField! @IBOutlet weak var inputLine : NSTextField!
@ -38,12 +38,12 @@ class ASSerialWin: NSWindowController {
var serialData = "" var serialData = ""
var serialObserver : AnyObject! var serialObserver : AnyObject!
var termination : AnyObject! var termination : AnyObject!
dynamic var portHandle : NSFileHandle? dynamic var portHandle : FileHandle?
var currentTheme : ACETheme = .Xcode var currentTheme : ACETheme = .xcode
var fontSize : UInt = 12 var fontSize : UInt = 12
var portDefaults = [String: AnyObject]() var portDefaults = [String: AnyObject]()
var shouldReconnect = false var shouldReconnect = false
dynamic var task : NSTask? dynamic var task : Task?
class func showWindowWithPort(port: String) { class func showWindowWithPort(port: String) {
if let existing = serialInstances[port] { if let existing = serialInstances[port] {
@ -54,13 +54,13 @@ class ASSerialWin: NSWindowController {
newInstance.showWindow(self) newInstance.showWindow(self)
} }
} }
class func showWindowWithPort(port: String, task: NSTask, speed: Int) { class func showWindowWithPort(port: String, task: Task, speed: Int) {
if let existing = serialInstances[port] { if let existing = serialInstances[port] {
existing.showWindowWithTask(task, speed:speed) existing.showWindowWithTask(task: task, speed:speed)
} else { } else {
let newInstance = ASSerialWin(port:port) let newInstance = ASSerialWin(port:port)
serialInstances[port] = newInstance serialInstances[port] = newInstance
newInstance.showWindowWithTask(task, speed:speed) newInstance.showWindowWithTask(task: task, speed:speed)
} }
} }
class func portNeededForUpload(port: String) { class func portNeededForUpload(port: String) {
@ -78,18 +78,18 @@ class ASSerialWin: NSWindowController {
self.init(windowNibName:"ASSerialWin") self.init(windowNibName:"ASSerialWin")
self.port = port self.port = port
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
if let portDef = (userDefaults.objectForKey("SerialDefaults") as! NSDictionary).objectForKey(port) as? [String: AnyObject] { if let portDef = (userDefaults.object(forKey:"SerialDefaults") as! NSDictionary).object(forKey:port) as? [String: AnyObject] {
portDefaults = portDef portDefaults = portDef
} else { } else {
portDefaults["Theme"] = userDefaults.stringForKey("SerialTheme") portDefaults["Theme"] = userDefaults.string(forKey:"SerialTheme")
portDefaults["FontSize"] = userDefaults.objectForKey("FontSize") portDefaults["FontSize"] = userDefaults.object(forKey:"FontSize")
portDefaults["SendCR"] = sendCR portDefaults["SendCR"] = sendCR
portDefaults["SendLF"] = sendLF portDefaults["SendLF"] = sendLF
portDefaults["BaudRate"] = 19200 portDefaults["BaudRate"] = 19200
} }
if let themeId = ACEView.themeIdByName(portDefaults["Theme"] as! String) { if let themeId = ACEView.themeIdByName(themeName: portDefaults["Theme"] as! String) {
currentTheme = themeId currentTheme = themeId
} }
fontSize = portDefaults["FontSize"] as! UInt fontSize = portDefaults["FontSize"] as! UInt
@ -97,13 +97,13 @@ class ASSerialWin: NSWindowController {
sendLF = portDefaults["SendLF"] as! Bool sendLF = portDefaults["SendLF"] as! Bool
baudRate = portDefaults["BaudRate"] as! Int baudRate = portDefaults["BaudRate"] as! Int
if let handlerName = userDefaults.stringForKey("Bindings") { if let handlerName = userDefaults.string(forKey:"Bindings") {
if let handlerId = ACEView.handlerIdByName(handlerName) { if let handlerId = ACEView.handlerIdByName(handlerName: handlerName) {
keyboardHandler = handlerId keyboardHandler = handlerId
} }
} }
let nc = NSNotificationCenter.defaultCenter() let nc = NotificationCenter.default
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")
@ -116,7 +116,7 @@ class ASSerialWin: NSWindowController {
} }
} }
}) })
termination = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification, termination = NotificationCenter.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 {
@ -130,9 +130,9 @@ class ASSerialWin: NSWindowController {
if portHandle != nil { if portHandle != nil {
connect(self) connect(self)
} }
NSNotificationCenter.defaultCenter().removeObserver(serialObserver) NotificationCenter.default.removeObserver(serialObserver)
NSNotificationCenter.defaultCenter().removeObserver(termination) NotificationCenter.default.removeObserver(termination)
serialInstances.removeValueForKey(port) serialInstances.removeValue(forKey: port)
} }
func windowWillClose(notification: NSNotification) { func windowWillClose(notification: NSNotification) {
@ -147,7 +147,7 @@ class ASSerialWin: NSWindowController {
logView.setTheme(currentTheme) logView.setTheme(currentTheme)
logView.setKeyboardHandler(keyboardHandler) logView.setKeyboardHandler(keyboardHandler)
logView.setFontSize(fontSize) logView.setFontSize(fontSize)
logView.setMode(.Text) logView.setMode(.text)
logView.alphaValue = 0.8 logView.alphaValue = 0.8
window?.title = port window?.title = port
if task == nil { if task == nil {
@ -156,15 +156,15 @@ class ASSerialWin: NSWindowController {
super.windowDidLoad() super.windowDidLoad()
} }
func installReader(handle: NSFileHandle?) { func installReader(handle: FileHandle?) {
if let readHandle = handle { if let readHandle = handle {
serialData = "" serialData = ""
logView.setString(serialData) logView.setString(serialData)
readHandle.readabilityHandler = {(handle) in readHandle.readabilityHandler = {(handle) in
let newData = handle.availableDataIgnoringExceptions() let newData = handle.availableDataIgnoringExceptions()
let newString = NSString(data: newData, encoding: NSASCIIStringEncoding) as! String let newString = NSString(data: newData, encoding: String.Encoding.ascii) as! String
self.serialData += newString self.serialData += newString
dispatch_async(dispatch_get_main_queue(), { () -> Void in DispatchQueue.main.async(execute: { () -> Void in
self.logView.setString(self.serialData) self.logView.setString(self.serialData)
if self.scrollToBottom { if self.scrollToBottom {
self.logView.gotoLine(1000000000, column: 0, animated: true) self.logView.gotoLine(1000000000, column: 0, animated: true)
@ -176,19 +176,19 @@ 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.data(using: String.Encoding.ascii, allowLossyConversion: true)!
portHandle?.writeData(data) portHandle?.write(data)
} }
func showWindowWithTask(task: NSTask, speed:Int) { func showWindowWithTask(task: Task, speed:Int) {
if portHandle != nil { if portHandle != nil {
connect(self) connect(self)
} }
baudRate = speed baudRate = speed
self.task = task self.task = task
portHandle = (task.standardInput as! NSPipe).fileHandleForWriting portHandle = (task.standardInput as! Pipe).fileHandleForWriting
showWindow(self) showWindow(self)
installReader((task.standardOutput as? NSPipe)?.fileHandleForReading) installReader(handle: (task.standardOutput as? Pipe)?.fileHandleForReading)
} }
@IBAction func connect(_: AnyObject) { @IBAction func connect(_: AnyObject) {
@ -202,7 +202,7 @@ class ASSerialWin: NSWindowController {
portHandle = nil portHandle = nil
} else { } else {
portHandle = ASSerial.openPort(port, withSpeed: Int32(baudRate)) portHandle = ASSerial.openPort(port, withSpeed: Int32(baudRate))
installReader(portHandle) installReader(handle: portHandle)
} }
} }
func disconnectTemporarily() { func disconnectTemporarily() {
@ -234,27 +234,27 @@ class ASSerialWin: NSWindowController {
// MARK: Editor configuration // MARK: Editor configuration
@IBAction func changeTheme(item: NSMenuItem) { @IBAction func changeTheme(item: NSMenuItem) {
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
currentTheme = ACETheme(rawValue: UInt(item.tag)) ?? .Xcode currentTheme = ACETheme(rawValue: UInt(item.tag)) ?? .xcode
logView.setTheme(currentTheme) logView.setTheme(currentTheme)
let themeName = ACEThemeNames.humanNameForTheme(currentTheme) let themeName = ACEThemeNames.humanName(for: currentTheme)
userDefaults.setObject(themeName, forKey: "SerialTheme") userDefaults.set(themeName, forKey: "SerialTheme")
portDefaults["Theme"] = themeName portDefaults["Theme"] = themeName
updatePortDefaults() updatePortDefaults()
} }
@IBAction func changeKeyboardHandler(item: NSMenuItem) { @IBAction func changeKeyboardHandler(item: NSMenuItem) {
keyboardHandler = ACEKeyboardHandler(rawValue: UInt(item.tag))! keyboardHandler = ACEKeyboardHandler(rawValue: UInt(item.tag))!
NSUserDefaults.standardUserDefaults().setObject( UserDefaults.standard.set(
ACEKeyboardHandlerNames.humanNameForKeyboardHandler(keyboardHandler), forKey: "Bindings") ACEKeyboardHandlerNames.humanName(for: keyboardHandler), forKey: "Bindings")
NSNotificationCenter.defaultCenter().postNotificationName("Bindings", object: item) NotificationCenter.defaultCenter.postNotificationName("Bindings", object: item)
} }
func validateUserInterfaceItem(anItem: NSValidatedUserInterfaceItem) -> Bool { func validateUserInterfaceItem(anItem: NSValidatedUserInterfaceItem) -> Bool {
if let menuItem = anItem as? NSMenuItem { if let menuItem = anItem as? NSMenuItem {
if menuItem.action == "changeTheme:" { if menuItem.action == Selector(("changeTheme:")) {
menuItem.state = (UInt(menuItem.tag) == currentTheme.rawValue ? NSOnState : NSOffState) menuItem.state = (UInt(menuItem.tag) == currentTheme.rawValue ? NSOnState : NSOffState)
return true return true
} else if menuItem.action == "changeKeyboardHandler:" { } else if menuItem.action == Selector(("changeKeyboardHandler:")) {
menuItem.state = (menuItem.tag == Int(keyboardHandler.rawValue) ? NSOnState : NSOffState) menuItem.state = (menuItem.tag == Int(keyboardHandler.rawValue) ? NSOnState : NSOffState)
return true return true
} }
@ -278,22 +278,22 @@ class ASSerialWin: NSWindowController {
} }
func updatePortDefaults() { func updatePortDefaults() {
let userDefaults = NSUserDefaults.standardUserDefaults() let userDefaults = UserDefaults.standard
let sd = userDefaults.objectForKey("SerialDefaults") as! [String: AnyObject] let sd = userDefaults.object(forKey:"SerialDefaults") as! [String: AnyObject]
let serialDefaults = NSMutableDictionary(dictionary: sd) let serialDefaults = NSMutableDictionary(dictionary: sd)
serialDefaults.setValue(NSDictionary(dictionary:portDefaults), forKey:port) serialDefaults.setValue(NSDictionary(dictionary:portDefaults), forKey:port)
userDefaults.setObject(serialDefaults, forKey:"SerialDefaults") userDefaults.set(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.isExtensionHidden = false
savePanel.beginSheetModalForWindow(window!, completionHandler: { (returnCode) -> Void in savePanel.beginSheetModal(for: window!, completionHandler: { (returnCode) -> Void in
if returnCode == NSFileHandlingPanelOKButton { if returnCode == NSFileHandlingPanelOKButton {
do { do {
try self.serialData.writeToURL(savePanel.URL!, atomically:false, encoding:NSUTF8StringEncoding) try self.serialData.write(to: savePanel.url!, atomically:false, encoding:String.Encoding.utf8)
} catch _ { } catch _ {
} }
} }

View File

@ -16,16 +16,16 @@ class ASSketchBook {
} }
class func findSketch(path: String) -> SketchBookItem { class func findSketch(path: String) -> SketchBookItem {
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
var inoSketch = SketchBookItem.Nothing var inoSketch = SketchBookItem.Nothing
let contents = (try! fileManager.contentsOfDirectoryAtPath(path)) let contents = (try! fileManager.contentsOfDirectory(atPath: path))
let nspath = path as NSString let nspath = path as NSString
for item in contents { for item in contents {
switch (item as NSString).pathExtension { switch (item as NSString).pathExtension {
case "avrsackproj": case "avrsackproj":
return .Sketch(nspath.lastPathComponent, nspath.stringByAppendingPathComponent(item)) return .Sketch(nspath.lastPathComponent, nspath.appendingPathComponent(item))
case "ino": case "ino":
inoSketch = .Sketch(nspath.lastPathComponent, nspath.stringByAppendingPathComponent(item)) inoSketch = .Sketch(nspath.lastPathComponent, nspath.appendingPathComponent(item))
default: default:
break break
} }
@ -34,10 +34,10 @@ class ASSketchBook {
} }
private class func enumerateSketches(path: String) -> SketchBookItem { private class func enumerateSketches(path: String) -> SketchBookItem {
let fileManager = NSFileManager.defaultManager() let fileManager = FileManager.default
let contents = (try! fileManager.contentsOfDirectoryAtPath(path)) let contents = (try! fileManager.contentsOfDirectory(atPath: path))
let nspath = path as NSString let nspath = path as NSString
let sketch = findSketch(path) let sketch = findSketch(path: path)
switch sketch { switch sketch {
case .Sketch: case .Sketch:
return sketch return sketch
@ -46,10 +46,10 @@ class ASSketchBook {
} }
var sketches = [SketchBookItem]() var sketches = [SketchBookItem]()
for item in contents { for item in contents {
let subpath = nspath.stringByAppendingPathComponent(item) let subpath = nspath.appendingPathComponent(item)
var isDir : ObjCBool = false var isDir : ObjCBool = false
if fileManager.fileExistsAtPath(subpath, isDirectory: &isDir) && isDir { if fileManager.fileExists(atPath: subpath, isDirectory: &isDir) && isDir.boolValue {
let subEnum = enumerateSketches(subpath) let subEnum = enumerateSketches(path: subpath)
switch subEnum { switch subEnum {
case .Nothing: case .Nothing:
break break
@ -58,7 +58,7 @@ class ASSketchBook {
} }
} }
} }
sketches.sortInPlace({ (a: SketchBookItem, b: SketchBookItem) -> Bool in sketches.sort(by: { (a: SketchBookItem, b: SketchBookItem) -> Bool in
var itemA : String = "" var itemA : String = ""
switch a { switch a {
case .Sketch(let item, _): case .Sketch(let item, _):
@ -80,32 +80,32 @@ class ASSketchBook {
return sketches.count > 0 ? .SketchDir(nspath.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], sketches: inout [String]) {
for sketch in sketchList { for sketch in sketchList {
switch (sketch) { switch (sketch) {
case .Sketch(let item, let path): case .Sketch(let item, let path):
let menuItem = menu.addItemWithTitle(item, action: action, keyEquivalent: "") let menuItem = menu.addItem(withTitle: item, action: action, keyEquivalent: "")
menuItem?.target = target menuItem.target = target
menuItem?.tag = sketches.count menuItem.tag = sketches.count
sketches.append(path) sketches.append(path)
case .SketchDir(let item, let subSketches): case .SketchDir(let item, let subSketches):
let menuItem = menu.addItemWithTitle(item, action: nil, keyEquivalent: "") let menuItem = menu.addItem(withTitle: item, action: nil, keyEquivalent: "")
let submenu = NSMenu() let submenu = NSMenu()
submenu.autoenablesItems = false submenu.autoenablesItems = false
appendSketchesToMenu(submenu, target: target, action: action, sketchList: subSketches, sketches: &sketches) appendSketchesToMenu(menu: submenu, target: target, action: action, sketchList: subSketches, sketches: &sketches)
menu.setSubmenu(submenu, forItem: menuItem!) menu.setSubmenu(submenu, for: menuItem)
default: default:
break break
} }
} }
} }
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, sketches: inout [String]) {
switch enumerateSketches(path) { switch enumerateSketches(path: path) {
case .SketchDir(_, let sketchList): case .SketchDir(_, let sketchList):
appendSketchesToMenu(menu, target: target, action: action, sketchList: sketchList, sketches: &sketches) appendSketchesToMenu(menu: menu, target: target, action: action, sketchList: sketchList, sketches: &sketches)
default: default:
break break
} }
} }
} }

View File

@ -54,7 +54,7 @@
<key>CFBundleHelpBookName</key> <key>CFBundleHelpBookName</key>
<string>AVRsack Help</string> <string>AVRsack Help</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>org.aereperennius.$(PRODUCT_NAME:rfc1034identifier)</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>

View File

@ -28,7 +28,7 @@ class AVRsackTests: XCTestCase {
func testPerformanceExample() { func testPerformanceExample() {
// This is an example of a performance test case. // This is an example of a performance test case.
self.measureBlock() { self.measure() {
// Put the code you want to measure the time of here. // Put the code you want to measure the time of here.
} }
} }

View File

@ -7,7 +7,7 @@
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>org.aereperennius.$(PRODUCT_NAME:rfc1034identifier)</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>