Skip to content

Commit

Permalink
Merge pull request #6304 from hamtiko/feature/removeableDrives-drop
Browse files Browse the repository at this point in the history
Adding drag and drop feature for VMRemovableDrivesView
  • Loading branch information
osy committed Apr 30, 2024
2 parents 0008112 + 00a1bb5 commit e4e8444
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 7 deletions.
38 changes: 34 additions & 4 deletions Platform/Shared/VMRemovableDrivesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//

import SwiftUI
import UniformTypeIdentifiers

struct VMRemovableDrivesView: View {
@ObservedObject var vm: VMData
Expand All @@ -25,7 +26,10 @@ struct VMRemovableDrivesView: View {
/// Explanation see "SwiftUI FileImporter modal bug" in the `body`
@State private var workaroundFileImporterBug: Bool = false
@State private var currentDrive: UTMQemuConfigurationDrive?


private static let shareDirectoryUTType = UTType.folder
private static let diskImageUTType = UTType.data

private var qemuVM: (any UTMSpiceVirtualMachine)! {
vm.wrapped as? any UTMSpiceVirtualMachine
}
Expand Down Expand Up @@ -73,8 +77,21 @@ struct VMRemovableDrivesView: View {
} else {
Button("Browse…", action: { shareDirectoryFileImportPresented.toggle() })
}
}.fileImporter(isPresented: $shareDirectoryFileImportPresented, allowedContentTypes: [.folder], onCompletion: selectShareDirectory)
.disabled(mode == .virtfs && vm.state != .stopped)
}.fileImporter(isPresented: $shareDirectoryFileImportPresented, allowedContentTypes: [Self.shareDirectoryUTType], onCompletion: selectShareDirectory)
.disabled(mode == .virtfs && vm.state != .stopped)
.onDrop(of: [Self.shareDirectoryUTType], isTargeted: nil) { providers in
guard let item = providers.first, item.hasItemConformingToTypeIdentifier(Self.shareDirectoryUTType.identifier) else { return false }

item.loadItem(forTypeIdentifier: Self.shareDirectoryUTType.identifier) { url, error in
if let url = url as? URL {
selectShareDirectory(result: .success(url))
}
if let error = error {
selectShareDirectory(result: .failure(error))
}
}
return true
}
}
ForEach(config.drives.filter { $0.isExternal }) { drive in
HStack {
Expand Down Expand Up @@ -128,12 +145,25 @@ struct VMRemovableDrivesView: View {
.lineLimit(1)
.truncationMode(.tail)
.foregroundColor(.secondary)
}.fileImporter(isPresented: $diskImageFileImportPresented, allowedContentTypes: [.data]) { result in
}.fileImporter(isPresented: $diskImageFileImportPresented, allowedContentTypes: [Self.diskImageUTType]) { result in
if let currentDrive = self.currentDrive {
selectRemovableImage(forDrive: currentDrive, result: result)
self.currentDrive = nil
}
}
.onDrop(of: [Self.diskImageUTType], isTargeted: nil) { providers in
guard let item = providers.first, item.hasItemConformingToTypeIdentifier(Self.diskImageUTType.identifier) else { return false }

item.loadItem(forTypeIdentifier: Self.diskImageUTType.identifier) { url, error in
if let url = url as? URL{
selectRemovableImage(forDrive: drive, result: .success(url))
}
if let error {
selectRemovableImage(forDrive: drive, result: .failure(error))
}
}
return true
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions Services/UTMQemuVirtualMachine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -792,10 +792,10 @@ extension UTMQemuVirtualMachine {
try await eject(drive, isForced: true)
let file = try UTMRegistryEntry.File(url: url, isReadOnly: drive.isReadOnly)
await registryEntry.setExternalDrive(file, forId: drive.id)
try await changeMedium(drive, with: tempBookmark, url: url, isSecurityScoped: false, isAccessOnly: isAccessOnly)
try await changeMedium(drive, with: tempBookmark, isSecurityScoped: false, isAccessOnly: isAccessOnly)
}

private func changeMedium(_ drive: UTMQemuConfigurationDrive, with bookmark: Data, url: URL?, isSecurityScoped: Bool, isAccessOnly: Bool) async throws {
private func changeMedium(_ drive: UTMQemuConfigurationDrive, with bookmark: Data, isSecurityScoped: Bool, isAccessOnly: Bool) async throws {
let system = await system ?? UTMProcess()
let (success, bookmark, path) = await system.accessData(withBookmark: bookmark, securityScoped: isSecurityScoped)
guard let bookmark = bookmark, let path = path, success else {
Expand All @@ -818,7 +818,7 @@ extension UTMQemuVirtualMachine {
let id = drive.id
if let bookmark = await registryEntry.externalDrives[id]?.remoteBookmark {
// an image bookmark was saved while QEMU was running
try await changeMedium(drive, with: bookmark, url: nil, isSecurityScoped: true, isAccessOnly: !isMounting)
try await changeMedium(drive, with: bookmark, isSecurityScoped: true, isAccessOnly: !isMounting)
} else if let localBookmark = await registryEntry.externalDrives[id]?.bookmark {
// an image bookmark was saved while QEMU was NOT running
let url = try URL(resolvingPersistentBookmarkData: localBookmark)
Expand Down

0 comments on commit e4e8444

Please sign in to comment.