// // MainWindowController+ContextualMenus.swift // Evergreen // // Created by Brent Simmons on 1/28/18. // Copyright © 2018 Ranchero Software. All rights reserved. // import AppKit import Data import Account import RSCore extension MainWindowController { func menu(for objects: [Any]?) -> NSMenu? { guard let objects = objects, objects.count > 0 else { return nil } if objects.count == 1 { if let feed = objects.first as? Feed { return menuForFeed(feed) } if let folder = objects.first as? Folder { return menuForFolder(folder) } return nil } return menuForMultipleObjects(objects) } } // MARK: Contextual Menu Actions extension MainWindowController { @objc func openHomePageFromContextualMenu(_ sender: Any?) { guard let menuItem = sender as? NSMenuItem, let urlString = menuItem.representedObject as? String else { return } Browser.open(urlString, inBackground: false) } @objc func copyURLFromContextualMenu(_ sender: Any?) { guard let menuItem = sender as? NSMenuItem, let urlString = menuItem.representedObject as? String else { return } URLPasteboardWriter.write(urlString: urlString, to: NSPasteboard.general) } @objc func markObjectsReadFromContextualMenu(_ sender: Any?) { } @objc func deleteFromContextualMenu(_ sender: Any?) { } @objc func renameFromContextualMenu(_ sender: Any?) { guard let window = window, let menuItem = sender as? NSMenuItem, let object = menuItem.representedObject as? DisplayNameProvider, object is Feed || object is Folder else { return } renameWindowController = RenameWindowController(originalTitle: object.nameForDisplay) { (newTitle) in guard let newTitle = newTitle else { return } if let feed = object as? Feed { feed.editedName = newTitle } else if let folder = object as? Folder { folder.name = newTitle } self.renameWindowController = nil } renameWindowController?.runSheetOnWindow(window) } } // MARK: Build Contextual Menus private extension MainWindowController { func menuForFeed(_ feed: Feed) -> NSMenu? { let menu = NSMenu(title: "") if feed.unreadCount > 0 { menu.addItem(markAllReadMenuItem([feed])) menu.addItem(NSMenuItem.separator()) } if let homePageURL = feed.homePageURL, let _ = URL(string: homePageURL) { let item = menuItem(NSLocalizedString("Open Home Page", comment: "Command"), #selector(openHomePageFromContextualMenu(_:)), homePageURL) menu.addItem(item) menu.addItem(NSMenuItem.separator()) } let copyFeedURLItem = menuItem(NSLocalizedString("Copy Feed URL", comment: "Command"), #selector(copyURLFromContextualMenu(_:)), feed.url) menu.addItem(copyFeedURLItem) if let homePageURL = feed.homePageURL { let item = menuItem(NSLocalizedString("Copy Home Page URL", comment: "Command"), #selector(copyURLFromContextualMenu(_:)), homePageURL) menu.addItem(item) } menu.addItem(NSMenuItem.separator()) menu.addItem(renameMenuItem(feed)) menu.addItem(deleteMenuItem([feed])) return menu } func menuForFolder(_ folder: Folder) -> NSMenu? { let menu = NSMenu(title: "") if folder.unreadCount > 0 { menu.addItem(markAllReadMenuItem([folder])) menu.addItem(NSMenuItem.separator()) } menu.addItem(renameMenuItem(folder)) menu.addItem(deleteMenuItem([folder])) return menu.numberOfItems > 0 ? menu : nil } func menuForMultipleObjects(_ objects: [Any]) -> NSMenu? { guard allObjectsAreFeedsAndOrFolders(objects) else { return nil } let menu = NSMenu(title: "") if anyObjectInArrayHasNonZeroUnreadCount(objects) { menu.addItem(markAllReadMenuItem(objects)) menu.addItem(NSMenuItem.separator()) } menu.addItem(deleteMenuItem(objects)) return menu.numberOfItems > 0 ? menu : nil } func markAllReadMenuItem(_ objects: [Any]) -> NSMenuItem { return menuItem(NSLocalizedString("Mark All as Read", comment: "Command"), #selector(markObjectsReadFromContextualMenu(_:)), objects) } func deleteMenuItem(_ objects: [Any]) -> NSMenuItem { return menuItem(NSLocalizedString("Delete", comment: "Command"), #selector(deleteFromContextualMenu(_:)), objects) } func renameMenuItem(_ object: Any) -> NSMenuItem { return menuItem(NSLocalizedString("Rename", comment: "Command"), #selector(renameFromContextualMenu(_:)), object) } func anyObjectInArrayHasNonZeroUnreadCount(_ objects: [Any]) -> Bool { for object in objects { if let unreadCountProvider = object as? UnreadCountProvider { if unreadCountProvider.unreadCount > 0 { return true } } } return false } func allObjectsAreFeedsAndOrFolders(_ objects: [Any]) -> Bool { for object in objects { if !objectIsFeedOrFolder(object) { return false } } return true } func objectIsFeedOrFolder(_ object: Any) -> Bool { return object is Feed || object is Folder } func menuItem(_ title: String, _ action: Selector, _ representedObject: Any) -> NSMenuItem { let item = NSMenuItem(title: title, action: action, keyEquivalent: "") item.representedObject = representedObject item.target = self return item } }