cocoa-cb: add support for dragging certain strings onto the window

only the dragged types NSFilenamesPboardType and NSURLPboardType were
supported to be dropped on the window, which was inconsistent with the
dragged types the dock icon supports. the dock icon additional supports
strings that represents an URL or a path. the system takes care of
validating the strings properly in the case of the dock icon, but in the
case of dropping on the window it needs to be done manually.

support for strings is added by also allowing the NSPasteboardTypeString
type and manually validating the strings. strings are split by new lines
and trimmed, to also support a list of URLs and paths. every new element
is checked if being an URL or path and only then being added to the
playlist.
This commit is contained in:
Akemi 2018-06-03 00:30:57 +02:00 committed by Jan Ekström
parent 3f6be83350
commit 716b871928
1 changed files with 31 additions and 2 deletions

View File

@ -36,7 +36,9 @@ class EventsView: NSView {
super.init(frame: NSMakeRect(0, 0, 960, 480))
autoresizingMask = [.viewWidthSizable, .viewHeightSizable]
wantsBestResolutionOpenGLSurface = true
register(forDraggedTypes: [NSFilenamesPboardType, NSURLPboardType])
register(forDraggedTypes: [ NSFilenamesPboardType,
NSURLPboardType,
NSPasteboardTypeString ])
}
required init?(coder: NSCoder) {
@ -60,12 +62,24 @@ class EventsView: NSView {
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
guard let types = sender.draggingPasteboard().types else { return [] }
if types.contains(NSFilenamesPboardType) || types.contains(NSURLPboardType) {
if types.contains(NSFilenamesPboardType) ||
types.contains(NSURLPboardType) ||
types.contains(NSPasteboardTypeString)
{
return .copy
}
return []
}
func isURL(_ str: String) -> Bool {
let regex = try! NSRegularExpression(pattern: "^(https?|ftp)://[^\\s/$.?#].[^\\s]*$",
options: .caseInsensitive)
let isURL = regex.numberOfMatches(in: str,
options: [],
range: NSRange(location: 0, length: str.count))
return isURL > 0
}
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
let pb = sender.draggingPasteboard()
guard let types = sender.draggingPasteboard().types else { return false }
@ -80,6 +94,21 @@ class EventsView: NSView {
EventsResponder.sharedInstance().handleFilesArray(url)
return true
}
} else if types.contains(NSPasteboardTypeString) {
guard let str = pb.string(forType: NSPasteboardTypeString) else { return false }
var filesArray: [String] = []
for val in str.components(separatedBy: "\n") {
let url = val.trimmingCharacters(in: .whitespacesAndNewlines)
let path = (url as NSString).expandingTildeInPath
if isURL(url) {
filesArray.append(url)
} else if path.starts(with: "/") {
filesArray.append(path)
}
}
EventsResponder.sharedInstance().handleFilesArray(filesArray)
return true
}
return false
}