OSDN Git Service

UAをVersion/10.0.3 Safari/602.4.8に変更
[kcd/KCD.git] / KCD / BookmarkListViewController.swift
1 //
2 //  BookmarkListViewController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2016/12/23.
6 //  Copyright © 2016年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 protocol BookmarkListViewControllerDelegate: class {
12     func didSelectBookmark(_ bookmark: Bookmark)
13 }
14
15 fileprivate struct DragingType {
16     static let bookmarkItem = "com.masakih.KCD.BookmarkItem"
17 }
18
19 class BookmarkListViewController: NSViewController {
20     let managedObjectContext = BookmarkManager.shared().manageObjectContext
21     
22     @IBOutlet var tableView: NSTableView!
23     @IBOutlet var bookmarkController: NSArrayController!
24     @IBOutlet var contextMenu: NSMenu!
25     @IBOutlet var popover: NSPopover!
26     
27     weak var delegate: BookmarkListViewControllerDelegate?
28     var editorController: BookmarkEditorViewController?
29     
30     // tableView support
31     var objectRange: CountableClosedRange = 0...0
32     
33     override var nibName: String! {
34         return "BookmarkListViewController"
35     }
36     
37     override func viewDidLoad() {
38         super.viewDidLoad()
39         
40         editorController = BookmarkEditorViewController()
41         popover.contentViewController = editorController
42         
43         tableView.register(forDraggedTypes: [DragingType.bookmarkItem])
44         tableView.setDraggingSourceOperationMask(.move, forLocal: true)
45     }
46     
47     @IBAction func editBookmark(_ sender: AnyObject?) {
48         let clickedRow = tableView.clickedRow
49         guard let bookmarks = bookmarkController.arrangedObjects as? [Any],
50             0..<bookmarks.count ~= clickedRow
51             else { return }
52         
53         editorController?.representedObject = bookmarks[clickedRow]
54         popover.show(relativeTo: tableView.rect(ofRow: clickedRow), of: tableView, preferredEdge: .minY)
55     }
56     @IBAction func deleteBookmark(_ sender: AnyObject?) {
57         let clickedRow = tableView.clickedRow
58         guard let bookmarks = bookmarkController.arrangedObjects as? [Any],
59             0..<bookmarks.count ~= clickedRow
60             else { return }
61         
62         bookmarkController.remove(atArrangedObjectIndex: clickedRow)
63     }
64 }
65
66 extension BookmarkListViewController: NSTableViewDelegate, NSTableViewDataSource {
67     func reorderingBoolmarks() {
68         guard let objects = bookmarkController.arrangedObjects as? [Bookmark] else { return }
69         var order = 100
70         objects.forEach {
71             $0.order = order
72             order += 100
73         }
74     }
75     
76     func tableViewSelectionDidChange(_ notification: Notification) {
77         guard let tableView = notification.object as? NSTableView,
78             let bookmarks = bookmarkController.arrangedObjects as? [Bookmark]
79             else { return }
80         let selection = tableView.selectedRow
81         tableView.deselectAll(nil)
82         guard 0..<bookmarks.count ~= selection
83             else { return }
84         delegate?.didSelectBookmark(bookmarks[selection])
85     }
86     func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
87         guard let objects = bookmarkController.arrangedObjects as? [NSPasteboardWriting]
88             else { return nil }
89         return objects[row]
90     }
91     func tableView(_ tableView: NSTableView,
92                    draggingSession session: NSDraggingSession,
93                    willBeginAt screenPoint: NSPoint,
94                    forRowIndexes rowIndexes: IndexSet) {
95         guard let first = rowIndexes.first,
96             let last = rowIndexes.last
97             else { return }
98         objectRange = first...last
99     }
100     func tableView(_ tableView: NSTableView,
101                    draggingSession session: NSDraggingSession,
102                    endedAt screenPoint: NSPoint,
103                    operation: NSDragOperation) {
104         objectRange = 0...0
105     }
106     func tableView(_ tableView: NSTableView,
107                    validateDrop info: NSDraggingInfo,
108                    proposedRow row: Int,
109                    proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation {
110         guard dropOperation == .above,
111             !(objectRange ~= row),
112             let tableView = info.draggingSource() as? NSTableView,
113             tableView == self.tableView
114             else { return [] }
115         return .move
116     }
117     func tableView(_ tableView: NSTableView,
118                    acceptDrop info: NSDraggingInfo,
119                    row: Int,
120                    dropOperation: NSTableViewDropOperation) -> Bool {
121         tableView.beginUpdates()
122         defer { tableView.endUpdates() }
123         
124         let targetOrder: Int = {
125             guard let objects = bookmarkController.arrangedObjects as? [Any],
126                 1...objects.count ~= row,
127                 let target = objects[row - 1] as? Bookmark
128                 else { return 0 }
129             return target.order
130         }()
131         guard let items = info.draggingPasteboard().pasteboardItems
132             else { return false }
133         let store = BookmarkManager.shared().editorStore
134         items.enumerated().forEach {
135             guard let data = $0.element.data(forType: DragingType.bookmarkItem),
136                 let uri = NSKeyedUnarchiver.unarchiveObject(with: data) as? URL,
137                 let oID = managedObjectContext.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: uri),
138                 let bookmark = store.object(with: oID) as? Bookmark
139                 else { return }
140             bookmark.order = targetOrder + $0.offset + 1
141         }
142         store.save()
143         bookmarkController.rearrangeObjects()
144         reorderingBoolmarks()
145         bookmarkController.rearrangeObjects()
146         
147         return true
148     }
149 }