NSCollectionView Drag & Drop с помощью файла Promise - PullRequest
0 голосов
/ 01 сентября 2018

Я хочу перетащить одно или несколько изображений из NSCollectionView в моем приложении MacOS в место назначения на компьютере или в приложение для фотографий.

Я использую NSFilePromiseProvider, поскольку изображения находятся на моем устройстве Android, и в моем приложении отображаются только миниатюры. Я хочу вытащить изображения на свой компьютер после завершения перетаскивания.

NSCollectionViewDelegate

extension ImageViewController: NSCollectionViewDelegate {
    func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {
        return true
    }

    func collectionView(_ collectionView: NSCollectionView, pasteboardWriterForItemAt indexPath: IndexPath) -> NSPasteboardWriting? {
        // Return a File Promise Provider as Pasteboard Writing.
        let provider = NSFilePromiseProvider(fileType: kUTTypeJPEG as String, delegate: self)
        provider.userInfo = meta[indexPath.item] // Some data to identify the dragged image
        return provider
    }

    func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndexPath proposedDropIndexPath: AutoreleasingUnsafeMutablePointer<NSIndexPath>,
        dropOperation proposedDropOrperation: UnsafeMutablePointer<NSCollectionView.DropOperation>) -> NSDragOperation {
        return [.copy] // Not called if the drag destination is outside of my app
    }
}

NSFilePromiseProviderDelegate

extension ImageViewController: NSFilePromiseProviderDelegate {
    func filePromiseProvider(_ filePromiseProvider: NSFilePromiseProvider, fileNameForType fileType: String) -> String {
        // Return the promised filename.
        let metadata = filePromiseProvider.userInfo as! Metadata
        return metadata.fileName
    }

    func operationQueue(for filePromiseProvider: NSFilePromiseProvider) -> OperationQueue {
        return workQueue
    }

    func filePromiseProvider(_ filePromiseProvider: NSFilePromiseProvider, writePromiseTo url: URL, completionHandler: @escaping (Error?) -> Void) {
        // Pull image over adb.
        let metadata = filePromiseProvider.userInfo as! Metadata
        ADB.executeAsync(args: "pull", metadata.path, url.path, callback: { (output) in
            completionHandler(nil)
        })
    }
}

Пока это работает, но мне нужно внести некоторые улучшения:

Как можно установить NSDragOperation на .copy, чтобы при перетаскивании отображать красный круг со знаком плюс? Функция проверки перетаскивания NSCollectionViewDelegate вызывается только при перетаскивании внутри моего приложения. Когда вместо обещания я предоставляю файл NSURL как NSPasteboardWriting, автоматически появляется значок плюса. Но поскольку файл не на моем компьютере, я должен вместо этого использовать обещание.

Также я хочу иметь возможность перетаскивать изображения непосредственно в приложение для фотографий или на значок док-станции, чтобы изображение автоматически импортировалось. Опять же, использование NSURL в качестве NSPasteboardWriting работает, но это невозможно для меня. Может ли приложение для фотографий обрабатывать файл с обещанием?

...