OSDN Git Service

Doutaku を 1.0 にアップデート
[kcd/KCD.git] / KCD / BookmarkManager.swift
1 //
2 //  BookmarkManager.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/22.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 private enum BookmarkMenuTag: Int {
12     
13     case bookmark = 5000
14     
15     case separator = 9999
16     
17     case bookmarkItem = 999999
18 }
19
20 final class BookmarkManager: NSObject, NSMenuDelegate {
21     
22     static let shared = BookmarkManager()
23     
24     private override init() {
25         
26         super.init()
27         
28         bookmarksController.managedObjectContext = self.manageObjectContext
29         bookmarksController.entityName = Bookmark.entityName
30         let sort = NSSortDescriptor(key: #keyPath(Bookmark.order), ascending: true)
31         bookmarksController.sortDescriptors = [sort]
32         
33         let mainMenu = NSApplication.shared.mainMenu
34         let bItem = mainMenu?.item(withTag: BookmarkMenuTag.bookmark.rawValue)
35         bookmarkMenu = bItem?.submenu
36         bookmarkMenu?.delegate = self
37         buildBookmarkMenu()
38     }
39     
40     let editorStore: BookmarkDataStore = BookmarkDataStore.oneTimeEditor()
41     let manageObjectContext = BookmarkDataStore.default.context
42     private let bookmarksController = NSArrayController()
43     
44     private var bookmarkMenu: NSMenu!
45     
46     var bookmarks: [Bookmark] {
47         
48         bookmarksController.fetch(nil)
49         
50         guard let items = bookmarksController.arrangedObjects as? [Bookmark] else {
51             
52             return []
53         }
54         
55         return items
56     }
57     
58     func createNewBookmark(configurator: @escaping (Bookmark) -> Bool) -> Bookmark? {
59         
60         guard let maxOrder = bookmarksController.value(forKeyPath: "arrangedObjects.@max.order") as? Int else {
61             
62             Logger.shared.log("BookmarkManager: Can no convert max order to Int")
63             
64             return nil
65         }
66         
67         let editorStore: BookmarkDataStore = BookmarkDataStore.oneTimeEditor()
68         
69         guard let new = editorStore.sync(execute: { editorStore.createBookmark() }) else {
70             
71             Logger.shared.log("BookmarkManager: Can not insert BookMarkItem")
72             
73             return nil
74         }
75         
76         return editorStore.sync {
77             
78             new.identifier = String(format: "B%@", arguments: [NSDate()])
79             new.order = maxOrder + 100
80             
81             if !configurator(new) {
82                 
83                 editorStore.delete(new)
84                 
85                 return nil
86             }
87             
88             editorStore.save()
89             
90             return new
91         }
92     }
93     
94     func menuNeedsUpdate(_ menu: NSMenu) {
95         
96         buildBookmarkMenu()
97     }
98     
99     private func buildBookmarkMenu() {
100         
101         bookmarkMenu
102             .items
103             .filter { $0.tag == BookmarkMenuTag.bookmarkItem.rawValue }
104             .forEach(bookmarkMenu.removeItem)
105         
106         bookmarks.forEach {
107             
108             let item = NSMenuItem(title: $0.name,
109                                   action: #selector(ExternalBrowserWindowController.selectBookmark(_:)),
110                                   keyEquivalent: "")
111             item.representedObject = $0
112             item.tag = BookmarkMenuTag.bookmarkItem.rawValue
113             bookmarkMenu.addItem(item)
114         }
115     }
116 }