OSDN Git Service

分岐係数込みの判定式(33)の値が誤っていたので修正
[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 private var tableView: NSTableView!
26     @IBOutlet private var bookmarkController: NSArrayController!
27     @IBOutlet private var contextMenu: NSMenu!
28     @IBOutlet private var popover: NSPopover!
29     
30     weak var delegate: BookmarkListViewControllerDelegate?
31     var editorController: BookmarkEditorViewController?
32     
33     // tableView support
34     var draggingRange: 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 {
57             
58             return
59         }
60         guard case 0..<bookmarks.count = clickedRow else {
61             
62             return
63         }
64         
65         editorController?.representedObject = bookmarks[clickedRow]
66         popover.show(relativeTo: tableView.rect(ofRow: clickedRow), of: tableView, preferredEdge: .minY)
67     }
68     
69     @IBAction func deleteBookmark(_ sender: AnyObject?) {
70         
71         let clickedRow = tableView.clickedRow
72         
73         guard let bookmarks = bookmarkController.arrangedObjects as? [Any] else {
74             
75             return
76         }
77         guard case 0..<bookmarks.count = clickedRow else {
78             
79             return
80         }
81         
82         bookmarkController.remove(atArrangedObjectIndex: clickedRow)
83     }
84 }
85
86 extension BookmarkListViewController: NSTableViewDelegate, NSTableViewDataSource {
87     
88     func reorderingBoolmarks() {
89         
90         guard let objects = bookmarkController.arrangedObjects as? [Bookmark] else {
91             
92             return
93         }
94         
95         var order = 100
96         objects.forEach {
97             
98             $0.order = order
99             order += 100
100         }
101     }
102     
103     func tableViewSelectionDidChange(_ notification: Notification) {
104         
105         guard let tableView = notification.object as? NSTableView else {
106             
107             return
108         }
109         guard let bookmarks = bookmarkController.arrangedObjects as? [Bookmark] else {
110             
111             return
112         }
113         
114         let selection = tableView.selectedRow
115         tableView.deselectAll(nil)
116         
117         guard case 0..<bookmarks.count = selection else {
118             
119             return
120         }
121         
122         delegate?.didSelectBookmark(bookmarks[selection])
123     }
124     
125     func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
126         
127         guard let objects = bookmarkController.arrangedObjects as? [NSPasteboardWriting] else {
128             
129             return nil
130         }
131         
132         return objects[row]
133     }
134     
135     func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) {
136         
137         guard let first = rowIndexes.first else {
138             
139             return
140         }
141         guard let last = rowIndexes.last else {
142             
143             return
144         }
145         
146         draggingRange = first...last
147     }
148     
149     func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
150         
151         draggingRange = 0...0
152     }
153     
154     func tableView(_ tableView: NSTableView,
155                    validateDrop info: NSDraggingInfo,
156                    proposedRow row: Int,
157                    proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
158         
159         guard dropOperation == .above else {
160             
161             return []
162         }
163         guard !(draggingRange ~= row) else {
164             
165             return []
166         }
167         guard let tableView = info.draggingSource() as? NSTableView, tableView == self.tableView else {
168             
169             return []
170         }
171         
172         return .move
173     }
174     
175     func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
176         
177         tableView.beginUpdates()
178         defer { tableView.endUpdates() }
179         
180         let targetOrder: Int = {
181             
182             guard let objects = bookmarkController.arrangedObjects as? [Any],
183                 case 1...objects.count = row,
184                 let target = objects[row - 1] as? Bookmark else {
185                     
186                     return 0
187             }
188             
189             return target.order
190         }()
191         
192         guard let items = info.draggingPasteboard().pasteboardItems else {
193             
194             return false
195         }
196         
197         let store = BookmarkManager.shared.editorStore
198         store.sync {
199             
200             items.enumerated().forEach {
201                 
202                 guard let data = $0.element.data(forType: .bookmarkItem) else {
203                     
204                     return
205                 }
206                 guard let uri = NSKeyedUnarchiver.unarchiveObject(with: data) as? URL else {
207                     
208                     return
209                 }
210                 guard let bookmark = store.object(of: Bookmark.entity, forURIRepresentation: uri) else {
211                     
212                     return
213                 }
214                 
215                 bookmark.order = targetOrder + $0.offset + 1
216             }
217             
218             store.save()
219             
220             self.bookmarkController.rearrangeObjects()
221             self.reorderingBoolmarks()
222             self.bookmarkController.rearrangeObjects()
223         }
224         
225         tableView.reloadData()
226         
227         return true
228     }
229 }