2 // BookmarkListViewController.swift
5 // Created by Hori,Masaki on 2016/12/23.
6 // Copyright © 2016年 Hori,Masaki. All rights reserved.
11 protocol BookmarkListViewControllerDelegate: class {
13 func didSelectBookmark(_ bookmark: Bookmark)
16 extension NSPasteboard.PasteboardType {
18 static let bookmarkItem = NSPasteboard.PasteboardType("com.masakih.KCD.BookmarkItem")
21 final class BookmarkListViewController: NSViewController {
23 @objc let managedObjectContext = BookmarkManager.shared.manageObjectContext
25 @IBOutlet var tableView: NSTableView!
26 @IBOutlet var bookmarkController: NSArrayController!
27 @IBOutlet var contextMenu: NSMenu!
28 @IBOutlet var popover: NSPopover!
30 weak var delegate: BookmarkListViewControllerDelegate?
31 var editorController: BookmarkEditorViewController?
34 var draggingRange: CountableClosedRange = 0...0
36 override var nibName: NSNib.Name {
38 return .nibName(instanceOf: self)
41 override func viewDidLoad() {
45 editorController = BookmarkEditorViewController()
46 popover.contentViewController = editorController
48 tableView.registerForDraggedTypes([.bookmarkItem])
49 tableView.setDraggingSourceOperationMask(.move, forLocal: true)
52 @IBAction func editBookmark(_ sender: AnyObject?) {
54 let clickedRow = tableView.clickedRow
56 guard let bookmarks = bookmarkController.arrangedObjects as? [Any] else { return }
57 guard case 0..<bookmarks.count = clickedRow else { return }
59 editorController?.representedObject = bookmarks[clickedRow]
60 popover.show(relativeTo: tableView.rect(ofRow: clickedRow), of: tableView, preferredEdge: .minY)
63 @IBAction func deleteBookmark(_ sender: AnyObject?) {
65 let clickedRow = tableView.clickedRow
67 guard let bookmarks = bookmarkController.arrangedObjects as? [Any] else { return }
68 guard case 0..<bookmarks.count = clickedRow else { return }
70 bookmarkController.remove(atArrangedObjectIndex: clickedRow)
74 extension BookmarkListViewController: NSTableViewDelegate, NSTableViewDataSource {
76 func reorderingBoolmarks() {
78 guard let objects = bookmarkController.arrangedObjects as? [Bookmark] else { return }
87 func tableViewSelectionDidChange(_ notification: Notification) {
89 guard let tableView = notification.object as? NSTableView else { return }
90 guard let bookmarks = bookmarkController.arrangedObjects as? [Bookmark] else { return }
92 let selection = tableView.selectedRow
93 tableView.deselectAll(nil)
95 guard case 0..<bookmarks.count = selection else { return }
97 delegate?.didSelectBookmark(bookmarks[selection])
100 func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
102 guard let objects = bookmarkController.arrangedObjects as? [NSPasteboardWriting] else { return nil }
107 func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) {
109 guard let first = rowIndexes.first else { return }
110 guard let last = rowIndexes.last else { return }
112 draggingRange = first...last
115 func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
117 draggingRange = 0...0
120 func tableView(_ tableView: NSTableView,
121 validateDrop info: NSDraggingInfo,
122 proposedRow row: Int,
123 proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
125 guard dropOperation == .above else { return [] }
126 guard !(draggingRange ~= row) else { return [] }
127 guard let tableView = info.draggingSource() as? NSTableView, tableView == self.tableView else { return [] }
132 func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
134 tableView.beginUpdates()
135 defer { tableView.endUpdates() }
137 let targetOrder: Int = {
139 guard let objects = bookmarkController.arrangedObjects as? [Any],
140 case 1...objects.count = row,
141 let target = objects[row - 1] as? Bookmark else {
149 guard let items = info.draggingPasteboard().pasteboardItems else { return false }
151 let store = BookmarkManager.shared.editorStore
152 items.enumerated().forEach {
154 guard let data = $0.element.data(forType: .bookmarkItem) else { return }
155 guard let uri = NSKeyedUnarchiver.unarchiveObject(with: data) as? URL else { return }
156 guard let oID = managedObjectContext.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: uri) else { return }
157 guard let bookmark = store.object(of: Bookmark.entity, with: oID) else { return }
159 bookmark.order = targetOrder + $0.offset + 1
162 store.save(errorHandler: store.presentOnMainThread)
163 bookmarkController.rearrangeObjects()
164 reorderingBoolmarks()
165 bookmarkController.rearrangeObjects()