Add add/delete files

This commit is contained in:
Matthias Neeracher 2015-01-12 01:53:35 +01:00 committed by Matthias Neeracher
parent 407a4a3793
commit 1e94a7d351
3 changed files with 193 additions and 47 deletions

View File

@ -26,7 +26,7 @@ func pushToFront(inout list: [String], front: String) {
list.insert(front, atIndex: 0) list.insert(front, atIndex: 0)
} }
class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate { class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePanelDelegate {
@IBOutlet weak var editor : ACEView! @IBOutlet weak var editor : ACEView!
@IBOutlet weak var outline : NSOutlineView! @IBOutlet weak var outline : NSOutlineView!
@IBOutlet weak var boardTool: NSPopUpButton! @IBOutlet weak var boardTool: NSPopUpButton!
@ -262,12 +262,25 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
let selectedIndexes = NSIndexSet(index: outline.rowForItem(selection)) let selectedIndexes = NSIndexSet(index: outline.rowForItem(selection))
outline.selectRowIndexes(selectedIndexes, byExtendingSelection: false) outline.selectRowIndexes(selectedIndexes, byExtendingSelection: false)
} }
func selectedFiles() -> [ASFileItem] {
var selection = [ASFileItem]()
outline.selectedRowIndexes.enumerateIndexesUsingBlock() { (index, stop) in
if let file = self.outline.itemAtRow(index) as? ASFileItem {
selection.append(file)
}
}
return selection
}
// MARK: Outline View Delegate // MARK: Outline View Delegate
func outlineViewSelectionDidChange(notification: NSNotification) { func outlineViewSelectionDidChange(notification: NSNotification) {
willChangeValueForKey("hasSelection")
if outline.numberOfSelectedRows < 2 {
selectNode(outline.itemAtRow(outline.selectedRow) as ASFileNode?) selectNode(outline.itemAtRow(outline.selectedRow) as ASFileNode?)
} }
didChangeValueForKey("hasSelection")
}
func outlineViewItemDidExpand(notification: NSNotification) { func outlineViewItemDidExpand(notification: NSNotification) {
let group = notification.userInfo!["NSObject"] as ASFileGroup let group = notification.userInfo!["NSObject"] as ASFileGroup
group.expanded = true group.expanded = true
@ -292,6 +305,91 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
} }
} }
// MARK: File manipulation
@IBAction func delete(AnyObject) {
let selection = selectedFiles()
var name : String
var ref : String
if selection.count == 1 {
name = "file “\(selection[0].url.lastPathComponent)"
ref = "reference to it"
} else {
name = "\(selection.count) selected files"
ref = "references to them"
}
let alert = NSAlert()
alert.messageText =
"Do you want to move the \(name) to the Trash, or only remove the \(ref)?"
alert.addButtonWithTitle("Move to Trash")
alert.addButtonWithTitle(selection.count == 1 ? "Remove Reference" : "Remove References")
alert.addButtonWithTitle("Cancel")
(alert.buttons[0] as NSButton).keyEquivalent = ""
(alert.buttons[1] as NSButton).keyEquivalent = "\r"
alert.beginSheetModalForWindow(outline.window!) { (response) in
if response != NSAlertThirdButtonReturn {
if response == NSAlertFirstButtonReturn {
NSWorkspace.sharedWorkspace().recycleURLs(selection.map {$0.url}, completionHandler:nil)
}
self.files.apply { (node) in
if let group = node as? ASFileGroup {
for file in selection {
for (groupIdx, groupItem) in enumerate(group.children) {
if file as ASFileNode === groupItem {
group.children.removeAtIndex(groupIdx)
break
}
}
}
}
}
self.outline.deselectAll(self)
self.outline.reloadData()
self.updateChangeCount(.ChangeDone)
}
}
}
@IBAction func add(AnyObject) {
let panel = NSOpenPanel()
panel.canChooseFiles = true
panel.canChooseDirectories = false
panel.allowsMultipleSelection = true
panel.allowedFileTypes = ["h", "hpp", "hh", "c", "cxx", "c++", "cpp", "cc", "ino", "s", "md"]
panel.delegate = self
panel.beginSheetModalForWindow(outline.window!, completionHandler: { (returnCode: Int) -> Void in
if returnCode == NSFileHandlingPanelOKButton {
for url in panel.URLs as [NSURL] {
self.files.addFileURL(url)
}
self.outline.deselectAll(self)
self.outline.reloadData()
self.updateChangeCount(.ChangeDone)
}
})
}
func panel(panel:NSSavePanel, shouldEnableURL url:NSURL) -> Bool {
var shouldEnable = true
var resourceID : AnyObject?
url.getResourceValue(&resourceID, forKey:NSURLFileResourceIdentifierKey, error:nil)
files.apply {(node) in
if let file = node as? ASFileItem {
var thisID : AnyObject?
file.url.getResourceValue(&thisID, forKey:NSURLFileResourceIdentifierKey, error:nil)
if thisID != nil && resourceID!.isEqual(thisID!) {
shouldEnable = false
}
}
}
return shouldEnable
}
var hasSelection : Bool {
return selectedFiles().count > 0
}
// MARK: Editor configuration // MARK: Editor configuration
@IBAction func changeTheme(item: NSMenuItem) { @IBAction func changeTheme(item: NSMenuItem) {

View File

@ -19,30 +19,36 @@
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="ProjectWindow" animationBehavior="default" id="xOd-HO-29H" userLabel="Window"> <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="ProjectWindow" animationBehavior="default" id="xOd-HO-29H" userLabel="Window">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" unifiedTitleAndToolbar="YES"/> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" unifiedTitleAndToolbar="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="133" y="235" width="764" height="481"/> <rect key="contentRect" x="133" y="235" width="760" height="500"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/> <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<value key="minSize" type="size" width="94" height="86"/> <value key="minSize" type="size" width="94" height="86"/>
<view key="contentView" id="gIp-Ho-8D9"> <view key="contentView" id="gIp-Ho-8D9">
<rect key="frame" x="0.0" y="0.0" width="764" height="481"/> <rect key="frame" x="0.0" y="0.0" width="760" height="500"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<splitView autosaveName="AVProjDocSplit" dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cSU-e7-KEz"> <splitView autosaveName="AVProjDocSplit" dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cSU-e7-KEz">
<rect key="frame" x="0.0" y="0.0" width="764" height="481"/> <rect key="frame" x="0.0" y="0.0" width="760" height="500"/>
<subviews> <subviews>
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="ObX-J0-NIB"> <box autoresizesSubviews="NO" title="Box" boxType="custom" borderType="none" titlePosition="noTitle" id="0X4-Im-JAh">
<rect key="frame" x="0.0" y="0.0" width="184" height="481"/> <rect key="frame" x="0.0" y="0.0" width="174" height="500"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<clipView key="contentView" id="kme-nx-YDz"> <view key="contentView">
<rect key="frame" x="0.0" y="0.0" width="174" height="500"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ObX-J0-NIB">
<rect key="frame" x="0.0" y="0.0" width="2" height="2"/>
<clipView key="contentView" misplaced="YES" id="kme-nx-YDz">
<rect key="frame" x="1" y="0.0" width="238" height="134"/> <rect key="frame" x="1" y="0.0" width="238" height="134"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" outlineTableColumn="89u-w6-f1G" id="nij-C2-Fna"> <outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" outlineTableColumn="89u-w6-f1G" id="nij-C2-Fna">
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/> <size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns> <tableColumns>
<tableColumn width="179" minWidth="40" maxWidth="1000" id="89u-w6-f1G"> <tableColumn width="40" minWidth="40" maxWidth="1000" id="89u-w6-f1G">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left"> <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@ -63,10 +69,7 @@
</subviews> </subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView> </clipView>
<constraints> <scroller key="horizontalScroller" verticalHuggingPriority="750" horizontal="YES" id="S4E-JC-RgA">
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="50" id="7zq-La-LcG"/>
</constraints>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="S4E-JC-RgA">
<rect key="frame" x="1" y="119" width="223" height="15"/> <rect key="frame" x="1" y="119" width="223" height="15"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
@ -75,8 +78,51 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
</scrollView> </scrollView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Mar-ts-Ae2">
<rect key="frame" x="0.0" y="-1" width="87" height="23"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="eBY-nc-VZ2"/>
</constraints>
<buttonCell key="cell" type="smallSquare" title="" bezelStyle="smallSquare" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Zuz-nM-FTj">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="add:" target="-1" id="2u6-qG-b4q"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nX2-CL-r24">
<rect key="frame" x="87" y="-1" width="87" height="23"/>
<buttonCell key="cell" type="smallSquare" title="" bezelStyle="smallSquare" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bih-cm-8LF">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="delete:" target="-1" id="nhW-e8-rwN"/>
<binding destination="-2" name="enabled" keyPath="hasSelection" id="zBP-Wq-2dR"/>
</connections>
</button>
</subviews>
</view>
<constraints>
<constraint firstItem="nX2-CL-r24" firstAttribute="leading" secondItem="Mar-ts-Ae2" secondAttribute="trailing" id="0rn-RP-nRD"/>
<constraint firstAttribute="trailing" secondItem="ObX-J0-NIB" secondAttribute="trailing" id="3Ap-4y-TqA"/>
<constraint firstItem="Mar-ts-Ae2" firstAttribute="height" secondItem="nX2-CL-r24" secondAttribute="height" id="D6Z-ZC-w6I"/>
<constraint firstItem="nX2-CL-r24" firstAttribute="width" secondItem="Mar-ts-Ae2" secondAttribute="width" id="DQN-Ql-JUB"/>
<constraint firstAttribute="bottom" secondItem="Mar-ts-Ae2" secondAttribute="bottom" id="GFr-dH-HnB"/>
<constraint firstAttribute="trailing" secondItem="nX2-CL-r24" secondAttribute="trailing" id="Pwh-aV-fuf"/>
<constraint firstItem="ObX-J0-NIB" firstAttribute="leading" secondItem="0X4-Im-JAh" secondAttribute="leading" id="Zh7-ms-2Sa"/>
<constraint firstItem="ObX-J0-NIB" firstAttribute="top" secondItem="0X4-Im-JAh" secondAttribute="top" id="dTf-YD-Yhg"/>
<constraint firstItem="ObX-J0-NIB" firstAttribute="bottom" secondItem="Mar-ts-Ae2" secondAttribute="top" id="lLZ-KN-JtG"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="vjU-TE-WcO"/>
<constraint firstItem="Mar-ts-Ae2" firstAttribute="leading" secondItem="0X4-Im-JAh" secondAttribute="leading" id="vsi-w4-onJ"/>
<constraint firstItem="Mar-ts-Ae2" firstAttribute="top" secondItem="nX2-CL-r24" secondAttribute="top" id="zo6-sp-k5r"/>
</constraints>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</box>
<customView id="Nhg-qn-6A8" customClass="ACEView"> <customView id="Nhg-qn-6A8" customClass="ACEView">
<rect key="frame" x="185" y="0.0" width="579" height="481"/> <rect key="frame" x="175" y="0.0" width="585" height="500"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<constraints> <constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="dHZ-ac-XrM"/> <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="dHZ-ac-XrM"/>
@ -224,7 +270,7 @@
<connections> <connections>
<outlet property="delegate" destination="-2" id="0bl-1N-x8E"/> <outlet property="delegate" destination="-2" id="0bl-1N-x8E"/>
</connections> </connections>
<point key="canvasLocation" x="406" y="428.5"/> <point key="canvasLocation" x="408" y="438"/>
</window> </window>
<userDefaultsController representsSharedInstance="YES" id="fpc-q0-yYy"/> <userDefaultsController representsSharedInstance="YES" id="fpc-q0-yYy"/>
</objects> </objects>

View File

@ -192,7 +192,9 @@
</connections> </connections>
</menuItem> </menuItem>
<menuItem title="Delete" id="UeZ-Qa-lhi"> <menuItem title="Delete" id="UeZ-Qa-lhi">
<modifierMask key="keyEquivalentModifierMask"/> <string key="keyEquivalent" base64-UTF8="YES">
CA
</string>
<connections> <connections>
<action selector="delete:" target="-1" id="Vqe-IX-NSW"/> <action selector="delete:" target="-1" id="Vqe-IX-NSW"/>
</connections> </connections>