// // DatabaseWindowController.swift // MongoView // // Created by Shadowfacts on 1/9/20. // Copyright © 2020 Shadowfacts. All rights reserved. // import Cocoa import Combine class DatabaseWindowController: NSWindowController { @IBOutlet weak var toolbar: NSToolbar! weak var statusView: WindowStatusView? private var titleObservation: NSKeyValueObservation? var mongoController: MongoController! var initialCollection: DatabaseCollection? private var mainViewController: NSViewController! private var statusChangeHandler: Cancellable? private var connectionStatusChangeHandler: Cancellable? convenience init() { self.init(windowNibName: "DatabaseWindowController") } override func windowDidLoad() { super.windowDidLoad() let setupMongo = mongoController == nil if setupMongo { mongoController = MongoController(connectionString: "mongodb://localhost:27017") } statusChangeHandler = mongoController.$statusManager .receive(on: DispatchQueue.main) .sink { self.updateStatusText(manager: $0) } if mongoController.client != nil { initializeUI() } else { connectionStatusChangeHandler = mongoController.$status .receive(on: DispatchQueue.main) .filter { $0 == .connected } .sink { (_) in self.initializeUI() } } if setupMongo { mongoController.setup() } titleObservation = observe(\.contentViewController?.title) { [unowned self] (_, _) in self.updateWindowTitle() } updateWindowTitle() window!.tabbingMode = .preferred window!.tabbingIdentifier = mongoController.connectionString window!.titleVisibility = .hidden } override func newWindowForTab(_ sender: Any?) { (NSApplication.shared.delegate as! AppDelegate).newWindow(mongoController: mongoController) } private func updateWindowTitle() { window?.title = mainViewController?.title ?? "MongoView" } private func updateStatusText(manager: StatusManager) { guard let statusView = self.statusView, let mostRelevant = manager.mostRelevant else { return } let dayComparisonResult = Calendar.current.compare(mostRelevant.timestamp, to: Date(), toGranularity: .day) let formatter = DateFormatter() if dayComparisonResult == .orderedSame { formatter.dateStyle = .none } else { formatter.dateStyle = .short } formatter.timeStyle = .medium let timestamp = formatter.string(from: mostRelevant.timestamp) let string = "\(mostRelevant.message) | \(timestamp)" statusView.setText(string) } private func initializeUI() { mainViewController = MainSplitViewController(mongoController: mongoController, initialCollection: initialCollection) // otherwise the VC size uses the size from the nib, potentially changing the window size mainViewController.view.frame = window!.contentLayoutRect contentViewController = mainViewController } } extension NSToolbarItem.Identifier { static let mongoStatus = NSToolbarItem.Identifier("MongoView.mongoStatus") static let refresh = NSToolbarItem.Identifier("MongoView.refresh") } extension DatabaseWindowController: NSToolbarDelegate { func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { return [ .space, .flexibleSpace, .mongoStatus, .refresh, ] } func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { return [ .refresh, .flexibleSpace, .mongoStatus, .flexibleSpace, ] } func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? { if itemIdentifier == .mongoStatus { return createMongoStatusToolbarItem() } else if itemIdentifier == .refresh { return createRefreshToolbarItem() } return NSToolbarItem(itemIdentifier: itemIdentifier) } func createMongoStatusToolbarItem() -> NSToolbarItem { let item = NSToolbarItem(itemIdentifier: .mongoStatus) item.label = "Status" item.paletteLabel = "Status" let statusView = WindowStatusView.create() self.statusView = statusView item.view = statusView return item } func createRefreshToolbarItem() -> NSToolbarItem { let item = NSToolbarItem(itemIdentifier: .refresh) item.label = "Refresh" item.paletteLabel = "Refresh" item.target = self let button = NSButton(image: NSImage(named: NSImage.refreshTemplateName)!, target: nil, action: #selector(MainSplitViewController.refresh(_:))) button.bezelStyle = .texturedRounded item.view = button return item } }