OSDN Git Service

BookmarkManager.shared()メソッドをsharedプロパティに変更
[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     
13     func didSelectBookmark(_ bookmark: Bookmark)
14 }
15
16 extension NSPasteboard.PasteboardType {
17     
18     static let bookmarkItem = NSPasteboard.PasteboardType("com.masakih.KCD.BookmarkItem")
19 }
20
21 final class BookmarkListViewController: NSViewController {
22     
23     @objc let managedObjectContext = BookmarkManager.shared.manageObjectContext
24     
25     @IBOutlet var tableView: NSTableView!
26     @IBOutlet var bookmarkController: NSArrayController!
27     @IBOutlet var contextMenu: NSMenu!
28     @IBOutlet var popover: NSPopover!
29     
30     weak var delegate: BookmarkListViewControllerDelegate?
31     var editorController: BookmarkEditorViewController?
32     
33     // tableView support
34     var objectRange: CountableClosedRange = 0...0
35     
36     override var nibName: NSNib.Name {
37         
38         return .nibName(instanceOf: self)
39     }
40     
41     override func viewDidLoad() {
42         
43         super.viewDidLoad()
44         
45         editorController = BookmarkEditorViewController()
46         popover.contentViewController = editorController
47         
48         tableView.registerForDraggedTypes([.bookmarkItem])
49         tableView.setDraggingSourceOperationMask(.move, forLocal: true)
50     }
51     
52     @IBAction func editBookmark(_ sender: AnyObject?) {
53         
54         let clickedRow = tableView.clickedRow
55         
56         guard let bookmarks = bookmarkController.arrangedObjects as? [Any] else { return }
57         guard case 0..<bookmarks.count = clickedRow else { return }
58         
59         editorController?.representedObject = bookmarks[clickedRow]
60         popover.show(relativeTo: tableView.rect(ofRow: clickedRow), of: tableView, preferredEdge: .minY)
61     }
62     
63     @IBAction func deleteBookmark(_ sender: AnyObject?) {
64         
65         let clickedRow = tableView.clickedRow
66         
67         guard let bookmarks = bookmarkController.arrangedObjects as? [Any] else { return }
68         guard case 0..<bookmarks.count = clickedRow else { return }
69         
70         bookmarkController.remove(atArrangedObjectIndex: clickedRow)
71     }
72 }
73
74 extension BookmarkListViewController: NSTableViewDelegate, NSTableViewDataSource {
75     
76     func reorderingBoolmarks() {
77         
78         guard let objects = bookmarkController.arrangedObjects as? [Bookmark] else { return }
79         
80         var order = 100
81         objects.forEach {
82             $0.order = order
83             order += 100
84         }
85     }
86     
87     func tableViewSelectionDidChange(_ notification: Notification) {
88         
89         guard let tableView = notification.object as? NSTableView else { return }
90         guard let bookmarks = bookmarkController.arrangedObjects as? [Bookmark] else { return }
91         
92         let selection = tableView.selectedRow
93         tableView.deselectAll(nil)
94         
95         guard case 0..<bookmarks.count = selection else { return }
96         
97         delegate?.didSelectBookmark(bookmarks[selection])
98     }
99     
100     func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
101         
102         guard let objects = bookmarkController.arrangedObjects as? [NSPasteboardWriting] else { return nil }
103         
104         return objects[row]
105     }
106     
107     func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) {
108         
109         guard let first = rowIndexes.first else { return }
110         guard let last = rowIndexes.last else { return }
111         
112         objectRange = first...last
113     }
114     
115     func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
116         
117         objectRange = 0...0
118     }
119     
120     func tableView(_ tableView: NSTableView,
121                    validateDrop info: NSDraggingInfo,
122                    proposedRow row: Int,
123                    proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
124         
125         guard dropOperation == .above else { return [] }
126         guard !(objectRange ~= row) else { return [] }
127         guard let tableView = info.draggingSource() as? NSTableView, tableView == self.tableView else { return [] }
128         
129         return .move
130     }
131     
132     func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
133         
134         tableView.beginUpdates()
135         defer { tableView.endUpdates() }
136         
137         let targetOrder: Int = {
138             
139             guard let objects = bookmarkController.arrangedObjects as? [Any],
140                 case 1...objects.count = row,
141                 let target = objects[row - 1] as? Bookmark else {
142                     
143                     return 0
144             }
145             
146             return target.order
147         }()
148         
149         guard let items = info.draggingPasteboard().pasteboardItems else { return false }
150         
151         let store = BookmarkManager.shared.editorStore
152         items.enumerated().forEach {
153             
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 }
158             
159             bookmark.order = targetOrder + $0.offset + 1
160         }
161         
162         store.save()
163         bookmarkController.rearrangeObjects()
164         reorderingBoolmarks()
165         bookmarkController.rearrangeObjects()
166         
167         return true
168     }
169 }