// // ActivityViewController.swift // TagTunes // // Created by Kim Wittenburg on 22.03.16. // Copyright © 2016 Kim Wittenburg. All rights reserved. // import SearchAPI import AppKitPlus // TODO: Order Fields, Documentation let saveQueue = OperationQueue() // TODO: Better Name private var operationsContext = 0 class ActivityViewController: NSViewController, OperationQueueDelegate { private struct Groups { static let Lookup: AnyObject = "LookupGroup" static let Save: AnyObject = "SaveGroup" } private static let LookupItem: AnyObject = "LookupActivityItem" // MARK: Properties @IBOutlet weak var outlineView: NSOutlineView! private var saveOperations = [SaveOperation]() { didSet { noteOutlineContentDidChange() } } // MARK: Initialization override init?(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) registerObservers() } required init?(coder: NSCoder) { super.init(coder: coder) registerObservers() } private func registerObservers() { saveQueue.addObserver(self, forKeyPath: "operations", options: [], context: &operationsContext) LookupQueue.globalQueue.delegate = self } // MARK: Obersers and Delegates private func noteOutlineContentDidChange() { // TODO: Optimize this to reload single rows self.outlineView?.reloadData() self.outlineView?.expandItem(nil, expandChildren: true) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer) { if context == &operationsContext { let operations = saveQueue.operations.flatMap { $0 as? SaveOperation } dispatch_async(dispatch_get_main_queue()) { self.saveOperations = operations } } } func operationQueue(operationQueue: OperationQueue, willAddOperation operation: NSOperation) { if operationQueue === LookupQueue.globalQueue { noteOutlineContentDidChange() } } func operationQueue(operationQueue: OperationQueue, operationDidFinish operation: NSOperation, withErrors errors: [NSError]) { // TODO: Why is this not on main thread and willAdd... is? dispatch_sync(dispatch_get_main_queue()) { if operationQueue === LookupQueue.globalQueue { self.noteOutlineContentDidChange() } } } } extension ActivityViewController: NSOutlineViewDataSource, NSOutlineViewDelegate { func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int { if item == nil { return 2 } if item === Groups.Lookup { return 0 // TODO: Return sometimes 1 } if item === Groups.Save { return saveOperations.count } return 0 } func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject { if item == nil { return [Groups.Lookup, Groups.Save][index] } if item === Groups.Lookup { return ActivityViewController.LookupItem } if item === Groups.Save { return saveOperations[index] } return "" } func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool { return self.outlineView(outlineView, isGroupItem: item) } func outlineView(outlineView: NSOutlineView, isGroupItem item: AnyObject) -> Bool { return item === Groups.Lookup || item === Groups.Save } func outlineView(outlineView: NSOutlineView, shouldShowOutlineCellForItem item: AnyObject) -> Bool { return false } func outlineView(outlineView: NSOutlineView, heightOfRowByItem item: AnyObject) -> CGFloat { if self.outlineView(outlineView, isGroupItem: item) { return 24 } else { return 42 } } func outlineView(outlineView: NSOutlineView, viewForTableColumn tableColumn: NSTableColumn?, item: AnyObject) -> NSView? { if item === Groups.Lookup { let view = outlineView.makeViewWithIdentifier("GroupCell", owner: nil) as? NSTableCellView // TODO: Localize view?.textField?.stringValue = "iTunes Match" return view } if item === Groups.Save { let view = outlineView.makeViewWithIdentifier("GroupCell", owner: nil) as? NSTableCellView // TODO: Localize view?.textField?.stringValue = "Saving" return view } print(item) if item === ActivityViewController.LookupItem { var view = outlineView.makeViewWithIdentifier("LookupCell", owner: nil) as? AdvancedTableCellView if view == nil { view = AdvancedTableCellView() view?.style = .Subtitle let progressIndicator = NSProgressIndicator() progressIndicator.controlSize = .RegularControlSize view?.leftAccessoryView = progressIndicator } // TODO: Localize view?.textField?.stringValue = "Looking up n tracks" view?.secondaryTextField?.stringValue = "m tracks in queue" return view } if let saveOperation = item as? SaveOperation { var view = outlineView.makeViewWithIdentifier("SaveCell", owner: nil) as? SaveTableCellView if view == nil { view = SaveTableCellView() } view?.progress = saveOperation.progress view?.leftAccessoryView = nil return view } return nil } }