From a2a94bb839719e4d3d40f48f970eaee2e42e2b19 Mon Sep 17 00:00:00 2001 From: 1024jp <1024jp@wolfrosch.com> Date: Mon, 6 May 2024 22:47:49 +0900 Subject: [PATCH] Move file drop snippet operation to EditorTextViewController --- CotEditor/Sources/EditorTextView.swift | 55 +++---------------- .../Sources/EditorTextViewController.swift | 47 ++++++++++++++++ 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/CotEditor/Sources/EditorTextView.swift b/CotEditor/Sources/EditorTextView.swift index ef16e2af0..ddce5f379 100644 --- a/CotEditor/Sources/EditorTextView.swift +++ b/CotEditor/Sources/EditorTextView.swift @@ -37,6 +37,12 @@ private extension NSAttributedString.Key { final class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, MultiCursorEditing { + @MainActor protocol Delegate: AnyObject { + + func editorTextView(_ textView: EditorTextView, readDroppedURLs URLs: [URL]) -> Bool + } + + // MARK: Notification Names static let didBecomeFirstResponderNotification = Notification.Name("TextViewDidBecomeFirstResponder") @@ -1013,7 +1019,7 @@ final class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, Multi // on file drop if pboard.name == .drag, let urls = pboard.readObjects(forClasses: [NSURL.self]) as? [URL], - self.insertDroppedFiles(urls) + (self.delegate as? any Delegate)?.editorTextView(self, readDroppedURLs: urls) == true { return true } @@ -1295,13 +1301,6 @@ final class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, Multi // MARK: Private Methods - /// The file URL of the document representing the text view contents. - private var documentURL: URL? { - - (self.window?.windowController?.document as? Document)?.fileURL - } - - /// Updates coloring settings with the current theme. private func applyTheme() { @@ -1434,46 +1433,6 @@ final class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, Multi } - /// Inserts string representation of dropped files applying the user's file drop settings. - /// - /// - Parameter urls: The file URLs of dropped files. - /// - Returns: Whether the file drop was performed. - private func insertDroppedFiles(_ urls: [URL]) -> Bool { - - guard !urls.isEmpty else { return false } - - let fileDropItems = UserDefaults.standard[.fileDropArray].map(FileDropItem.init(dictionary:)) - - let replacementString = urls.reduce(into: "") { (string, url) in - if url.pathExtension == "textClipping", let textClipping = try? TextClipping(contentsOf: url) { - string += textClipping.string - return - } - - if let fileDropItem = fileDropItems.first(where: { $0.supports(extension: url.pathExtension, scope: self.syntaxName) }) { - string += fileDropItem.dropText(forFileURL: url, documentURL: self.documentURL) - return - } - - // just insert the absolute path if no specific setting for the file type was found - // -> This is the default behavior of NSTextView by file dropping. - if !string.isEmpty { - string += self.lineEnding.string - } - - string += url.isFileURL ? url.path : url.absoluteString - } - - // insert drop text to view - guard self.shouldChangeText(in: self.rangeForUserTextChange, replacementString: replacementString) else { return false } - - self.replaceCharacters(in: self.rangeForUserTextChange, with: replacementString) - self.didChangeText() - - return true - } - - /// Highlights the brace matching to the brace next to the cursor. private func highlightMatchingBrace() { diff --git a/CotEditor/Sources/EditorTextViewController.swift b/CotEditor/Sources/EditorTextViewController.swift index f5006c30b..5f1d0637d 100644 --- a/CotEditor/Sources/EditorTextViewController.swift +++ b/CotEditor/Sources/EditorTextViewController.swift @@ -449,6 +449,53 @@ extension EditorTextViewController: NSUserInterfaceValidations { } +extension EditorTextViewController: EditorTextView.Delegate { + + /// Inserts string representation of dropped files applying the user's file drop snippets. + /// + /// - Parameter urls: The file URLs of dropped files. + /// - Returns: Whether the file drop was performed. + func editorTextView(_ textView: EditorTextView, readDroppedURLs urls: [URL]) -> Bool { + + guard !urls.isEmpty else { return false } + + let fileDropItems = UserDefaults.standard[.fileDropArray].map(FileDropItem.init(dictionary:)) + + guard !fileDropItems.isEmpty else { return false } + + let replacementString = urls.reduce(into: "") { (string, url) in + if url.pathExtension == "textClipping", let textClipping = try? TextClipping(contentsOf: url) { + string += textClipping.string + return + } + + if let fileDropItem = fileDropItems.first(where: { $0.supports(extension: url.pathExtension, scope: textView.syntaxName) }) { + string += fileDropItem.dropText(forFileURL: url, documentURL: self.document.fileURL) + return + } + + // just insert the absolute path if no specific setting for the file type was found + // -> This is the default behavior of NSTextView by file dropping. + if !string.isEmpty { + string += textView.lineEnding.string + } + + string += url.isFileURL ? url.path : url.absoluteString + } + + guard replacementString.isEmpty else { return true } + + // insert snippets to view + guard textView.shouldChangeText(in: textView.rangeForUserTextChange, replacementString: replacementString) else { return false } + + textView.replaceCharacters(in: textView.rangeForUserTextChange, with: replacementString) + textView.didChangeText() + + return true + } +} + + extension EditorTextViewController: NSFontChanging {