From 45c9d1c6ac37c2b1f6258030e8f546188a001934 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sat, 15 Jun 2019 18:12:40 -0700 Subject: [PATCH] Moving over to a seperate datasource. --- Clocker/Overall App/Logger.swift | 7 +- .../Data Layer/TimezoneDataOperations.swift | 2 +- Clocker/Panel/FloatingWindowController.swift | 2 +- Clocker/Panel/PanelController.swift | 18 +- Clocker/Panel/ParentPanelController.swift | 12 +- .../General/PreferencesDataSource.swift | 208 ++++++++++++- .../General/PreferencesViewController.swift | 283 ++++++------------ Clocker/Preferences/Preferences.storyboard | 6 +- 8 files changed, 313 insertions(+), 225 deletions(-) diff --git a/Clocker/Overall App/Logger.swift b/Clocker/Overall App/Logger.swift index 691567b..146e825 100644 --- a/Clocker/Overall App/Logger.swift +++ b/Clocker/Overall App/Logger.swift @@ -14,15 +14,14 @@ class Logger: NSObject { @available(OSX 10.14, *) class PerfLogger: NSObject { - static var panelLog = OSLog(subsystem: "com.abhishek.Clocker", category: "Open Panel") static let signpostID = OSSignpostID(log: panelLog) - + class func disable() { panelLog = .disabled } - + class func startMarker(_ name: StaticString) { os_signpost(.begin, log: panelLog, @@ -37,5 +36,3 @@ class PerfLogger: NSObject { signpostID: signpostID) } } - - diff --git a/Clocker/Panel/Data Layer/TimezoneDataOperations.swift b/Clocker/Panel/Data Layer/TimezoneDataOperations.swift index 1c13c55..18a24ed 100644 --- a/Clocker/Panel/Data Layer/TimezoneDataOperations.swift +++ b/Clocker/Panel/Data Layer/TimezoneDataOperations.swift @@ -318,7 +318,7 @@ extension TimezoneDataOperations { return dateFormatter.string(from: Date()) } - func saveObject(at index: Int = -1) { + func saveObject(at index: Int = -1) { var defaults = DataStore.shared().timezones() let encodedObject = NSKeyedArchiver.archivedData(withRootObject: dataObject as Any) index == -1 ? defaults.append(encodedObject) : defaults.insert(encodedObject, at: index) diff --git a/Clocker/Panel/FloatingWindowController.swift b/Clocker/Panel/FloatingWindowController.swift index f96598e..f69a7e1 100644 --- a/Clocker/Panel/FloatingWindowController.swift +++ b/Clocker/Panel/FloatingWindowController.swift @@ -43,7 +43,7 @@ class FloatingWindowController: ParentPanelController { mainTableView.setAccessibility("FloatingTableView") } - override func updatePanelColor() { + override func updatePanelColor() { super.updatePanelColor() updateTheme() } diff --git a/Clocker/Panel/PanelController.swift b/Clocker/Panel/PanelController.swift index cbab950..70806c2 100644 --- a/Clocker/Panel/PanelController.swift +++ b/Clocker/Panel/PanelController.swift @@ -19,7 +19,7 @@ class PanelController: ParentPanelController { override func awakeFromNib() { super.awakeFromNib() - + enablePerformanceLoggingIfNeccessary() window?.title = "Clocker Panel" @@ -40,7 +40,7 @@ class PanelController: ParentPanelController { super.updateDefaultPreferences() } - + private func enablePerformanceLoggingIfNeccessary() { if !ProcessInfo.processInfo.environment.keys.contains("ENABLE_PERF_LOGGING") { if #available(OSX 10.14, *) { @@ -120,7 +120,7 @@ class PanelController: ParentPanelController { if #available(OSX 10.14, *) { PerfLogger.startMarker("Set Panel Frame") } - + guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return } @@ -163,7 +163,7 @@ class PanelController: ParentPanelController { if #available(OSX 10.14, *) { PerfLogger.startMarker("Logging") } - + let preferences = DataStore.shared().timezones() guard let theme = DataStore.shared().retrieve(key: CLThemeKey) as? NSNumber, @@ -207,7 +207,7 @@ class PanelController: ParentPanelController { ] Logger.log(object: panelEvent, for: "openedPanel") - + if #available(OSX 10.14, *) { PerfLogger.endMarker("Logging") } @@ -217,21 +217,21 @@ class PanelController: ParentPanelController { if #available(OSX 10.14, *) { PerfLogger.startMarker("Start Window Timer") } - + stopMenubarTimerIfNeccesary() if let timer = parentTimer, timer.state == .paused { parentTimer?.start() - + if #available(OSX 10.14, *) { PerfLogger.endMarker("Start Window Timer") } - + return } startTimer() - + if #available(OSX 10.14, *) { PerfLogger.endMarker("Start Window Timer") } diff --git a/Clocker/Panel/ParentPanelController.swift b/Clocker/Panel/ParentPanelController.swift index 12520f1..3b84d88 100644 --- a/Clocker/Panel/ParentPanelController.swift +++ b/Clocker/Panel/ParentPanelController.swift @@ -411,7 +411,7 @@ class ParentPanelController: NSWindowController { if #available(OSX 10.14, *) { PerfLogger.startMarker("Update Default Preferences") } - + updatePanelColor() let defaults = DataStore.shared().timezones() @@ -425,7 +425,7 @@ class ParentPanelController: NSWindowController { mainTableView.panelDelegate = datasource updateDatasource(with: convertedTimezones) - + if #available(OSX 10.14, *) { PerfLogger.endMarker("Update Default Preferences") } @@ -657,7 +657,7 @@ class ParentPanelController: NSWindowController { if #available(OSX 10.14, *) { PerfLogger.startMarker("Retrieve Calendar Events") } - + let eventCenter = EventCenter.sharedCenter() if eventCenter.calendarAccessGranted() { @@ -667,7 +667,7 @@ class ParentPanelController: NSWindowController { } else { removeUpcomingEventView() } - + if #available(OSX 10.14, *) { PerfLogger.endMarker("Retrieve Calendar Events") } @@ -731,7 +731,7 @@ class ParentPanelController: NSWindowController { if #available(OSX 10.14, *) { PerfLogger.startMarker("Fetch Calendar Events") } - + let eventCenter = EventCenter.sharedCenter() let now = Date() @@ -762,7 +762,7 @@ class ParentPanelController: NSWindowController { let withoutAgo = withoutAn.replacingOccurrences(of: "ago", with: CLEmptyString) self.setCalendarButtonTitle(buttonTitle: "in \(withoutAgo.lowercased())") - + if #available(OSX 10.14, *) { PerfLogger.endMarker("Fetch Calendar Events") } diff --git a/Clocker/Preferences/General/PreferencesDataSource.swift b/Clocker/Preferences/General/PreferencesDataSource.swift index 9a3bf4c..91a09e8 100644 --- a/Clocker/Preferences/General/PreferencesDataSource.swift +++ b/Clocker/Preferences/General/PreferencesDataSource.swift @@ -2,6 +2,212 @@ import Cocoa +protocol PreferenceSelectionUpdates: AnyObject { + func didAddTimezone(_ timezone: TimezoneData) + func markAsFavorite(_ dataObject: TimezoneData) + func unfavourite(_ dataObject: TimezoneData) + func refreshTimezoneTable() + func refreshMainTableView() + func tableViewSelectionDidChange(_ status: Bool) + func table(didClick tableColumn: NSTableColumn) +} + class PreferencesDataSource: NSObject { - private var selectedTimezones: [Data]! + private weak var updateDelegate: PreferenceSelectionUpdates? + var selectedTimezones: [Data] { + return DataStore.shared().timezones() + } + + init(callbackDelegate delegate: PreferenceSelectionUpdates) { + updateDelegate = delegate + super.init() + } +} + +extension PreferencesDataSource: NSTableViewDelegate { + func tableViewSelectionDidChange(_ notification: Notification) { + if let tableView = notification.object as? NSTableView { + updateDelegate?.tableViewSelectionDidChange(tableView.selectedRow == -1) + } + } + + func tableView(_: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool { + let data = NSKeyedArchiver.archivedData(withRootObject: rowIndexes) + + pboard.declareTypes([.dragSession], owner: self) + pboard.setData(data, forType: .dragSession) + + return true + } + + func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation _: NSTableView.DropOperation) -> Bool { + var newOrder = selectedTimezones + + var destination = row + + if row == newOrder.count { + destination -= 1 + } + + let pBoard = info.draggingPasteboard + + guard let data = pBoard.data(forType: .dragSession) else { + assertionFailure("Data was unexpectedly nil") + return false + } + + guard let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: data) as? IndexSet, let first = rowIndexes.first else { + assertionFailure("Row was unexpectedly nil") + return false + } + + let currentObject = newOrder[first] + + newOrder.remove(at: first) + + newOrder.insert(currentObject, at: destination) + + DataStore.shared().setTimezones(newOrder) + + tableView.reloadData() + + updateDelegate?.refreshMainTableView() + + tableView.deselectRow(tableView.selectedRow) + + return true + } + + func tableView(_: NSTableView, validateDrop _: NSDraggingInfo, proposedRow _: Int, proposedDropOperation _: NSTableView.DropOperation) -> NSDragOperation { + return .every + } + + func tableView(_: NSTableView, didClick tableColumn: NSTableColumn) { + updateDelegate?.table(didClick: tableColumn) + } +} + +extension PreferencesDataSource: NSTableViewDataSource { + func numberOfRows(in _: NSTableView) -> Int { + return selectedTimezones.count + } + + func tableView(_: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { + var selectedDataSource: TimezoneData? + + if selectedTimezones.count > row, + let model = TimezoneData.customObject(from: selectedTimezones[row]) { + selectedDataSource = model + } + + if tableColumn?.identifier.rawValue == PreferencesConstants.timezoneNameIdentifier { + return handleTimezoneNameIdentifier(selectedDataSource) + } + + if tableColumn?.identifier.rawValue == PreferencesConstants.customLabelIdentifier { + return selectedDataSource?.customLabel ?? "Error" + } + + if tableColumn?.identifier.rawValue == "favouriteTimezone" { + return selectedDataSource?.isFavourite ?? 0 + } + + return nil + } + + private func handleTimezoneNameIdentifier(_ selectedDataSource: TimezoneData?) -> Any? { + guard let model = selectedDataSource else { + return nil + } + + if let address = model.formattedAddress, address.isEmpty == false { + return model.formattedAddress + } + + return model.timezoneID + } + + func tableView(_: NSTableView, setObjectValue object: Any?, for _: NSTableColumn?, row: Int) { + guard !selectedTimezones.isEmpty, let dataObject = TimezoneData.customObject(from: selectedTimezones[row]) else { + return + } + + if let edit = object as? String { + setNewLabel(edit, for: dataObject, at: row) + } else if let isFavouriteValue = object as? NSNumber { + dataObject.isFavourite = isFavouriteValue.intValue + insert(timezone: dataObject, at: row) + dataObject.isFavourite == 1 ? + updateDelegate?.markAsFavorite(dataObject) : + updateDelegate?.unfavourite(dataObject) + updateStatusItem() + updateDelegate?.refreshTimezoneTable() + } + + updateDelegate?.refreshMainTableView() + } + + private func setNewLabel(_ label: String, for dataObject: TimezoneData, at row: Int) { + let formattedValue = label.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines) + + if selectedTimezones.count > row { + Logger.log(object: [ + "Old Label": dataObject.customLabel ?? "Error", + "New Label": formattedValue, + ], + for: "Custom Label Changed") + + dataObject.setLabel(formattedValue) + + insert(timezone: dataObject, at: row) + + updateMenubarTitles() + } else { + Logger.log(object: [ + "MethodName": "SetObjectValue", + "Selected Timezone Count": selectedTimezones.count, + "Current Row": row, + ], + for: "Error in selected row count") + } + } + + private func insert(timezone: TimezoneData, at index: Int) { + let encodedObject = NSKeyedArchiver.archivedData(withRootObject: timezone) + var newDefaults = selectedTimezones + newDefaults[index] = encodedObject + DataStore.shared().setTimezones(newDefaults) + } + + private func updateMenubarTitles() { + let defaultTimezones = DataStore.shared().timezones() + UserDefaults.standard.set([], forKey: CLMenubarFavorites) + + let menubarTimes = defaultTimezones.compactMap { (data) -> TimezoneData? in + if let model = TimezoneData.customObject(from: data), model.isFavourite == 1 { + return model + } + return nil + } + + let archivedObjects = menubarTimes.map { (timezone) -> Data in + NSKeyedArchiver.archivedData(withRootObject: timezone) + } + + UserDefaults.standard.set(archivedObjects, forKey: CLMenubarFavorites) + + // Update appereance if in compact menubar mode + if let appDelegate = NSApplication.shared.delegate as? AppDelegate { + appDelegate.setupMenubarTimer() + } + } + + // TODO: This probably does not need to be used + private func updateStatusItem() { + guard let statusItem = (NSApplication.shared.delegate as? AppDelegate)?.statusItemForPanel() else { + return + } + + statusItem.performTimerWork() + } } diff --git a/Clocker/Preferences/General/PreferencesViewController.swift b/Clocker/Preferences/General/PreferencesViewController.swift index d3198b4..5535cfa 100644 --- a/Clocker/Preferences/General/PreferencesViewController.swift +++ b/Clocker/Preferences/General/PreferencesViewController.swift @@ -76,6 +76,8 @@ class PreferencesViewController: ParentViewController { @IBOutlet var sortToggle: NSButton! private var themeDidChangeNotification: NSObjectProtocol? + private var selectionsDataSource: PreferencesDataSource! + override func viewDidLoad() { super.viewDidLoad() @@ -97,9 +99,13 @@ class PreferencesViewController: ParentViewController { themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { _ in self.setup() } - + searchField.placeholderString = "Enter city, state, country or timezone name" setupTimezoneDatasource() + + selectionsDataSource = PreferencesDataSource(callbackDelegate: self) + timezoneTableView.dataSource = selectionsDataSource + timezoneTableView.delegate = selectionsDataSource } deinit { @@ -316,59 +322,34 @@ class PreferencesViewController: ParentViewController { } extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate { - func numberOfRows(in tableView: NSTableView) -> Int { - var numberOfRows = 0 - - if tableView == timezoneTableView { - numberOfRows = selectedTimeZones.count - } else { - numberOfRows = numberOfSearchResults() - } - - return numberOfRows + func numberOfRows(in _: NSTableView) -> Int { + return numberOfSearchResults() } - - func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { + + func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row _: Int) -> NSView? { if let message = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCell"), owner: self) as? SearchResultTableViewCell { message.sourceName.stringValue = "Nicaragua" return message } - - return nil; + + return nil } func tableView(_: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { var dataSource: TimezoneData? - var selectedDataSource: TimezoneData? if filteredArray.count > row, let currentFilteredObject = filteredArray[row] as? TimezoneData { dataSource = currentFilteredObject } - if selectedTimeZones.count > row, let model = TimezoneData.customObject(from: selectedTimeZones[row]) { - selectedDataSource = model - } - - if tableColumn?.identifier.rawValue == PreferencesConstants.timezoneNameIdentifier { - return handleTimezoneNameIdentifier(for: row, selectedDataSource) - } - if tableColumn?.identifier.rawValue == PreferencesConstants.availableTimezoneIdentifier { if filteredArray.isEmpty { return timezoneArray[row] } - - return dataSource != nil ? - handleAvailableTimezoneColumn(for: row, dataSource) : - filteredArray[row] as? String - } - - if tableColumn?.identifier.rawValue == PreferencesConstants.customLabelIdentifier { - return selectedDataSource?.customLabel ?? "Error" - } - if tableColumn?.identifier.rawValue == "favouriteTimezone" { - return selectedDataSource?.isFavourite ?? 0 + return dataSource != nil ? + handleAvailableTimezoneColumn(for: row, dataSource) : + filteredArray[row] as? String } if tableColumn?.identifier.rawValue == "abbreviation" { @@ -378,18 +359,6 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate return nil } - private func handleTimezoneNameIdentifier(for _: Int, _ selectedDataSource: TimezoneData?) -> Any? { - guard let model = selectedDataSource else { - return nil - } - - if let address = model.formattedAddress, address.isEmpty == false { - return model.formattedAddress - } - - return model.timezoneID - } - private func handleAvailableTimezoneColumn(for row: Int, _ dataSource: TimezoneData?) -> Any? { if row < filteredArray.count { return dataSource?.formattedAddress @@ -413,27 +382,7 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate return nil } - func tableView(_: NSTableView, setObjectValue object: Any?, for _: NSTableColumn?, row: Int) { - guard !selectedTimeZones.isEmpty, let dataObject = TimezoneData.customObject(from: selectedTimeZones[row]) else { - return - } - - if let edit = object as? String { - setNewLabel(edit, for: dataObject, at: row) - } else if let isFavouriteValue = object as? NSNumber { - dataObject.isFavourite = isFavouriteValue.intValue - insert(timezone: dataObject, at: row) - dataObject.isFavourite == 1 ? - markAsFavorite(dataObject) : - unfavourite(dataObject) - updateStatusItem() - refreshTimezoneTableView() - } - - refreshMainTable() - } - - private func markAsFavorite(_ dataObject: TimezoneData) { + private func _markAsFavorite(_ dataObject: TimezoneData) { guard let menubarTitles = DataStore.shared().retrieve(key: CLMenubarFavorites) as? [Data] else { return } @@ -457,7 +406,7 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate } } - private func unfavourite(_ dataObject: TimezoneData) { + private func _unfavourite(_ dataObject: TimezoneData) { guard let menubarTimers = DataStore.shared().retrieve(key: CLMenubarFavorites) as? [Data] else { assertionFailure("Menubar timers is unexpectedly nil") return @@ -487,31 +436,6 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate } } - private func setNewLabel(_ label: String, for dataObject: TimezoneData, at row: Int) { - let formattedValue = label.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines) - - if selectedTimeZones.count > row { - Logger.log(object: [ - "Old Label": dataObject.customLabel ?? "Error", - "New Label": formattedValue, - ], - for: "Custom Label Changed") - - dataObject.setLabel(formattedValue) - - insert(timezone: dataObject, at: row) - - updateMenubarTitles() - } else { - Logger.log(object: [ - "MethodName": "SetObjectValue", - "Selected Timezone Count": selectedTimeZones.count, - "Current Row": row, - ], - for: "Error in selected row count") - } - } - private func showAlertIfMoreThanOneTimezoneHasBeenAddedToTheMenubar() { let isUITestRunning = ProcessInfo.processInfo.arguments.contains(CLUITestingLaunchArgument) @@ -558,100 +482,6 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate } } } - - func tableView(_: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool { - let data = NSKeyedArchiver.archivedData(withRootObject: rowIndexes) - - pboard.declareTypes([.dragSession], owner: self) - pboard.setData(data, forType: .dragSession) - - return true - } - - func tableView(_: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation _: NSTableView.DropOperation) -> Bool { - var newOrder = selectedTimeZones - - var destination = row - - if row == newOrder.count { - destination -= 1 - } - - let pBoard = info.draggingPasteboard - - guard let data = pBoard.data(forType: .dragSession) else { - assertionFailure("Data was unexpectedly nil") - return false - } - - guard let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: data) as? IndexSet, let first = rowIndexes.first else { - assertionFailure("Row was unexpectedly nil") - return false - } - - let currentObject = newOrder[first] - - newOrder.remove(at: first) - - newOrder.insert(currentObject, at: destination) - - DataStore.shared().setTimezones(newOrder) - - timezoneTableView.reloadData() - - refreshMainTable() - - timezoneTableView.deselectRow(timezoneTableView.selectedRow) - - return true - } - - func tableView(_: NSTableView, validateDrop _: NSDraggingInfo, proposedRow _: Int, proposedDropOperation _: NSTableView.DropOperation) -> NSDragOperation { - return .every - } - - func tableViewSelectionDidChange(_: Notification) { - deleteButton.isEnabled = !(timezoneTableView.selectedRow == -1) - } - - func tableView(_ tableView: NSTableView, didClick tableColumn: NSTableColumn) { - if tableColumn.identifier.rawValue == "favouriteTimezone" { - return - } - - if tableView == timezoneTableView { - let sortedTimezones = selectedTimeZones.sorted { (obj1, obj2) -> Bool in - - guard let object1 = TimezoneData.customObject(from: obj1), - let object2 = TimezoneData.customObject(from: obj2) else { - assertionFailure("Data was unexpectedly nil") - return false - } - - if tableColumn.identifier.rawValue == "formattedAddress" { - return arePlacesSortedInAscendingOrder ? - object1.formattedAddress! > object2.formattedAddress! : - object1.formattedAddress! < object2.formattedAddress! - } else { - return arePlacesSortedInAscendingOrder ? - object1.customLabel! > object2.customLabel! : - object1.customLabel! < object2.customLabel! - } - } - - let indicatorImage = arePlacesSortedInAscendingOrder ? - NSImage(named: NSImage.Name("NSDescendingSortIndicator"))! : - NSImage(named: NSImage.Name("NSAscendingSortIndicator"))! - - timezoneTableView.setIndicatorImage(indicatorImage, in: tableColumn) - - arePlacesSortedInAscendingOrder.toggle() - - DataStore.shared().setTimezones(sortedTimezones) - - updateAfterSorting() - } - } } extension PreferencesViewController { @@ -716,7 +546,7 @@ extension PreferencesViewController { }) } } - + private func findLocalSearchResultsForTimezones() { timezoneFilteredArray = [] let lowercasedSearchString = searchField.stringValue.lowercased() @@ -763,7 +593,6 @@ extension PreferencesViewController { self.filteredArray.append(TimezoneData(with: totalPackage)) } - } private func prepareUIForPresentingResults() { @@ -925,7 +754,7 @@ extension PreferencesViewController { availableTimezoneTableView.isHidden = false isActivityInProgress = false } - + private func setupTimezoneDatasource() { timezoneArray = [] timezoneArray.append("UTC") @@ -973,20 +802,20 @@ extension PreferencesViewController { cleanupAfterInstallingTimezone() return } - + guard let dataObject = filteredArray[availableTimezoneTableView.selectedRow] as? TimezoneData else { assertionFailure("Data was unexpectedly nil") return } - + if messageLabel.stringValue.isEmpty { searchField.stringValue = CLEmptyString - + guard let latitude = dataObject.latitude, let longitude = dataObject.longitude else { assertionFailure("Data was unexpectedly nil") return } - + getTimezone(for: latitude, and: longitude) } } @@ -1001,7 +830,7 @@ extension PreferencesViewController { } let currentSelection = filteredArray[availableTimezoneTableView.selectedRow] - + guard let selection = currentSelection as? String else { assertionFailure() return @@ -1168,7 +997,7 @@ extension PreferencesViewController { availableTimezoneTableView.reloadData() } - @IBAction func filterArray(_ sender: Any?) { + @IBAction func filterArray(_: Any?) { messageLabel.stringValue = CLEmptyString filteredArray = [] @@ -1336,3 +1165,63 @@ extension PreferencesViewController { class SearchResultTableViewCell: NSTableCellView { @IBOutlet var sourceName: NSTextField! } + +extension PreferencesViewController: PreferenceSelectionUpdates { + func didAddTimezone(_: TimezoneData) {} + func markAsFavorite(_ dataObject: TimezoneData) { + _markAsFavorite(dataObject) + } + + func unfavourite(_ dataObject: TimezoneData) { + _unfavourite(dataObject) + } + + func refreshTimezoneTable() { + refreshTimezoneTableView() + } + + func refreshMainTableView() { + refreshMainTable() + } + + func tableViewSelectionDidChange(_ status: Bool) { + deleteButton.isEnabled = !status + } + + func table(didClick tableColumn: NSTableColumn) { + if tableColumn.identifier.rawValue == "favouriteTimezone" { + return + } + + let sortedTimezones = selectedTimeZones.sorted { (obj1, obj2) -> Bool in + + guard let object1 = TimezoneData.customObject(from: obj1), + let object2 = TimezoneData.customObject(from: obj2) else { + assertionFailure("Data was unexpectedly nil") + return false + } + + if tableColumn.identifier.rawValue == "formattedAddress" { + return arePlacesSortedInAscendingOrder ? + object1.formattedAddress! > object2.formattedAddress! : + object1.formattedAddress! < object2.formattedAddress! + } else { + return arePlacesSortedInAscendingOrder ? + object1.customLabel! > object2.customLabel! : + object1.customLabel! < object2.customLabel! + } + } + + let indicatorImage = arePlacesSortedInAscendingOrder ? + NSImage(named: NSImage.Name("NSDescendingSortIndicator"))! : + NSImage(named: NSImage.Name("NSAscendingSortIndicator"))! + + timezoneTableView.setIndicatorImage(indicatorImage, in: tableColumn) + + arePlacesSortedInAscendingOrder.toggle() + + DataStore.shared().setTimezones(sortedTimezones) + + updateAfterSorting() + } +} diff --git a/Clocker/Preferences/Preferences.storyboard b/Clocker/Preferences/Preferences.storyboard index fe50f59..02c2279 100644 --- a/Clocker/Preferences/Preferences.storyboard +++ b/Clocker/Preferences/Preferences.storyboard @@ -1472,10 +1472,6 @@ - - - - @@ -1649,7 +1645,7 @@ CA - +