OSDN Git Service

saveメソッドを一本化
[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     case bookmarkItem = 999999
17 }
18
19 final class BookmarkManager: NSObject, NSMenuDelegate {
20     
21     static let shared = BookmarkManager()
22     
23     private override init() {
24         
25         super.init()
26         
27         bookmarksController.managedObjectContext = self.manageObjectContext
28         bookmarksController.entityName = Bookmark.entityName
29         let sort = NSSortDescriptor(key: #keyPath(Bookmark.order), ascending: true)
30         bookmarksController.sortDescriptors = [sort]
31         
32         let mainMenu = NSApplication.shared.mainMenu
33         let bItem = mainMenu?.item(withTag: BookmarkMenuTag.bookmark.rawValue)
34         bookmarkMenu = bItem?.submenu
35         bookmarkMenu?.delegate = self
36         buildBookmarkMenu()
37     }
38     
39     let editorStore: BookmarkDataStore = BookmarkDataStore.oneTimeEditor()
40     let manageObjectContext = BookmarkDataStore.default.context
41     private let bookmarksController = NSArrayController()
42     
43     private var bookmarkMenu: NSMenu!
44     
45     var bookmarks: [Bookmark] {
46         
47         bookmarksController.fetch(nil)
48         
49         guard let items = bookmarksController.arrangedObjects as? [Bookmark] else { return [] }
50         
51         return items
52     }
53     
54     func createNewBookmark(configurator: @escaping (Bookmark) -> Bool) -> Bookmark? {
55         
56         guard let maxOrder = bookmarksController.value(forKeyPath: "arrangedObjects.@max.order") as? Int else {
57             
58             return Logger.shared.log("BookmarkManager: Can no convert max order to Int", value: nil)
59         }
60         
61         let editorStore: BookmarkDataStore = BookmarkDataStore.oneTimeEditor()
62         
63         guard let new = editorStore.sync(execute: { editorStore.createBookmark() }) else {
64             
65             return Logger.shared.log("BookmarkManager: Can not insert BookMarkItem", value: nil)
66         }
67         
68         return editorStore.sync {
69             
70             new.identifier = String(format: "B%@", arguments: [NSDate()])
71             new.order = maxOrder + 100
72             
73             if !configurator(new) {
74                 
75                 editorStore.delete(new)
76                 
77                 return nil
78             }
79             
80             editorStore.save()
81             
82             return new
83         }
84     }
85     
86     func menuNeedsUpdate(_ menu: NSMenu) {
87         
88         buildBookmarkMenu()
89     }
90     
91     private func buildBookmarkMenu() {
92         
93         bookmarkMenu
94             .items
95             .filter { $0.tag == BookmarkMenuTag.bookmarkItem.rawValue }
96             .forEach(bookmarkMenu.removeItem)
97         
98         bookmarks.forEach {
99             
100             let item = NSMenuItem(title: $0.name,
101                                   action: #selector(ExternalBrowserWindowController.selectBookmark(_:)),
102                                   keyEquivalent: "")
103             item.representedObject = $0
104             item.tag = BookmarkMenuTag.bookmarkItem.rawValue
105             bookmarkMenu.addItem(item)
106         }
107     }
108 }