Write dragged feeds with various UTI types, including a custom feed type.
This commit is contained in:
parent
06de21776a
commit
51825f8f05
@ -13,6 +13,7 @@
|
|||||||
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */; };
|
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */; };
|
||||||
842E45E71ED8C747000A8B52 /* DB5.plist in Resources */ = {isa = PBXBuildFile; fileRef = 842E45E61ED8C747000A8B52 /* DB5.plist */; };
|
842E45E71ED8C747000A8B52 /* DB5.plist in Resources */ = {isa = PBXBuildFile; fileRef = 842E45E61ED8C747000A8B52 /* DB5.plist */; };
|
||||||
84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */; };
|
84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */; };
|
||||||
|
845F52ED1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */; };
|
||||||
846A7BEC1F872C5600FEFD30 /* BatchUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846A7BEB1F872C5600FEFD30 /* BatchUpdate.swift */; };
|
846A7BEC1F872C5600FEFD30 /* BatchUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846A7BEB1F872C5600FEFD30 /* BatchUpdate.swift */; };
|
||||||
846E773D1F6EF67A00A165E2 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; };
|
846E773D1F6EF67A00A165E2 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; };
|
||||||
846E773E1F6EF67A00A165E2 /* Account.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
846E773E1F6EF67A00A165E2 /* Account.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
@ -391,6 +392,7 @@
|
|||||||
842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowSplitView.swift; sourceTree = "<group>"; };
|
842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowSplitView.swift; sourceTree = "<group>"; };
|
||||||
842E45E61ED8C747000A8B52 /* DB5.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = DB5.plist; path = Evergreen/Resources/DB5.plist; sourceTree = "<group>"; };
|
842E45E61ED8C747000A8B52 /* DB5.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = DB5.plist; path = Evergreen/Resources/DB5.plist; sourceTree = "<group>"; };
|
||||||
84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListControlsView.swift; sourceTree = "<group>"; };
|
84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListControlsView.swift; sourceTree = "<group>"; };
|
||||||
|
845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedPasteboardWriter.swift; sourceTree = "<group>"; };
|
||||||
846A7BEB1F872C5600FEFD30 /* BatchUpdate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BatchUpdate.swift; path = Evergreen/BatchUpdate.swift; sourceTree = "<group>"; };
|
846A7BEB1F872C5600FEFD30 /* BatchUpdate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BatchUpdate.swift; path = Evergreen/BatchUpdate.swift; sourceTree = "<group>"; };
|
||||||
846E77161F6EF5D000A165E2 /* Database.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Database.xcodeproj; path = Frameworks/Database/Database.xcodeproj; sourceTree = "<group>"; };
|
846E77161F6EF5D000A165E2 /* Database.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Database.xcodeproj; path = Frameworks/Database/Database.xcodeproj; sourceTree = "<group>"; };
|
||||||
846E77301F6EF5D600A165E2 /* Account.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Account.xcodeproj; path = Frameworks/Account/Account.xcodeproj; sourceTree = "<group>"; };
|
846E77301F6EF5D600A165E2 /* Account.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Account.xcodeproj; path = Frameworks/Account/Account.xcodeproj; sourceTree = "<group>"; };
|
||||||
@ -590,6 +592,7 @@
|
|||||||
849A979E1ED9F130007D329B /* SidebarCell.swift */,
|
849A979E1ED9F130007D329B /* SidebarCell.swift */,
|
||||||
849A97611ED9EB96007D329B /* SidebarTreeControllerDelegate.swift */,
|
849A97611ED9EB96007D329B /* SidebarTreeControllerDelegate.swift */,
|
||||||
849A97631ED9EB96007D329B /* UnreadCountView.swift */,
|
849A97631ED9EB96007D329B /* UnreadCountView.swift */,
|
||||||
|
845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */,
|
||||||
);
|
);
|
||||||
path = Sidebar;
|
path = Sidebar;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1214,6 +1217,7 @@
|
|||||||
84DAEE321F870B390058304B /* DockBadge.swift in Sources */,
|
84DAEE321F870B390058304B /* DockBadge.swift in Sources */,
|
||||||
842E45DD1ED8C54B000A8B52 /* Browser.swift in Sources */,
|
842E45DD1ED8C54B000A8B52 /* Browser.swift in Sources */,
|
||||||
842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */,
|
842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */,
|
||||||
|
845F52ED1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift in Sources */,
|
||||||
849A975E1ED9EB72007D329B /* MainWindowController.swift in Sources */,
|
849A975E1ED9EB72007D329B /* MainWindowController.swift in Sources */,
|
||||||
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */,
|
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */,
|
||||||
849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */,
|
849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */,
|
||||||
|
100
Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift
Normal file
100
Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
//
|
||||||
|
// FeedPasteboardWriter.swift
|
||||||
|
// Evergreen
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 11/7/17.
|
||||||
|
// Copyright © 2017 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
import Data
|
||||||
|
|
||||||
|
@objc final class FeedPasteboardWriter: NSObject, NSPasteboardWriting {
|
||||||
|
|
||||||
|
private let feed: Feed
|
||||||
|
static let feedUTI = "com.ranchero.feed"
|
||||||
|
static let feedUTIType = NSPasteboard.PasteboardType(rawValue: feedUTI)
|
||||||
|
static let feedUTIInternal = "com.ranchero.evergreen.internal.feed";
|
||||||
|
static let feedUTIInternalType = NSPasteboard.PasteboardType(rawValue: feedUTIInternal)
|
||||||
|
|
||||||
|
init(feed: Feed) {
|
||||||
|
|
||||||
|
self.feed = feed
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - NSPasteboardWriting
|
||||||
|
|
||||||
|
func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
|
||||||
|
|
||||||
|
return [.string, .URL, FeedPasteboardWriter.feedUTIType, FeedPasteboardWriter.feedUTIInternalType]
|
||||||
|
}
|
||||||
|
|
||||||
|
func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
|
||||||
|
|
||||||
|
let plist: Any?
|
||||||
|
|
||||||
|
switch type {
|
||||||
|
case .string:
|
||||||
|
plist = feed.nameForDisplay
|
||||||
|
case .URL:
|
||||||
|
plist = feed.url
|
||||||
|
case FeedPasteboardWriter.feedUTIType:
|
||||||
|
plist = exportDictionary()
|
||||||
|
case FeedPasteboardWriter.feedUTIInternalType:
|
||||||
|
plist = internalDictionary()
|
||||||
|
default:
|
||||||
|
plist = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return plist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension FeedPasteboardWriter {
|
||||||
|
|
||||||
|
private struct Key {
|
||||||
|
|
||||||
|
static let url = "URL"
|
||||||
|
static let homePageURL = "homePageURL"
|
||||||
|
static let name = "name"
|
||||||
|
|
||||||
|
// Internal
|
||||||
|
static let accountID = "accountID"
|
||||||
|
static let feedID = "feedID"
|
||||||
|
static let editedName = "editedName"
|
||||||
|
static let unreadCount = "unreadCount"
|
||||||
|
}
|
||||||
|
|
||||||
|
func exportDictionary() -> [String: String] {
|
||||||
|
|
||||||
|
var d = [String: String]()
|
||||||
|
|
||||||
|
d[Key.url] = feed.url
|
||||||
|
d[Key.homePageURL] = feed.homePageURL ?? ""
|
||||||
|
d[Key.name] = feed.nameForDisplay
|
||||||
|
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
func internalDictionary() -> [String: Any] {
|
||||||
|
|
||||||
|
var d = [String: Any]()
|
||||||
|
|
||||||
|
d[Key.url] = feed.url
|
||||||
|
if let homePageURL = feed.homePageURL {
|
||||||
|
d[Key.homePageURL] = homePageURL
|
||||||
|
}
|
||||||
|
if let name = feed.name {
|
||||||
|
d[Key.name] = name
|
||||||
|
}
|
||||||
|
if let editedName = feed.editedName {
|
||||||
|
d[Key.editedName] = editedName
|
||||||
|
}
|
||||||
|
if feed.unreadCount > 0 {
|
||||||
|
d[Key.unreadCount] = feed.unreadCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,8 @@ import RSCore
|
|||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
|
||||||
outlineView.sidebarViewController = self
|
outlineView.sidebarViewController = self
|
||||||
|
outlineView.setDraggingSourceOperationMask(.move, forLocal: true)
|
||||||
|
outlineView.setDraggingSourceOperationMask(.copy, forLocal: false)
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(containerChildrenDidChange(_:)), name: .ChildrenDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(containerChildrenDidChange(_:)), name: .ChildrenDidChange, object: nil)
|
||||||
@ -140,7 +142,7 @@ import RSCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: NSOutlineViewDataSource
|
// MARK: NSOutlineViewDataSource
|
||||||
|
|
||||||
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
||||||
|
|
||||||
@ -156,6 +158,15 @@ import RSCore
|
|||||||
|
|
||||||
return nodeForItem(item as AnyObject?).canHaveChildNodes
|
return nodeForItem(item as AnyObject?).canHaveChildNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
|
||||||
|
|
||||||
|
let node = nodeForItem(item as AnyObject?)
|
||||||
|
if let feed = node.representedObject as? Feed {
|
||||||
|
return FeedPasteboardWriter(feed: feed)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - Private
|
//MARK: - Private
|
||||||
|
@ -69,7 +69,6 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
|
|||||||
tableView.target = self
|
tableView.target = self
|
||||||
tableView.doubleAction = #selector(openArticleInBrowser(_:))
|
tableView.doubleAction = #selector(openArticleInBrowser(_:))
|
||||||
tableView.keyboardDelegate = self
|
tableView.keyboardDelegate = self
|
||||||
tableView.setDraggingSourceOperationMask(.copy, forLocal: true)
|
|
||||||
tableView.setDraggingSourceOperationMask(.copy, forLocal: false)
|
tableView.setDraggingSourceOperationMask(.copy, forLocal: false)
|
||||||
|
|
||||||
if !didRegisterForNotifications {
|
if !didRegisterForNotifications {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user