ClientListMgr // Allow dragging app bundles to the window.

This commit is contained in:
ShikiSuen 2023-02-24 19:16:59 +08:00
parent 92f5fcbfdb
commit 04f1889923
1 changed files with 55 additions and 0 deletions

View File

@ -32,6 +32,7 @@ class CtlClientListMgr: NSWindowController, NSTableViewDelegate, NSTableViewData
window?.setPosition(vertical: .center, horizontal: .right, padding: 20)
localize()
tblClients.delegate = self
tblClients.registerForDraggedTypes([.init(rawValue: kUTTypeFileURL as String)])
tblClients.allowsMultipleSelection = true
tblClients.dataSource = self
tblClients.action = #selector(onItemClicked(_:))
@ -225,6 +226,60 @@ extension CtlClientListMgr {
return Self.clientsList[row]
}
/// NSDraggingInfo URL App Bundle
/// - Parameters:
/// - info: NSDraggingInfo
/// - onError: 滿 lambda expression
/// - handler: 滿 lambda expression URL
private func validatePasteboardForAppBundles(
neta info: NSDraggingInfo, onError: @escaping () -> Void?, handler: (([URL]) -> Void)? = nil
) {
let board = info.draggingPasteboard
let type = NSPasteboard.PasteboardType(rawValue: kUTTypeApplicationBundle as String)
let options: [NSPasteboard.ReadingOptionKey: Any] = [
.urlReadingFileURLsOnly: true,
.urlReadingContentsConformToTypes: [type],
]
guard let urls = board.readObjects(forClasses: [NSURL.self], options: options) as? [URL], !urls.isEmpty else {
onError()
return
}
if let handler = handler {
handler(urls)
}
}
func tableView(
_: NSTableView, validateDrop info: NSDraggingInfo, proposedRow _: Int,
proposedDropOperation _: NSTableView.DropOperation
) -> NSDragOperation {
var result = NSDragOperation.copy
validatePasteboardForAppBundles(
neta: info, onError: { result = .init(rawValue: 0) } // NSDragOperationNone
)
return result
}
func tableView(
_: NSTableView, acceptDrop info: NSDraggingInfo,
row _: Int, dropOperation _: NSTableView.DropOperation
) -> Bool {
var result = true
validatePasteboardForAppBundles(
neta: info, onError: { result = false } // NSDragOperationNone
) { theURLs in
var dealt = false
theURLs.forEach { url in
guard let bundle = Bundle(url: url), let bundleID = bundle.bundleIdentifier else { return }
self.applyNewValue(bundleID, highMitigation: true)
dealt = true
}
result = dealt
}
defer { if result { tblClients.reloadData() } }
return result
}
private func localize() {
guard let window = window else { return }
window.title = NSLocalizedString("Client Manager", comment: "")