OSDN Git Service

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