import Cocoa
-fileprivate enum BookmarkMenuTag: Int {
+private enum BookmarkMenuTag: Int {
+
case bookmark = 5000
+
case separator = 9999
+
+ case bookmarkItem = 999999
}
-class BookmarkManager: NSObject, NSMenuDelegate {
- private static let sharedInstance: BookmarkManager = BookmarkManager()
+final class BookmarkManager: NSObject, NSMenuDelegate {
- class func shared() -> BookmarkManager {
- return sharedInstance
- }
-
- private let bookmarksController: NSArrayController
+ static let shared = BookmarkManager()
private override init() {
- bookmarksController = NSArrayController()
+
super.init()
+
bookmarksController.managedObjectContext = self.manageObjectContext
- bookmarksController.entityName = BookmarkItem.entityName
- let sort = NSSortDescriptor(key: "order", ascending: true)
+ bookmarksController.entityName = Bookmark.entityName
+ let sort = NSSortDescriptor(key: #keyPath(Bookmark.order), ascending: true)
bookmarksController.sortDescriptors = [sort]
- let mainMenu = NSApplication.shared().mainMenu
+
+ let mainMenu = NSApplication.shared.mainMenu
let bItem = mainMenu?.item(withTag: BookmarkMenuTag.bookmark.rawValue)
bookmarkMenu = bItem?.submenu
bookmarkMenu?.delegate = self
buildBookmarkMenu()
}
- private(set) var editorStore: BookmarkDataStore = BookmarkDataStore.oneTimeEditor()
+ let editorStore: BookmarkDataStore = BookmarkDataStore.oneTimeEditor()
+ let manageObjectContext = BookmarkDataStore.default.context
+ private let bookmarksController = NSArrayController()
+
private var bookmarkMenu: NSMenu!
- var manageObjectContext = BookmarkDataStore.default.managedObjectContext
- var bookmarks: [BookmarkItem] {
+
+ var bookmarks: [Bookmark] {
+
bookmarksController.fetch(nil)
- guard let items = bookmarksController.arrangedObjects as? [BookmarkItem]
- else { return [] }
+
+ guard let items = bookmarksController.arrangedObjects as? [Bookmark] else {
+
+ return []
+ }
+
return items
}
- func createNewBookmark() -> BookmarkItem? {
- guard let maxOrder = bookmarksController.value(forKeyPath: "arrangedObjects.@max.order") as? Int
- else {
- print("BookmarkManager: Can no convert max order to Int")
- return nil
- }
- guard let new = editorStore.createBookmark()
- else {
- print("BookmarkManager: Can not insert BookMarkItem")
- return nil
+ func createNewBookmark(configurator: @escaping (Bookmark) -> Bool) -> Bookmark? {
+
+ guard let maxOrder = bookmarksController.value(forKeyPath: "arrangedObjects.@max.order") as? Int else {
+
+ Logger.shared.log("BookmarkManager: Can no convert max order to Int")
+
+ return nil
}
- new.identifier = String(format: "B%@", arguments: [NSDate()])
- new.order = maxOrder + 100
- DispatchQueue.main.asyncAfter(deadline: .now()) {
- self.editorStore.saveActionCore()
+ let editorStore: BookmarkDataStore = BookmarkDataStore.oneTimeEditor()
+
+ guard let new = editorStore.sync(execute: { editorStore.createBookmark() }) else {
+
+ Logger.shared.log("BookmarkManager: Can not insert BookMarkItem")
+
+ return nil
}
- return new
+ return editorStore.sync {
+
+ new.identifier = String(format: "B%@", arguments: [NSDate()])
+ new.order = maxOrder + 100
+
+ if !configurator(new) {
+
+ editorStore.delete(new)
+
+ return nil
+ }
+
+ editorStore.save()
+
+ return new
+ }
}
+
func menuNeedsUpdate(_ menu: NSMenu) {
+
buildBookmarkMenu()
}
+
private func buildBookmarkMenu() {
- for item in bookmarkMenu.items.reversed() {
- if item.tag == BookmarkMenuTag.separator.rawValue { break }
- bookmarkMenu.removeItem(item)
- }
+
+ bookmarkMenu
+ .items
+ .filter { $0.tag == BookmarkMenuTag.bookmarkItem.rawValue }
+ .forEach(bookmarkMenu.removeItem)
bookmarks.forEach {
- let item = NSMenuItem(title: $0.name, action: #selector(ExternalBrowserWindowController.selectBookmark(_:)), keyEquivalent: "")
+
+ let item = NSMenuItem(title: $0.name,
+ action: #selector(ExternalBrowserWindowController.selectBookmark(_:)),
+ keyEquivalent: "")
item.representedObject = $0
+ item.tag = BookmarkMenuTag.bookmarkItem.rawValue
bookmarkMenu.addItem(item)
}
}