aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WireGuard/WireGuard/Base.lproj/Localizable.strings3
-rw-r--r--WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift25
-rw-r--r--WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift26
3 files changed, 41 insertions, 13 deletions
diff --git a/WireGuard/WireGuard/Base.lproj/Localizable.strings b/WireGuard/WireGuard/Base.lproj/Localizable.strings
index 00f4d583..7652b347 100644
--- a/WireGuard/WireGuard/Base.lproj/Localizable.strings
+++ b/WireGuard/WireGuard/Base.lproj/Localizable.strings
@@ -271,6 +271,7 @@
"macWindowTitleManageTunnels" = "Manage WireGuard Tunnels";
"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.";
"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Delete";
"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Cancel";
@@ -284,6 +285,8 @@
"macNameFieldExportZip" = "Export tunnels to";
"macSheetButtonExportZip" = "Save";
+"macButtonDeleteTunnels (%d)" = "Delete %d tunnels";
+
// Mac detail/edit view fields
"macFieldKey (%@)" = "%@:";
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift
index 58065475..18b8fcb7 100644
--- a/WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift
+++ b/WireGuard/WireGuard/UI/macOS/ViewController/ManageTunnelsRootViewController.swift
@@ -77,10 +77,27 @@ class ManageTunnelsRootViewController: NSViewController {
}
extension ManageTunnelsRootViewController: TunnelsListTableViewControllerDelegate {
- func tunnelSelected(tunnel: TunnelContainer) {
- let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager, tunnel: tunnel)
- setTunnelDetailContentVC(tunnelDetailVC)
- self.tunnelDetailVC = tunnelDetailVC
+ func tunnelsSelected(tunnelIndices: [Int]) {
+ assert(!tunnelIndices.isEmpty)
+ if tunnelIndices.count == 1 {
+ 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() {
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift
index 3a298400..7f2dbc8b 100644
--- a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift
+++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift
@@ -4,7 +4,7 @@
import Cocoa
protocol TunnelsListTableViewControllerDelegate: class {
- func tunnelSelected(tunnel: TunnelContainer)
+ func tunnelsSelected(tunnelIndices: [Int])
func tunnelsListEmpty()
}
@@ -18,6 +18,7 @@ class TunnelsListTableViewController: NSViewController {
tableView.addTableColumn(NSTableColumn(identifier: NSUserInterfaceItemIdentifier("TunnelsList")))
tableView.headerView = nil
tableView.rowSizeStyle = .medium
+ tableView.allowsMultipleSelection = true
return tableView
}()
@@ -158,18 +159,24 @@ class TunnelsListTableViewController: NSViewController {
@objc func handleRemoveTunnelAction() {
guard let window = view.window else { return }
- let selectedTunnelIndex = tableView.selectedRow
- guard selectedTunnelIndex >= 0 && selectedTunnelIndex < tunnelsManager.numberOfTunnels() else { return }
- let selectedTunnel = tunnelsManager.tunnel(at: selectedTunnelIndex)
+ let selectedTunnelIndices = tableView.selectedRowIndexes.sorted()
+ let selectedTunnels = selectedTunnelIndices.compactMap { tunnelIndex in
+ tunnelIndex >= 0 && tunnelIndex < tunnelsManager.numberOfTunnels() ? tunnelsManager.tunnel(at: tunnelIndex) : nil
+ }
+ guard !selectedTunnels.isEmpty else { return }
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.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleDelete"))
alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleCancel"))
alert.beginSheetModal(for: window) { [weak self] response in
guard response == .alertFirstButtonReturn else { return }
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 }
defer { self.removeButton.isEnabled = true }
if let error = error {
@@ -309,9 +316,10 @@ extension TunnelsListTableViewController: NSTableViewDelegate {
}
func tableViewSelectionDidChange(_ notification: Notification) {
- guard tableView.selectedRow >= 0 else { return }
- let selectedTunnel = tunnelsManager.tunnel(at: tableView.selectedRow)
- delegate?.tunnelSelected(tunnel: selectedTunnel)
+ let selectedTunnelIndices = tableView.selectedRowIndexes.sorted()
+ if !selectedTunnelIndices.isEmpty {
+ delegate?.tunnelsSelected(tunnelIndices: tableView.selectedRowIndexes.sorted())
+ }
}
}