123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- //
- // Copyright © 2020 osy. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- import SwiftUI
- @available(macOS 12, *)
- struct VMConfigNetworkPortForwardView: View {
- @Binding var config: UTMQemuConfigurationNetwork
- @State private var isEditingNewPort = false
- @State private var isEditingExistingPort = false
- @State private var selectedId: UUID?
- @State private var editPortForward: UTMQemuConfigurationPortForward?
-
- var body: some View {
- VStack {
- Table(config.portForward, selection: $selectedId) {
- TableColumn("Protocol") { row in
- Text(row.protocol.prettyValue)
- }
- TableColumn("Guest Address") { row in
- Text(row.guestAddress ?? "")
- }
- TableColumn("Guest Port") { row in
- Text(String(row.guestPort))
- }
- TableColumn("Host Address") { row in
- Text(row.hostAddress ?? "")
- }
- TableColumn("Host Port") { row in
- Text(String(row.hostPort))
- }
- }.onDoubleClick {
- editPortForward = config.portForward.first(where: { $0.id == selectedId })
- }
- HStack {
- Spacer()
- if let selectedId = selectedId {
- Button("Delete") {
- config.portForward.removeAll(where: { $0.id == selectedId })
- self.selectedId = nil
- }
- Button("Edit…") {
- editPortForward = config.portForward.first(where: { $0.id == selectedId })
- }.popover(item: $editPortForward, arrowEdge: .top) { item in
- PortForwardEdit(config: $config, forward: item).padding()
- .frame(width: 250)
- }
- }
- Button("New…") {
- isEditingNewPort.toggle()
- }.popover(isPresented: $isEditingNewPort, arrowEdge: .top) {
- PortForwardEdit(config: $config, forward: .init()).padding()
- .frame(width: 250)
- }
- }.padding()
- }
- }
- }
- @available(macOS 11, *)
- struct VMConfigNetworkPortForwardLegacyView: View {
- @Binding var config: UTMQemuConfigurationNetwork
- @State private var editingNewPort = false
- @State private var selectedPortForward: UTMQemuConfigurationPortForward?
-
- var body: some View {
- Section(header: HStack {
- Text("Port Forward")
- Spacer()
- Button(action: { editingNewPort = true }, label: {
- Text("New…")
- }).popover(isPresented: $editingNewPort, arrowEdge: .bottom) {
- PortForwardEdit(config: $config, forward: .init()).padding()
- .frame(width: 250)
- }
- }) {
- VStack {
- ForEach(config.portForward) { forward in
- let isPopoverShown = Binding<Bool> {
- selectedPortForward == forward
- } set: { value in
- if value {
- selectedPortForward = forward
- } else {
- selectedPortForward = nil
- }
- }
- Button(action: { isPopoverShown.wrappedValue = true }, label: {
- let guest = "\(forward.guestAddress ?? ""):\(forward.guestPort)"
- let host = "\(forward.hostAddress ?? ""):\(forward.hostPort)"
- Text("\(guest) ➡️ \(host)")
- }).buttonStyle(.bordered)
- .popover(isPresented: isPopoverShown, arrowEdge: .bottom) {
- PortForwardEdit(config: $config, forward: forward).padding()
- .frame(width: 250)
- }
- }
- }
- }
- }
- }
- @available(macOS 11, *)
- struct PortForwardEdit: View {
- @Binding var config: UTMQemuConfigurationNetwork
- @State var forward: UTMQemuConfigurationPortForward
- @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
-
- var body: some View {
- VStack {
- VMConfigPortForwardForm(forward: $forward).multilineTextAlignment(.trailing)
- HStack {
- Spacer()
- let index = config.portForward.firstIndex(where: { $0.id == forward.id })
- if let index = index {
- Button(action: {
- config.portForward.remove(at: index)
- closePopup()
- }, label: {
- Text("Delete")
- })
- }
- Button(action: {
- if let index = index {
- config.portForward[index] = forward
- } else {
- config.portForward.append(forward)
- }
- closePopup()
- }, label: {
- Text("Save")
- }).disabled(forward.guestPort == 0 || forward.hostPort == 0)
- }
- }
- }
-
- private func closePopup() {
- self.presentationMode.wrappedValue.dismiss()
- }
- }
- @available(macOS 11, *)
- struct VMConfigNetworkPortForwardView_Previews: PreviewProvider {
- @State static private var config = UTMQemuConfigurationNetwork()
-
- static var previews: some View {
- Group {
- Form {
- if #available(macOS 12, *) {
- VMConfigNetworkPortForwardView(config: $config)
- } else {
- VMConfigNetworkPortForwardLegacyView(config: $config)
- }
- }.onAppear {
- if config.portForward.count == 0 {
- var newConfigPort = UTMQemuConfigurationPortForward()
- newConfigPort.protocol = .tcp
- newConfigPort.guestAddress = "1.2.3.4"
- newConfigPort.guestPort = 1234
- newConfigPort.hostAddress = "4.3.2.1"
- newConfigPort.hostPort = 4321
- config.portForward.append(newConfigPort)
- newConfigPort.protocol = .udp
- newConfigPort.guestAddress = ""
- newConfigPort.guestPort = 2222
- newConfigPort.hostAddress = ""
- newConfigPort.hostPort = 3333
- config.portForward.append(newConfigPort)
- }
- }
- }
- }
- }
|