Handle board/programmer/port selection
This commit is contained in:
parent
2fd2a10432
commit
8325cf1113
|
@ -26,6 +26,15 @@ class ASPropertyEntry {
|
|||
|
||||
typealias ASProperties = [String: ASPropertyEntry]
|
||||
|
||||
extension NSMenu {
|
||||
func addSortedChoices(choices:[ASPropertyEntry], target: AnyObject, selector: Selector) {
|
||||
for choice in choices.sorted({ $0["name"] < $1["name"] }) {
|
||||
let item = self.addItemWithTitle(choice["name"], action: selector, keyEquivalent: "")
|
||||
item?.target = target
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func subdirectories(path: NSString) -> [NSString] {
|
||||
let fileManager = NSFileManager.defaultManager()
|
||||
var subDirs = [NSString]()
|
||||
|
@ -67,6 +76,7 @@ class ASHardware {
|
|||
//
|
||||
for dir in directories {
|
||||
let boardsPath = dir+"/boards.txt"
|
||||
let provenience = dir.lastPathComponent
|
||||
if let boardsFile = NSString(contentsOfFile: boardsPath, usedEncoding: nil, error: nil) {
|
||||
var seen = [String: Bool]()
|
||||
for line in boardsFile.componentsSeparatedByString("\n") as [NSString] {
|
||||
|
@ -76,17 +86,20 @@ class ASHardware {
|
|||
let value = line.substringWithRange(match.rangeAtIndex(3))
|
||||
if seen.updateValue(true, forKey: board) == nil {
|
||||
boards[board] = ASPropertyEntry()
|
||||
boards[board]!["provenience"] = provenience
|
||||
}
|
||||
boards[board]![property] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Gather programmer declarations
|
||||
//
|
||||
for dir in directories {
|
||||
let programmersPath = dir+"/programmers.txt"
|
||||
let provenience = dir.lastPathComponent
|
||||
if let programmersFile = NSString(contentsOfFile: programmersPath, usedEncoding: nil, error: nil) {
|
||||
var seen = [String: Bool]()
|
||||
for line in programmersFile.componentsSeparatedByString("\n") as [NSString] {
|
||||
|
@ -96,7 +109,7 @@ class ASHardware {
|
|||
let value = line.substringWithRange(match.rangeAtIndex(3))
|
||||
if seen.updateValue(true, forKey: programmer) == nil {
|
||||
programmers[programmer] = ASPropertyEntry()
|
||||
seen[programmer] = true
|
||||
programmers[programmer]!["provenience"] = provenience
|
||||
}
|
||||
programmers[programmer]![property] = value
|
||||
}
|
||||
|
@ -104,6 +117,43 @@ class ASHardware {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildMenu(menu:NSMenu, choices:ASProperties, recentChoices:[String], target: AnyObject, selector: Selector) {
|
||||
menu.removeAllItems()
|
||||
if choices.count <= 10 {
|
||||
menu.addSortedChoices([ASPropertyEntry](choices.values), target: target, selector: selector)
|
||||
} else {
|
||||
menu.addSortedChoices(recentChoices.map({ (recent: String) in choices[recent]! }), target: target, selector: selector)
|
||||
menu.addItem(NSMenuItem.separatorItem())
|
||||
var seen = [String: Bool]()
|
||||
for prop in choices.values {
|
||||
seen[prop["provenience"]] = true
|
||||
}
|
||||
var sortedKeys = [String](seen.keys)
|
||||
sortedKeys.sort { $0 < $1 }
|
||||
for provenience in sortedKeys {
|
||||
var subset = [ASPropertyEntry]()
|
||||
for prop in choices.values {
|
||||
if prop["provenience"] == provenience {
|
||||
subset.append(prop)
|
||||
}
|
||||
}
|
||||
let item = menu.addItemWithTitle(provenience, action: nil, keyEquivalent: "")!
|
||||
let submenu = NSMenu()
|
||||
submenu.autoenablesItems = false
|
||||
submenu.addSortedChoices(subset, target: target, selector: selector)
|
||||
menu.setSubmenu(submenu, forItem: item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildBoardsMenu(menu:NSMenu, recentBoards:[String], target: AnyObject, selector: Selector) {
|
||||
buildMenu(menu, choices:boards, recentChoices:recentBoards, target: target, selector: selector)
|
||||
}
|
||||
|
||||
func buildProgrammersMenu(menu:NSMenu, recentProgrammers:[String], target: AnyObject, selector: Selector) {
|
||||
buildMenu(menu, choices:programmers, recentChoices:recentProgrammers, target: target, selector: selector)
|
||||
}
|
||||
}
|
||||
|
||||
private let librariesInstance = ASLibraries()
|
||||
|
|
|
@ -6,22 +6,44 @@
|
|||
// Copyright (c) 2014 Aere Perennius. All rights reserved.
|
||||
//
|
||||
|
||||
import Swift
|
||||
import Cocoa
|
||||
|
||||
private var keyboardHandler : ACEKeyboardHandler = .Ace
|
||||
|
||||
class ASProjDoc: NSDocument, NSOutlineViewDelegate {
|
||||
func pushToFront(inout list: [String], front: String) {
|
||||
let kMaxRecents = 8
|
||||
|
||||
if let existing = find(list, front) {
|
||||
if existing == 0 {
|
||||
return
|
||||
} else {
|
||||
list.removeAtIndex(existing)
|
||||
}
|
||||
} else if list.count >= kMaxRecents {
|
||||
list.removeLast()
|
||||
}
|
||||
list.insert(front, atIndex: 0)
|
||||
}
|
||||
|
||||
class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
|
||||
@IBOutlet weak var editor : ACEView!
|
||||
@IBOutlet weak var outline : NSOutlineView!
|
||||
@IBOutlet weak var boardTool: NSPopUpButton!
|
||||
@IBOutlet weak var progTool : NSPopUpButton!
|
||||
@IBOutlet weak var portTool : NSPopUpButton!
|
||||
|
||||
let files = ASFileTree()
|
||||
let builder = ASBuilder()
|
||||
var mainEditor : ASFileNode?
|
||||
var currentTheme : UInt = 0
|
||||
var fontSize : UInt = 12
|
||||
var themeObserver : AnyObject?
|
||||
var board : String = "uno"
|
||||
var programmer : String = ""
|
||||
var port : String = ""
|
||||
var board = "uno"
|
||||
var programmer = "arduino"
|
||||
var port = ""
|
||||
var recentBoards = [String]()
|
||||
var recentProgrammers = [String]()
|
||||
var logModified = NSDate.distantPast() as NSDate
|
||||
var updateLogTimer : NSTimer?
|
||||
|
||||
|
@ -34,6 +56,8 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate {
|
|||
let kBoardKey = "Board"
|
||||
let kProgrammerKey = "Programmer"
|
||||
let kPortKey = "Port"
|
||||
let kRecentBoardsKey = "RecentBoards"
|
||||
let kRecentProgrammersKey = "RecentProgrammers"
|
||||
|
||||
// MARK: Initialization / Finalization
|
||||
|
||||
|
@ -63,6 +87,8 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate {
|
|||
board = userDefaults.stringForKey(kBoardKey)!
|
||||
programmer = userDefaults.stringForKey(kProgrammerKey)!
|
||||
port = userDefaults.stringForKey(kPortKey)!
|
||||
recentBoards = userDefaults.objectForKey(kRecentBoardsKey) as [String]
|
||||
recentProgrammers = userDefaults.objectForKey(kRecentProgrammersKey) as [String]
|
||||
|
||||
updateLogTimer =
|
||||
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "updateLog:", userInfo: nil, repeats: true)
|
||||
|
@ -88,6 +114,12 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate {
|
|||
}
|
||||
updateChangeCount(.ChangeCleared)
|
||||
outlineViewSelectionDidChange(NSNotification(name: "", object: nil))
|
||||
menuNeedsUpdate(boardTool.menu!)
|
||||
menuNeedsUpdate(progTool.menu!)
|
||||
portTool.removeAllItems()
|
||||
portTool.addItemWithTitle("Title")
|
||||
portTool.addItemsWithTitles(ASSerial.ports())
|
||||
portTool.setTitle(port)
|
||||
}
|
||||
|
||||
override class func autosavesInPlace() -> Bool {
|
||||
|
@ -112,7 +144,11 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate {
|
|||
let data = [kVersionKey: kCurVersion,
|
||||
kThemeKey: ACEThemeNames.nameForTheme(currentTheme),
|
||||
kFontSizeKey: fontSize,
|
||||
kFilesKey: files.propertyList()]
|
||||
kFilesKey: files.propertyList(),
|
||||
kBoardKey: board,
|
||||
kProgrammerKey: programmer,
|
||||
kPortKey: port
|
||||
]
|
||||
return NSPropertyListSerialization.dataFromPropertyList(data, format: .XMLFormat_v1_0, errorDescription: nil)
|
||||
}
|
||||
|
||||
|
@ -168,6 +204,11 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate {
|
|||
fontSize = UInt(fontSz)
|
||||
}
|
||||
files.readPropertyList(projectData[kFilesKey] as NSDictionary)
|
||||
board = (projectData[kBoardKey] as? String) ?? board
|
||||
programmer = (projectData[kProgrammerKey] as? String) ?? programmer
|
||||
port = (projectData[kPortKey] as? String) ?? port
|
||||
recentBoards = (projectData[kRecentBoardsKey] as? [String]) ?? recentBoards
|
||||
recentProgrammers = (projectData[kRecentProgrammersKey] as? [String]) ?? recentProgrammers
|
||||
updateChangeCount(.ChangeCleared)
|
||||
|
||||
return true
|
||||
|
@ -293,25 +334,85 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate {
|
|||
selectNode(files.buildLog)
|
||||
}
|
||||
|
||||
func serialPorts() -> [String] {
|
||||
return ASSerial.ports()
|
||||
func menuNeedsUpdate(menu: NSMenu) {
|
||||
switch menu.title {
|
||||
case "Boards":
|
||||
ASHardware.instance().buildBoardsMenu(menu, recentBoards: recentBoards,
|
||||
target: self, selector: "selectBoard:")
|
||||
boardTool.setTitle(selectedBoard)
|
||||
case "Programmers":
|
||||
ASHardware.instance().buildProgrammersMenu(menu, recentProgrammers: recentProgrammers,
|
||||
target: self, selector: "selectProgrammer:")
|
||||
progTool.setTitle(selectedProgrammer)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func boards() -> [String] {
|
||||
var result = [String]()
|
||||
var selectedBoard : String {
|
||||
get {
|
||||
let boardProps = ASHardware.instance().boards[board]
|
||||
return boardProps?["name"] ?? ""
|
||||
}
|
||||
set (newBoard) {
|
||||
for (ident, prop) in ASHardware.instance().boards {
|
||||
result.append(prop["name"])
|
||||
if prop["name"] == newBoard {
|
||||
board = ident
|
||||
|
||||
pushToFront(&recentBoards, board)
|
||||
|
||||
let userDefaults = NSUserDefaults.standardUserDefaults()
|
||||
var globalBoards = userDefaults.objectForKey(kRecentBoardsKey) as [String]
|
||||
pushToFront(&globalBoards, board)
|
||||
userDefaults.setObject(globalBoards, forKey: kRecentBoardsKey)
|
||||
|
||||
updateChangeCount(.ChangeDone)
|
||||
menuNeedsUpdate(boardTool.menu!)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func programmers() -> [String] {
|
||||
var result = [String]()
|
||||
@IBAction func selectBoard(item: AnyObject) {
|
||||
selectedBoard = (item as NSMenuItem).title
|
||||
}
|
||||
|
||||
var selectedProgrammer : String {
|
||||
get {
|
||||
let progProps = ASHardware.instance().programmers[programmer]
|
||||
return progProps?["name"] ?? ""
|
||||
}
|
||||
set (newProg) {
|
||||
for (ident, prop) in ASHardware.instance().programmers {
|
||||
result.append(prop["name"])
|
||||
if prop["name"] == newProg {
|
||||
programmer = ident
|
||||
|
||||
pushToFront(&recentProgrammers, programmer)
|
||||
|
||||
let userDefaults = NSUserDefaults.standardUserDefaults()
|
||||
var globalProgs = userDefaults.objectForKey(kRecentProgrammersKey) as [String]
|
||||
pushToFront(&globalProgs, programmer)
|
||||
userDefaults.setObject(globalProgs, forKey: kRecentProgrammersKey)
|
||||
|
||||
updateChangeCount(.ChangeDone)
|
||||
progTool.setTitle(newProg)
|
||||
menuNeedsUpdate(progTool.menu!)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@IBAction func selectProgrammer(item: AnyObject) {
|
||||
selectedProgrammer = (item as NSMenuItem).title
|
||||
}
|
||||
|
||||
@IBAction func selectPort(item: AnyObject) {
|
||||
port = (item as NSPopUpButton).titleOfSelectedItem!
|
||||
portTool.setTitle(port)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="ASProjDoc" customModule="AVRsack">
|
||||
<connections>
|
||||
<outlet property="boardTool" destination="xO5-xB-HHj" id="xzX-eY-Ofe"/>
|
||||
<outlet property="editor" destination="Nhg-qn-6A8" id="eUR-Gk-IBw"/>
|
||||
<outlet property="outline" destination="nij-C2-Fna" id="sVi-eL-hqZ"/>
|
||||
<outlet property="portTool" destination="4rZ-U5-AH6" id="8Nb-iI-pJH"/>
|
||||
<outlet property="progTool" destination="08n-xg-fNl" id="959-as-OtP"/>
|
||||
<outlet property="window" destination="xOd-HO-29H" id="JIz-fz-R2o"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
|
@ -112,70 +115,70 @@
|
|||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="A3F4B25E-669B-4AEB-877C-CA0AF13A9E49" label="Board" paletteLabel="Board" id="vAE-60-8kd">
|
||||
<nil key="toolTip"/>
|
||||
<size key="minSize" width="100" height="28"/>
|
||||
<size key="maxSize" width="100" height="28"/>
|
||||
<popUpButton key="view" verticalHuggingPriority="750" id="xO5-xB-HHj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="28"/>
|
||||
<size key="minSize" width="75" height="28"/>
|
||||
<size key="maxSize" width="400" height="28"/>
|
||||
<popUpButton key="view" verticalHuggingPriority="750" allowsExpansionToolTips="YES" id="xO5-xB-HHj">
|
||||
<rect key="frame" x="0.0" y="14" width="75" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="roundTextured" title="Item 1" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" selectedItem="EIo-LP-BL2" id="70v-IV-ury">
|
||||
<popUpButtonCell key="cell" type="roundTextured" title="Item 1" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" pullsDown="YES" selectedItem="BI3-Mj-Hjl" id="70v-IV-ury">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="0W3-Jd-NvF">
|
||||
<menu key="menu" title="Boards" id="0W3-Jd-NvF">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="EIo-LP-BL2"/>
|
||||
<menuItem title="Item 2" id="BI3-Mj-Hjl"/>
|
||||
<menuItem title="Item 1" hidden="YES" id="EIo-LP-BL2"/>
|
||||
<menuItem title="Item 2" state="on" id="BI3-Mj-Hjl"/>
|
||||
<menuItem title="Item 3" id="JVV-uK-XFS"/>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="9Wl-yy-I09"/>
|
||||
</connections>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="contentValues" keyPath="boards" id="I0F-IB-VDu"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="BD8B4827-8CD2-4E50-B435-165CD744B39D" label="Programmer" paletteLabel="Programmer" id="Lt2-Z7-7Pg">
|
||||
<nil key="toolTip"/>
|
||||
<size key="minSize" width="100" height="28"/>
|
||||
<size key="maxSize" width="100" height="28"/>
|
||||
<popUpButton key="view" verticalHuggingPriority="750" id="08n-xg-fNl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="28"/>
|
||||
<size key="minSize" width="75" height="28"/>
|
||||
<size key="maxSize" width="200" height="28"/>
|
||||
<popUpButton key="view" verticalHuggingPriority="750" allowsExpansionToolTips="YES" id="08n-xg-fNl">
|
||||
<rect key="frame" x="0.0" y="14" width="75" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="roundTextured" title="Item 1" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" selectedItem="DL9-Dk-EGd" id="drB-K8-prb">
|
||||
<popUpButtonCell key="cell" type="roundTextured" title="Item 1" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" pullsDown="YES" id="drB-K8-prb">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="I2g-9Y-t88">
|
||||
<menu key="menu" title="Programmers" id="I2g-9Y-t88">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="DL9-Dk-EGd"/>
|
||||
<menuItem title="Item 1" hidden="YES" id="DL9-Dk-EGd"/>
|
||||
<menuItem title="Item 2" id="cbL-7g-Dbs"/>
|
||||
<menuItem title="Item 3" id="VZO-b8-lTE"/>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="C5g-FS-Zb7"/>
|
||||
</connections>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="contentValues" keyPath="programmers" id="6XS-xq-UIC"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="1E69CE88-D7A1-4231-B56C-89C813E75589" label="Serial Port" paletteLabel="Serial Port" id="r8E-ar-tLo">
|
||||
<nil key="toolTip"/>
|
||||
<size key="minSize" width="100" height="28"/>
|
||||
<size key="maxSize" width="100" height="28"/>
|
||||
<popUpButton key="view" verticalHuggingPriority="750" id="4rZ-U5-AH6">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="28"/>
|
||||
<size key="minSize" width="75" height="28"/>
|
||||
<size key="maxSize" width="400" height="28"/>
|
||||
<popUpButton key="view" verticalHuggingPriority="750" allowsExpansionToolTips="YES" id="4rZ-U5-AH6">
|
||||
<rect key="frame" x="0.0" y="14" width="75" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="roundTextured" title="Item 1" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" selectedItem="7U0-rg-90a" id="XSm-NS-ZtW">
|
||||
<popUpButtonCell key="cell" type="roundTextured" title="Item 1" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" pullsDown="YES" selectedItem="7U0-rg-90a" id="XSm-NS-ZtW">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="VO0-bS-zYz">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="7U0-rg-90a"/>
|
||||
<menuItem title="Item 1" state="on" hidden="YES" id="7U0-rg-90a"/>
|
||||
<menuItem title="Item 2" id="rck-gJ-Wwo"/>
|
||||
<menuItem title="Item 3" id="PoP-ir-bnB"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="contentValues" keyPath="serialPorts" id="d9a-Yy-DeA"/>
|
||||
<action selector="selectPort:" target="-2" id="tRd-x3-Oig"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</toolbarItem>
|
||||
|
@ -188,11 +191,11 @@
|
|||
<toolbarItem reference="69r-aN-6vG"/>
|
||||
<toolbarItem reference="FYt-ZW-Epr"/>
|
||||
<toolbarItem reference="lGv-lT-Eh9"/>
|
||||
<toolbarItem reference="2D6-o4-n09"/>
|
||||
<toolbarItem reference="FYt-ZW-Epr"/>
|
||||
<toolbarItem reference="vAE-60-8kd"/>
|
||||
<toolbarItem reference="Lt2-Z7-7Pg"/>
|
||||
<toolbarItem reference="r8E-ar-tLo"/>
|
||||
<toolbarItem reference="2D6-o4-n09"/>
|
||||
<toolbarItem reference="FYt-ZW-Epr"/>
|
||||
<toolbarItem reference="ln2-Ky-MBg"/>
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
|
|
|
@ -2,6 +2,23 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>RecentProgrammers</key>
|
||||
<array>
|
||||
<string>usbasp</string>
|
||||
<string>usbtinyisp</string>
|
||||
<string>avrispmkii</string>
|
||||
<string>avrisp</string>
|
||||
<string>scratchmonkey</string>
|
||||
<string>arduinoisp</string>
|
||||
<string>arduino</string>
|
||||
</array>
|
||||
<key>RecentBoards</key>
|
||||
<array>
|
||||
<string>micro</string>
|
||||
<string>leonardo</string>
|
||||
<string>mega2560</string>
|
||||
<string>uno</string>
|
||||
</array>
|
||||
<key>Port</key>
|
||||
<string></string>
|
||||
<key>Programmer</key>
|
||||
|
|
Loading…
Reference in New Issue
Block a user