macOS: Ability to remove multiple tunnels at a time
This commit is contained in:
parent
8648f80877
commit
9c71d63254
|
@ -271,6 +271,7 @@
|
||||||
"macWindowTitleManageTunnels" = "Manage WireGuard Tunnels";
|
"macWindowTitleManageTunnels" = "Manage WireGuard Tunnels";
|
||||||
|
|
||||||
"macDeleteTunnelConfirmationAlertMessage (%@)" = "Are you sure you want to delete ‘%@’?";
|
"macDeleteTunnelConfirmationAlertMessage (%@)" = "Are you sure you want to delete ‘%@’?";
|
||||||
|
"macDeleteMultipleTunnelsConfirmationAlertMessage (%d)" = "Are you sure you want to delete %d tunnels?";
|
||||||
"macDeleteTunnelConfirmationAlertInfo" = "You cannot undo this action.";
|
"macDeleteTunnelConfirmationAlertInfo" = "You cannot undo this action.";
|
||||||
"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Delete";
|
"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Delete";
|
||||||
"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Cancel";
|
"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Cancel";
|
||||||
|
@ -284,6 +285,8 @@
|
||||||
"macNameFieldExportZip" = "Export tunnels to";
|
"macNameFieldExportZip" = "Export tunnels to";
|
||||||
"macSheetButtonExportZip" = "Save";
|
"macSheetButtonExportZip" = "Save";
|
||||||
|
|
||||||
|
"macButtonDeleteTunnels (%d)" = "Delete %d tunnels";
|
||||||
|
|
||||||
// Mac detail/edit view fields
|
// Mac detail/edit view fields
|
||||||
|
|
||||||
"macFieldKey (%@)" = "%@:";
|
"macFieldKey (%@)" = "%@:";
|
||||||
|
|
|
@ -77,10 +77,27 @@ class ManageTunnelsRootViewController: NSViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ManageTunnelsRootViewController: TunnelsListTableViewControllerDelegate {
|
extension ManageTunnelsRootViewController: TunnelsListTableViewControllerDelegate {
|
||||||
func tunnelSelected(tunnel: TunnelContainer) {
|
func tunnelsSelected(tunnelIndices: [Int]) {
|
||||||
let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager, tunnel: tunnel)
|
assert(!tunnelIndices.isEmpty)
|
||||||
setTunnelDetailContentVC(tunnelDetailVC)
|
if tunnelIndices.count == 1 {
|
||||||
self.tunnelDetailVC = tunnelDetailVC
|
let tunnel = tunnelsManager.tunnel(at: tunnelIndices.first!)
|
||||||
|
let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager, tunnel: tunnel)
|
||||||
|
setTunnelDetailContentVC(tunnelDetailVC)
|
||||||
|
self.tunnelDetailVC = tunnelDetailVC
|
||||||
|
} else if tunnelIndices.count > 1 {
|
||||||
|
let multiSelectionVC: ButtonedDetailViewController
|
||||||
|
if let buttonedDetailVC = tunnelDetailContentVC as? ButtonedDetailViewController {
|
||||||
|
multiSelectionVC = buttonedDetailVC
|
||||||
|
} else {
|
||||||
|
multiSelectionVC = ButtonedDetailViewController()
|
||||||
|
}
|
||||||
|
multiSelectionVC.setButtonTitle(tr(format: "macButtonDeleteTunnels (%d)", tunnelIndices.count))
|
||||||
|
multiSelectionVC.onButtonClicked = { [weak tunnelsListVC] in
|
||||||
|
tunnelsListVC?.handleRemoveTunnelAction()
|
||||||
|
}
|
||||||
|
setTunnelDetailContentVC(multiSelectionVC)
|
||||||
|
self.tunnelDetailVC = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tunnelsListEmpty() {
|
func tunnelsListEmpty() {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
protocol TunnelsListTableViewControllerDelegate: class {
|
protocol TunnelsListTableViewControllerDelegate: class {
|
||||||
func tunnelSelected(tunnel: TunnelContainer)
|
func tunnelsSelected(tunnelIndices: [Int])
|
||||||
func tunnelsListEmpty()
|
func tunnelsListEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ class TunnelsListTableViewController: NSViewController {
|
||||||
tableView.addTableColumn(NSTableColumn(identifier: NSUserInterfaceItemIdentifier("TunnelsList")))
|
tableView.addTableColumn(NSTableColumn(identifier: NSUserInterfaceItemIdentifier("TunnelsList")))
|
||||||
tableView.headerView = nil
|
tableView.headerView = nil
|
||||||
tableView.rowSizeStyle = .medium
|
tableView.rowSizeStyle = .medium
|
||||||
|
tableView.allowsMultipleSelection = true
|
||||||
return tableView
|
return tableView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -158,18 +159,24 @@ class TunnelsListTableViewController: NSViewController {
|
||||||
|
|
||||||
@objc func handleRemoveTunnelAction() {
|
@objc func handleRemoveTunnelAction() {
|
||||||
guard let window = view.window else { return }
|
guard let window = view.window else { return }
|
||||||
let selectedTunnelIndex = tableView.selectedRow
|
let selectedTunnelIndices = tableView.selectedRowIndexes.sorted()
|
||||||
guard selectedTunnelIndex >= 0 && selectedTunnelIndex < tunnelsManager.numberOfTunnels() else { return }
|
let selectedTunnels = selectedTunnelIndices.compactMap { tunnelIndex in
|
||||||
let selectedTunnel = tunnelsManager.tunnel(at: selectedTunnelIndex)
|
tunnelIndex >= 0 && tunnelIndex < tunnelsManager.numberOfTunnels() ? tunnelsManager.tunnel(at: tunnelIndex) : nil
|
||||||
|
}
|
||||||
|
guard !selectedTunnels.isEmpty else { return }
|
||||||
let alert = NSAlert()
|
let alert = NSAlert()
|
||||||
alert.messageText = tr(format: "macDeleteTunnelConfirmationAlertMessage (%@)", selectedTunnel.name)
|
if selectedTunnels.count == 1 {
|
||||||
|
alert.messageText = tr(format: "macDeleteTunnelConfirmationAlertMessage (%@)", selectedTunnels.first!.name)
|
||||||
|
} else {
|
||||||
|
alert.messageText = tr(format: "macDeleteMultipleTunnelsConfirmationAlertMessage (%d)", selectedTunnels.count)
|
||||||
|
}
|
||||||
alert.informativeText = tr("macDeleteTunnelConfirmationAlertInfo")
|
alert.informativeText = tr("macDeleteTunnelConfirmationAlertInfo")
|
||||||
alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleDelete"))
|
alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleDelete"))
|
||||||
alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleCancel"))
|
alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleCancel"))
|
||||||
alert.beginSheetModal(for: window) { [weak self] response in
|
alert.beginSheetModal(for: window) { [weak self] response in
|
||||||
guard response == .alertFirstButtonReturn else { return }
|
guard response == .alertFirstButtonReturn else { return }
|
||||||
self?.removeButton.isEnabled = false
|
self?.removeButton.isEnabled = false
|
||||||
self?.tunnelsManager.remove(tunnel: selectedTunnel) { [weak self] error in
|
self?.tunnelsManager.removeMultiple(tunnels: selectedTunnels) { [weak self] error in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
defer { self.removeButton.isEnabled = true }
|
defer { self.removeButton.isEnabled = true }
|
||||||
if let error = error {
|
if let error = error {
|
||||||
|
@ -309,9 +316,10 @@ extension TunnelsListTableViewController: NSTableViewDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableViewSelectionDidChange(_ notification: Notification) {
|
func tableViewSelectionDidChange(_ notification: Notification) {
|
||||||
guard tableView.selectedRow >= 0 else { return }
|
let selectedTunnelIndices = tableView.selectedRowIndexes.sorted()
|
||||||
let selectedTunnel = tunnelsManager.tunnel(at: tableView.selectedRow)
|
if !selectedTunnelIndices.isEmpty {
|
||||||
delegate?.tunnelSelected(tunnel: selectedTunnel)
|
delegate?.tunnelsSelected(tunnelIndices: tableView.selectedRowIndexes.sorted())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue