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 kNameKey = "Name"
|
||||
|
||||
class ASFileNode {
|
||||
class ASFileNode : Equatable {
|
||||
var name : String
|
||||
|
||||
init(name: String) {
|
||||
|
@ -97,6 +97,10 @@ class ASFileNode {
|
|||
}
|
||||
}
|
||||
|
||||
func ==(a: ASFileNode, b: ASFileNode) -> Bool {
|
||||
return a === b
|
||||
}
|
||||
|
||||
class ASLogNode : ASFileNode {
|
||||
var path : String
|
||||
|
||||
|
@ -268,6 +272,7 @@ class ASFileTree : NSObject, NSOutlineViewDataSource {
|
|||
var buildLog = ASLogNode(name: "Build Log", path: "build/build.log")
|
||||
var uploadLog = ASLogNode(name: "Upload Log", path: "build/upload.log")
|
||||
var disassembly = ASLogNode(name: "Disassembly", path: "build/disasm.log")
|
||||
var dragged = [ASFileNode]()
|
||||
|
||||
func addFileURL(url: NSURL, omitUnknown: Bool = true) {
|
||||
let type = ASFileType.guessForURL(url)
|
||||
|
@ -326,4 +331,67 @@ class ASFileTree : NSObject, NSOutlineViewDataSource {
|
|||
func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? {
|
||||
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)
|
||||
|
||||
outline.registerForDraggedTypes([files.kLocalReorderPasteboardType])
|
||||
outline.setDraggingSourceOperationMask(NSDragOperation.Every, forLocal: true)
|
||||
outline.setDraggingSourceOperationMask(NSDragOperation.None, forLocal: false)
|
||||
|
||||
outline.setDataSource(files)
|
||||
files.apply() { node in
|
||||
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
|
||||
|
||||
@IBAction func delete(_: AnyObject) {
|
||||
let selection = selectedFiles()
|
||||
var name : String
|
||||
|
|
Loading…
Reference in New Issue
Block a user