|
|
@ -14,6 +14,18 @@ struct PreferencesConstants { |
|
|
|
static let offlineErrorMessage = "The Internet connection appears to be offline." |
|
|
|
static let offlineErrorMessage = "The Internet connection appears to be offline." |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum RowType { |
|
|
|
|
|
|
|
case timezoneHeader |
|
|
|
|
|
|
|
case cityHeader |
|
|
|
|
|
|
|
case city |
|
|
|
|
|
|
|
case timezone |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct TimezoneMetadata { |
|
|
|
|
|
|
|
let timezone: Timezone |
|
|
|
|
|
|
|
let tages: Set<String> = Set() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class PreferencesViewController: ParentViewController { |
|
|
|
class PreferencesViewController: ParentViewController { |
|
|
|
private var isActivityInProgress = false { |
|
|
|
private var isActivityInProgress = false { |
|
|
|
didSet { |
|
|
|
didSet { |
|
|
@ -33,7 +45,6 @@ class PreferencesViewController: ParentViewController { |
|
|
|
private var filteredArray: [Any] = [] |
|
|
|
private var filteredArray: [Any] = [] |
|
|
|
private var timezoneArray: [String] = [] |
|
|
|
private var timezoneArray: [String] = [] |
|
|
|
private var timezoneFilteredArray: [String] = [] |
|
|
|
private var timezoneFilteredArray: [String] = [] |
|
|
|
private var columnName = "Place(s)" |
|
|
|
|
|
|
|
private var dataTask: URLSessionDataTask? = .none |
|
|
|
private var dataTask: URLSessionDataTask? = .none |
|
|
|
|
|
|
|
|
|
|
|
private lazy var notimezoneView: NoTimezoneView? = { |
|
|
|
private lazy var notimezoneView: NoTimezoneView? = { |
|
|
@ -75,8 +86,8 @@ class PreferencesViewController: ParentViewController { |
|
|
|
|
|
|
|
|
|
|
|
@IBOutlet var sortToggle: NSButton! |
|
|
|
@IBOutlet var sortToggle: NSButton! |
|
|
|
private var themeDidChangeNotification: NSObjectProtocol? |
|
|
|
private var themeDidChangeNotification: NSObjectProtocol? |
|
|
|
|
|
|
|
|
|
|
|
private var selectionsDataSource: PreferencesDataSource! |
|
|
|
private var selectionsDataSource: PreferencesDataSource! |
|
|
|
|
|
|
|
private var finalArray: [RowType] = [] |
|
|
|
|
|
|
|
|
|
|
|
override func viewDidLoad() { |
|
|
|
override func viewDidLoad() { |
|
|
|
super.viewDidLoad() |
|
|
|
super.viewDidLoad() |
|
|
@ -90,8 +101,6 @@ class PreferencesViewController: ParentViewController { |
|
|
|
|
|
|
|
|
|
|
|
setup() |
|
|
|
setup() |
|
|
|
|
|
|
|
|
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setupShortcutObserver() |
|
|
|
setupShortcutObserver() |
|
|
|
|
|
|
|
|
|
|
|
darkModeChanges() |
|
|
|
darkModeChanges() |
|
|
@ -106,9 +115,37 @@ class PreferencesViewController: ParentViewController { |
|
|
|
selectionsDataSource = PreferencesDataSource(callbackDelegate: self) |
|
|
|
selectionsDataSource = PreferencesDataSource(callbackDelegate: self) |
|
|
|
timezoneTableView.dataSource = selectionsDataSource |
|
|
|
timezoneTableView.dataSource = selectionsDataSource |
|
|
|
timezoneTableView.delegate = selectionsDataSource |
|
|
|
timezoneTableView.delegate = selectionsDataSource |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reloadSearchResults() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private func calculateArray() { |
|
|
|
|
|
|
|
finalArray = [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func addTimezonesIfNeeded(_ data: [String]) { |
|
|
|
|
|
|
|
if !data.isEmpty { |
|
|
|
|
|
|
|
finalArray.append(.timezoneHeader) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
data.forEach { (_) in |
|
|
|
|
|
|
|
finalArray.append(.timezone) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if searchField.stringValue.isEmpty { |
|
|
|
|
|
|
|
addTimezonesIfNeeded(timezoneArray) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if !filteredArray.isEmpty { |
|
|
|
|
|
|
|
finalArray.append(.cityHeader) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
filteredArray.forEach { (_) in |
|
|
|
|
|
|
|
finalArray.append(.city) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
addTimezonesIfNeeded(timezoneFilteredArray) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
deinit { |
|
|
|
deinit { |
|
|
|
|
|
|
|
// We still need to remove observers set using NotificationCenter block: APIs |
|
|
|
if let themeDidChangeNotif = themeDidChangeNotification { |
|
|
|
if let themeDidChangeNotif = themeDidChangeNotification { |
|
|
|
NotificationCenter.default.removeObserver(themeDidChangeNotif) |
|
|
|
NotificationCenter.default.removeObserver(themeDidChangeNotif) |
|
|
|
} |
|
|
|
} |
|
|
@ -223,12 +260,6 @@ class PreferencesViewController: ParentViewController { |
|
|
|
|
|
|
|
|
|
|
|
[placeholderLabel, additionalSortOptions].forEach { $0.isHidden = true } |
|
|
|
[placeholderLabel, additionalSortOptions].forEach { $0.isHidden = true } |
|
|
|
|
|
|
|
|
|
|
|
if timezoneArray.isEmpty { |
|
|
|
|
|
|
|
timezoneArray.append("UTC") |
|
|
|
|
|
|
|
timezoneArray.append("Anywhere on Earth") |
|
|
|
|
|
|
|
timezoneArray.append(contentsOf: NSTimeZone.knownTimeZoneNames) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
messageLabel.stringValue = CLEmptyString |
|
|
|
messageLabel.stringValue = CLEmptyString |
|
|
|
|
|
|
|
|
|
|
|
timezoneTableView.registerForDraggedTypes([.dragSession]) |
|
|
|
timezoneTableView.registerForDraggedTypes([.dragSession]) |
|
|
@ -326,59 +357,71 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate |
|
|
|
return numberOfSearchResults() |
|
|
|
return numberOfSearchResults() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row _: Int) -> NSView? { |
|
|
|
func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool { |
|
|
|
if let message = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCell"), owner: self) as? SearchResultTableViewCell { |
|
|
|
let currentRowType = finalArray[row] |
|
|
|
message.sourceName.stringValue = "Nicaragua" |
|
|
|
return |
|
|
|
return message |
|
|
|
currentRowType == .timezoneHeader || |
|
|
|
|
|
|
|
currentRowType == .cityHeader |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool { |
|
|
|
|
|
|
|
print("Should Select Row") |
|
|
|
|
|
|
|
let currentRowType = finalArray[row] |
|
|
|
|
|
|
|
return !(currentRowType == .timezoneHeader || currentRowType == .cityHeader) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func tableView(_: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { |
|
|
|
func tableView(_ tableView: NSTableView, selectionIndexesForProposedSelection proposedSelectionIndexes: IndexSet) -> IndexSet { |
|
|
|
var dataSource: TimezoneData? |
|
|
|
// print("Selection Indexes for Proposed Selection: \(proposedSelectionIndexes.first!)") |
|
|
|
|
|
|
|
return proposedSelectionIndexes |
|
|
|
if filteredArray.count > row, let currentFilteredObject = filteredArray[row] as? TimezoneData { |
|
|
|
|
|
|
|
dataSource = currentFilteredObject |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if tableColumn?.identifier.rawValue == PreferencesConstants.availableTimezoneIdentifier { |
|
|
|
func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? { |
|
|
|
if filteredArray.isEmpty { |
|
|
|
let currentRowType = finalArray[row] |
|
|
|
return timezoneArray[row] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return dataSource != nil ? |
|
|
|
switch currentRowType { |
|
|
|
handleAvailableTimezoneColumn(for: row, dataSource) : |
|
|
|
case .timezoneHeader, .cityHeader: |
|
|
|
filteredArray[row] as? String |
|
|
|
return headerCell(tableView, currentRowType) |
|
|
|
|
|
|
|
case .timezone: |
|
|
|
|
|
|
|
return timezoneCell(tableView, currentRowType, row) |
|
|
|
|
|
|
|
case .city: |
|
|
|
|
|
|
|
return cityCell(tableView, currentRowType, row) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if tableColumn?.identifier.rawValue == "abbreviation" { |
|
|
|
|
|
|
|
return handleAbbreviationColumn(for: row) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private func timezoneCell(_ tableView: NSTableView, _ rowType: RowType, _ row: Int) -> NSView? { |
|
|
|
|
|
|
|
if let message = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCell"), owner: self) as? SearchResultTableViewCell { |
|
|
|
|
|
|
|
let datasource = searchField.stringValue.isEmpty ? timezoneArray : timezoneFilteredArray |
|
|
|
|
|
|
|
guard !datasource.isEmpty else { |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
let index = searchField.stringValue.isEmpty ? row - 1 : row |
|
|
|
private func handleAvailableTimezoneColumn(for row: Int, _ dataSource: TimezoneData?) -> Any? { |
|
|
|
message.sourceName.stringValue = datasource[index % datasource.count] |
|
|
|
if row < filteredArray.count { |
|
|
|
return message |
|
|
|
return dataSource?.formattedAddress |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private func handleAbbreviationColumn(for row: Int) -> Any? { |
|
|
|
private func cityCell(_ tableView: NSTableView, _ rowType: RowType, _ row: Int) -> NSView? { |
|
|
|
if timezoneArray.count > row { |
|
|
|
if let cityCell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCell"), owner: self) as? SearchResultTableViewCell { |
|
|
|
// Special return for manually inserted 'UTC' |
|
|
|
|
|
|
|
if timezoneArray[row] == "UTC" { |
|
|
|
guard let timezoneData = filteredArray[row % filteredArray.count] as? TimezoneData else { |
|
|
|
return "UTC" |
|
|
|
assertionFailure() |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cityCell.sourceName.stringValue = timezoneData.formattedAddress ?? "Error" |
|
|
|
|
|
|
|
return cityCell |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if timezoneArray[row] == "Anywhere on Earth" { |
|
|
|
return nil |
|
|
|
return "AoE" |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return NSTimeZone(name: timezoneArray[row])?.abbreviation ?? "Error" |
|
|
|
private func headerCell(_ tableView: NSTableView, _ headerType: RowType) -> NSView? { |
|
|
|
|
|
|
|
if let message = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "headerCell"), owner: self) as? HeaderTableViewCell { |
|
|
|
|
|
|
|
message.headerField.stringValue = headerType == .timezoneHeader ? "Timezones" : "Places" |
|
|
|
|
|
|
|
return message |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -534,6 +577,8 @@ extension PreferencesViewController { |
|
|
|
|
|
|
|
|
|
|
|
if searchResults?.status == "ZERO_RESULTS" { |
|
|
|
if searchResults?.status == "ZERO_RESULTS" { |
|
|
|
self.placeholderLabel.placeholderString = "No results! 😔 Try entering the exact name." |
|
|
|
self.placeholderLabel.placeholderString = "No results! 😔 Try entering the exact name." |
|
|
|
|
|
|
|
self.findLocalSearchResultsForTimezones() |
|
|
|
|
|
|
|
self.reloadSearchResults() |
|
|
|
self.isActivityInProgress = false |
|
|
|
self.isActivityInProgress = false |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -551,7 +596,6 @@ extension PreferencesViewController { |
|
|
|
timezoneFilteredArray = [] |
|
|
|
timezoneFilteredArray = [] |
|
|
|
let lowercasedSearchString = searchField.stringValue.lowercased() |
|
|
|
let lowercasedSearchString = searchField.stringValue.lowercased() |
|
|
|
timezoneFilteredArray = timezoneArray.filter { $0.lowercased().contains(lowercasedSearchString) } |
|
|
|
timezoneFilteredArray = timezoneArray.filter { $0.lowercased().contains(lowercasedSearchString) } |
|
|
|
filteredArray.append(contentsOf: timezoneFilteredArray) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private func generateSearchURL() -> String { |
|
|
|
private func generateSearchURL() -> String { |
|
|
@ -598,6 +642,12 @@ extension PreferencesViewController { |
|
|
|
private func prepareUIForPresentingResults() { |
|
|
|
private func prepareUIForPresentingResults() { |
|
|
|
placeholderLabel.placeholderString = CLEmptyString |
|
|
|
placeholderLabel.placeholderString = CLEmptyString |
|
|
|
isActivityInProgress = false |
|
|
|
isActivityInProgress = false |
|
|
|
|
|
|
|
reloadSearchResults() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private func reloadSearchResults() { |
|
|
|
|
|
|
|
print("Reloading Search Results") |
|
|
|
|
|
|
|
calculateArray() |
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -658,11 +708,12 @@ extension PreferencesViewController { |
|
|
|
|
|
|
|
|
|
|
|
OperationQueue.main.addOperation { |
|
|
|
OperationQueue.main.addOperation { |
|
|
|
if self.handleEdgeCase(for: response) == true { |
|
|
|
if self.handleEdgeCase(for: response) == true { |
|
|
|
|
|
|
|
self.reloadSearchResults() |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if error == nil, let json = response, let timezone = self.decodeTimezone(from: json) { |
|
|
|
if error == nil, let json = response, let timezone = self.decodeTimezone(from: json) { |
|
|
|
if self.availableTimezoneTableView.selectedRow >= 0, self.availableTimezoneTableView.selectedRow < self.filteredArray.count { |
|
|
|
if self.availableTimezoneTableView.selectedRow >= 0 { |
|
|
|
self.installTimezone(timezone) |
|
|
|
self.installTimezone(timezone) |
|
|
|
} |
|
|
|
} |
|
|
|
self.updateViewState() |
|
|
|
self.updateViewState() |
|
|
@ -682,7 +733,7 @@ extension PreferencesViewController { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private func installTimezone(_ timezone: Timezone) { |
|
|
|
private func installTimezone(_ timezone: Timezone) { |
|
|
|
guard let dataObject = self.filteredArray[self.availableTimezoneTableView.selectedRow] as? TimezoneData else { |
|
|
|
guard let dataObject = self.filteredArray[self.availableTimezoneTableView.selectedRow % filteredArray.count] as? TimezoneData else { |
|
|
|
assertionFailure("Data was unexpectedly nil") |
|
|
|
assertionFailure("Data was unexpectedly nil") |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -720,7 +771,7 @@ extension PreferencesViewController { |
|
|
|
placeholderLabel.placeholderString = PreferencesConstants.noInternetConnectivityError |
|
|
|
placeholderLabel.placeholderString = PreferencesConstants.noInternetConnectivityError |
|
|
|
isActivityInProgress = false |
|
|
|
isActivityInProgress = false |
|
|
|
filteredArray = [] |
|
|
|
filteredArray = [] |
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
reloadSearchResults() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Returns true if there's an error. |
|
|
|
/// Returns true if there's an error. |
|
|
@ -745,7 +796,7 @@ extension PreferencesViewController { |
|
|
|
|
|
|
|
|
|
|
|
private func updateViewState() { |
|
|
|
private func updateViewState() { |
|
|
|
filteredArray = [] |
|
|
|
filteredArray = [] |
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
reloadSearchResults() |
|
|
|
refreshTimezoneTableView() |
|
|
|
refreshTimezoneTableView() |
|
|
|
refreshMainTable() |
|
|
|
refreshMainTable() |
|
|
|
timezonePanel.close() |
|
|
|
timezonePanel.close() |
|
|
@ -798,12 +849,43 @@ extension PreferencesViewController { |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if let dataObject = filteredArray[availableTimezoneTableView.selectedRow] as? String, dataObject != nil { |
|
|
|
if searchField.stringValue.isEmpty { |
|
|
|
|
|
|
|
addTimezoneIfSearchStringIsEmpty() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
addTimezoneIfSearchStringIsNotEmpty() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private func addTimezoneIfSearchStringIsEmpty() { |
|
|
|
|
|
|
|
let currentRowType = finalArray[availableTimezoneTableView.selectedRow] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch currentRowType { |
|
|
|
|
|
|
|
case .timezoneHeader, .cityHeader: |
|
|
|
|
|
|
|
isActivityInProgress = false |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
case .timezone: |
|
|
|
cleanupAfterInstallingTimezone() |
|
|
|
cleanupAfterInstallingTimezone() |
|
|
|
|
|
|
|
default: |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
guard let dataObject = filteredArray[availableTimezoneTableView.selectedRow] as? TimezoneData else { |
|
|
|
private func addTimezoneIfSearchStringIsNotEmpty() { |
|
|
|
|
|
|
|
let currentRowType = finalArray[availableTimezoneTableView.selectedRow] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch currentRowType { |
|
|
|
|
|
|
|
case .timezoneHeader, .cityHeader: |
|
|
|
|
|
|
|
isActivityInProgress = false |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
case .timezone: |
|
|
|
|
|
|
|
cleanupAfterInstallingTimezone() |
|
|
|
|
|
|
|
case .city: |
|
|
|
|
|
|
|
cleanupAfterInstallingCity() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private func cleanupAfterInstallingCity() { |
|
|
|
|
|
|
|
guard let dataObject = filteredArray[availableTimezoneTableView.selectedRow % filteredArray.count] as? TimezoneData else { |
|
|
|
assertionFailure("Data was unexpectedly nil") |
|
|
|
assertionFailure("Data was unexpectedly nil") |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -825,23 +907,14 @@ extension PreferencesViewController { |
|
|
|
data.setLabel(CLEmptyString) |
|
|
|
data.setLabel(CLEmptyString) |
|
|
|
|
|
|
|
|
|
|
|
if searchField.stringValue.isEmpty == false { |
|
|
|
if searchField.stringValue.isEmpty == false { |
|
|
|
if filteredArray.count <= availableTimezoneTableView.selectedRow { |
|
|
|
let currentSelection = timezoneFilteredArray[availableTimezoneTableView.selectedRow % timezoneFilteredArray.count] |
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let currentSelection = filteredArray[availableTimezoneTableView.selectedRow] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
guard let selection = currentSelection as? String else { |
|
|
|
|
|
|
|
assertionFailure() |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let metaInfo = metadata(for: selection) |
|
|
|
let metaInfo = metadata(for: currentSelection) |
|
|
|
data.timezoneID = metaInfo.0 |
|
|
|
data.timezoneID = metaInfo.0 |
|
|
|
data.formattedAddress = metaInfo.1 |
|
|
|
data.formattedAddress = metaInfo.1 |
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
let currentSelection = timezoneArray[availableTimezoneTableView.selectedRow] |
|
|
|
let currentSelection = timezoneArray[availableTimezoneTableView.selectedRow - 1] |
|
|
|
|
|
|
|
|
|
|
|
let metaInfo = metadata(for: currentSelection) |
|
|
|
let metaInfo = metadata(for: currentSelection) |
|
|
|
data.timezoneID = metaInfo.0 |
|
|
|
data.timezoneID = metaInfo.0 |
|
|
@ -856,7 +929,7 @@ extension PreferencesViewController { |
|
|
|
filteredArray = [] |
|
|
|
filteredArray = [] |
|
|
|
timezoneFilteredArray = [] |
|
|
|
timezoneFilteredArray = [] |
|
|
|
|
|
|
|
|
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
reloadSearchResults() |
|
|
|
|
|
|
|
|
|
|
|
refreshTimezoneTableView() |
|
|
|
refreshTimezoneTableView() |
|
|
|
|
|
|
|
|
|
|
@ -887,21 +960,15 @@ extension PreferencesViewController { |
|
|
|
|
|
|
|
|
|
|
|
@IBAction func closePanel(_: NSButton) { |
|
|
|
@IBAction func closePanel(_: NSButton) { |
|
|
|
filteredArray = [] |
|
|
|
filteredArray = [] |
|
|
|
|
|
|
|
timezoneFilteredArray = [] |
|
|
|
columnName = "Place(s)" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
searchField.stringValue = CLEmptyString |
|
|
|
searchField.stringValue = CLEmptyString |
|
|
|
|
|
|
|
|
|
|
|
placeholderLabel.placeholderString = CLEmptyString |
|
|
|
placeholderLabel.placeholderString = CLEmptyString |
|
|
|
|
|
|
|
|
|
|
|
searchField.placeholderString = "Enter a city, state or country name" |
|
|
|
searchField.placeholderString = "Enter a city, state or country name" |
|
|
|
|
|
|
|
|
|
|
|
timezonePanel.close() |
|
|
|
reloadSearchResults() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timezonePanel.close() |
|
|
|
isActivityInProgress = false |
|
|
|
isActivityInProgress = false |
|
|
|
|
|
|
|
|
|
|
|
addTimezoneButton.state = .off |
|
|
|
addTimezoneButton.state = .off |
|
|
|
|
|
|
|
|
|
|
|
// The table might be hidden because of an early exit especially |
|
|
|
// The table might be hidden because of an early exit especially |
|
|
@ -994,7 +1061,6 @@ extension PreferencesViewController { |
|
|
|
@IBAction func filterTimezoneArray(_: Any?) { |
|
|
|
@IBAction func filterTimezoneArray(_: Any?) { |
|
|
|
let lowercasedSearchString = searchField.stringValue.lowercased() |
|
|
|
let lowercasedSearchString = searchField.stringValue.lowercased() |
|
|
|
timezoneFilteredArray = timezoneArray.filter { $0.lowercased().contains(lowercasedSearchString) } |
|
|
|
timezoneFilteredArray = timezoneArray.filter { $0.lowercased().contains(lowercasedSearchString) } |
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@IBAction func filterArray(_: Any?) { |
|
|
|
@IBAction func filterArray(_: Any?) { |
|
|
@ -1005,6 +1071,7 @@ extension PreferencesViewController { |
|
|
|
if searchField.stringValue.count > 50 { |
|
|
|
if searchField.stringValue.count > 50 { |
|
|
|
isActivityInProgress = false |
|
|
|
isActivityInProgress = false |
|
|
|
messageLabel.stringValue = PreferencesConstants.maxCharactersAllowed |
|
|
|
messageLabel.stringValue = PreferencesConstants.maxCharactersAllowed |
|
|
|
|
|
|
|
reloadSearchResults() |
|
|
|
Timer.scheduledTimer(withTimeInterval: 5, |
|
|
|
Timer.scheduledTimer(withTimeInterval: 5, |
|
|
|
repeats: false) { _ in |
|
|
|
repeats: false) { _ in |
|
|
|
OperationQueue.main.addOperation { |
|
|
|
OperationQueue.main.addOperation { |
|
|
@ -1022,7 +1089,7 @@ extension PreferencesViewController { |
|
|
|
resetSearchView() |
|
|
|
resetSearchView() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
availableTimezoneTableView.reloadData() |
|
|
|
reloadSearchResults() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1079,7 +1146,9 @@ extension PreferencesViewController { |
|
|
|
return isLabelOptionSelected ? object1.customLabel! > object2.customLabel! : object1.customLabel! < object2.customLabel! |
|
|
|
return isLabelOptionSelected ? object1.customLabel! > object2.customLabel! : object1.customLabel! < object2.customLabel! |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sender.image = isLabelOptionSelected ? NSImage(named: NSImage.Name("NSDescendingSortIndicator"))! : NSImage(named: NSImage.Name("NSAscendingSortIndicator"))! |
|
|
|
sender.image = isLabelOptionSelected ? |
|
|
|
|
|
|
|
NSImage(named: NSImage.Name("NSDescendingSortIndicator"))! : |
|
|
|
|
|
|
|
NSImage(named: NSImage.Name("NSAscendingSortIndicator"))! |
|
|
|
|
|
|
|
|
|
|
|
isLabelOptionSelected.toggle() |
|
|
|
isLabelOptionSelected.toggle() |
|
|
|
|
|
|
|
|
|
|
@ -1111,9 +1180,7 @@ extension PreferencesViewController { |
|
|
|
|
|
|
|
|
|
|
|
private func updateAfterSorting() { |
|
|
|
private func updateAfterSorting() { |
|
|
|
let newDefaults = selectedTimeZones |
|
|
|
let newDefaults = selectedTimeZones |
|
|
|
|
|
|
|
|
|
|
|
DataStore.shared().setTimezones(newDefaults) |
|
|
|
DataStore.shared().setTimezones(newDefaults) |
|
|
|
|
|
|
|
|
|
|
|
refreshTimezoneTableView() |
|
|
|
refreshTimezoneTableView() |
|
|
|
refreshMainTable() |
|
|
|
refreshMainTable() |
|
|
|
} |
|
|
|
} |
|
|
@ -1124,11 +1191,7 @@ extension PreferencesViewController: SRRecorderControlDelegate {} |
|
|
|
// Helpers |
|
|
|
// Helpers |
|
|
|
extension PreferencesViewController { |
|
|
|
extension PreferencesViewController { |
|
|
|
private func numberOfSearchResults() -> Int { |
|
|
|
private func numberOfSearchResults() -> Int { |
|
|
|
if searchField.stringValue.isEmpty == false { |
|
|
|
return finalArray.count |
|
|
|
return filteredArray.count |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return timezoneArray.count |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private func insert(timezone: TimezoneData, at index: Int) { |
|
|
|
private func insert(timezone: TimezoneData, at index: Int) { |
|
|
@ -1143,8 +1206,11 @@ class SearchResultTableViewCell: NSTableCellView { |
|
|
|
@IBOutlet var sourceName: NSTextField! |
|
|
|
@IBOutlet var sourceName: NSTextField! |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HeaderTableViewCell: NSTableCellView { |
|
|
|
|
|
|
|
@IBOutlet var headerField: NSTextField! |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
extension PreferencesViewController: PreferenceSelectionUpdates { |
|
|
|
extension PreferencesViewController: PreferenceSelectionUpdates { |
|
|
|
func didAddTimezone(_: TimezoneData) {} |
|
|
|
|
|
|
|
func markAsFavorite(_ dataObject: TimezoneData) { |
|
|
|
func markAsFavorite(_ dataObject: TimezoneData) { |
|
|
|
_markAsFavorite(dataObject) |
|
|
|
_markAsFavorite(dataObject) |
|
|
|
} |
|
|
|
} |
|
|
|