Implement drag and drop of files in Project view
This commit is contained in:
parent
e5427ae2bb
commit
0ecc67146c
|
@ -54,7 +54,7 @@ private let kNodeTypeGroup = "Group"
|
||||||
private let kNodeTypeFile = "File"
|
private let kNodeTypeFile = "File"
|
||||||
private let kNameKey = "Name"
|
private let kNameKey = "Name"
|
||||||
|
|
||||||
class ASFileNode {
|
class ASFileNode : Equatable {
|
||||||
var name : String
|
var name : String
|
||||||
|
|
||||||
init(name: String) {
|
init(name: String) {
|
||||||
|
@ -97,6 +97,10 @@ class ASFileNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ==(a: ASFileNode, b: ASFileNode) -> Bool {
|
||||||
|
return a === b
|
||||||
|
}
|
||||||
|
|
||||||
class ASLogNode : ASFileNode {
|
class ASLogNode : ASFileNode {
|
||||||
var path : String
|
var path : String
|
||||||
|
|
||||||
|
@ -268,6 +272,7 @@ class ASFileTree : NSObject, NSOutlineViewDataSource {
|
||||||
var buildLog = ASLogNode(name: "Build Log", path: "build/build.log")
|
var buildLog = ASLogNode(name: "Build Log", path: "build/build.log")
|
||||||
var uploadLog = ASLogNode(name: "Upload Log", path: "build/upload.log")
|
var uploadLog = ASLogNode(name: "Upload Log", path: "build/upload.log")
|
||||||
var disassembly = ASLogNode(name: "Disassembly", path: "build/disasm.log")
|
var disassembly = ASLogNode(name: "Disassembly", path: "build/disasm.log")
|
||||||
|
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)
|
||||||
|
@ -326,4 +331,67 @@ class ASFileTree : NSObject, NSOutlineViewDataSource {
|
||||||
func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? {
|
func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? {
|
||||||
return (item as! ASFileNode).nodeName()
|
return (item as! ASFileNode).nodeName()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let kLocalReorderPasteboardType = "ASFilePasteboardType"
|
||||||
|
func outlineView(outlineView: NSOutlineView, writeItems items: [AnyObject], toPasteboard pasteboard: NSPasteboard) -> Bool {
|
||||||
|
dragged = items as! [ASFileNode]
|
||||||
|
pasteboard.declareTypes([kLocalReorderPasteboardType], owner: self)
|
||||||
|
pasteboard.setData(NSData(), forType: kLocalReorderPasteboardType)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
func itemIsDescendentOfDrag(outlineView: NSOutlineView, item: ASFileNode) -> Bool {
|
||||||
|
if dragged.contains(item) {
|
||||||
|
return true
|
||||||
|
} else if item is ASProject {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return itemIsDescendentOfDrag(outlineView, item: outlineView.parentForItem(item) as! ASFileNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func outlineView(outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: AnyObject?, proposedChildIndex index: Int) -> NSDragOperation {
|
||||||
|
if info.draggingPasteboard().availableTypeFromArray([kLocalReorderPasteboardType]) == nil {
|
||||||
|
return NSDragOperation.None // Only allow reordering drags
|
||||||
|
}
|
||||||
|
for drag in dragged {
|
||||||
|
switch (drag) {
|
||||||
|
case is ASProject, is ASLogNode:
|
||||||
|
return NSDragOperation.None // Don't allow root or log nodes to be dragged
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (item) {
|
||||||
|
case is ASProject, is ASFileGroup:
|
||||||
|
if itemIsDescendentOfDrag(outlineView, item: item as! ASFileNode) {
|
||||||
|
return NSDragOperation.None // Don't allow drag on member of dragged items or a descendent thereof
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return NSDragOperation.None // Don't allow drag onto leaf
|
||||||
|
}
|
||||||
|
return NSDragOperation.Generic
|
||||||
|
}
|
||||||
|
func outlineView(outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: AnyObject?, var childIndex insertAtIndex: Int) -> Bool {
|
||||||
|
let parent : ASFileGroup = (item as? ASFileGroup) ?? root
|
||||||
|
if insertAtIndex == NSOutlineViewDropOnItemIndex {
|
||||||
|
insertAtIndex = parent.children.count
|
||||||
|
}
|
||||||
|
outlineView.beginUpdates()
|
||||||
|
for item in dragged {
|
||||||
|
let origParent = outlineView.parentForItem(item) as! ASFileGroup
|
||||||
|
let origIndex = origParent.children.indexOf(item)!
|
||||||
|
origParent.children.removeAtIndex(origIndex)
|
||||||
|
outlineView.removeItemsAtIndexes(NSIndexSet(index:origIndex), inParent:origParent, withAnimation:NSTableViewAnimationOptions.EffectNone)
|
||||||
|
if origParent == parent && insertAtIndex > origIndex {
|
||||||
|
insertAtIndex -= 1
|
||||||
|
}
|
||||||
|
parent.children.insert(item, atIndex:insertAtIndex)
|
||||||
|
outlineView.insertItemsAtIndexes(NSIndexSet(index:insertAtIndex), inParent: parent, withAnimation:NSTableViewAnimationOptions.EffectGap)
|
||||||
|
insertAtIndex += 1
|
||||||
|
}
|
||||||
|
outlineView.endUpdates()
|
||||||
|
(outlineView.delegate() as! ASProjDoc).updateChangeCount(NSDocumentChangeType.ChangeDone)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -126,6 +126,10 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
|
|
||||||
editors.setViews([editor], inGravity: .Top)
|
editors.setViews([editor], inGravity: .Top)
|
||||||
|
|
||||||
|
outline.registerForDraggedTypes([files.kLocalReorderPasteboardType])
|
||||||
|
outline.setDraggingSourceOperationMask(NSDragOperation.Every, forLocal: true)
|
||||||
|
outline.setDraggingSourceOperationMask(NSDragOperation.None, forLocal: false)
|
||||||
|
|
||||||
outline.setDataSource(files)
|
outline.setDataSource(files)
|
||||||
files.apply() { node in
|
files.apply() { node in
|
||||||
if let group = node as? ASFileGroup {
|
if let group = node as? ASFileGroup {
|
||||||
|
@ -496,9 +500,11 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func outlineView(outlineView: NSOutlineView, shouldTrackCell cell: NSCell, forTableColumn tableColumn: NSTableColumn?, item: AnyObject) -> Bool {
|
||||||
|
return outlineView.isRowSelected(outlineView.rowForItem(item))
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: File manipulation
|
// MARK: File manipulation
|
||||||
|
|
||||||
@IBAction func delete(_: AnyObject) {
|
@IBAction func delete(_: AnyObject) {
|
||||||
let selection = selectedFiles()
|
let selection = selectedFiles()
|
||||||
var name : String
|
var name : String
|
||||||
|
|
Loading…
Reference in New Issue
Block a user