From 29fe1869aac47df595fa0469067ec038e9b9da8c Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 28 Jan 2018 13:28:33 -0800 Subject: [PATCH] Build contextual menus in MainWindowController extension. --- Evergreen.xcodeproj/project.pbxproj | 8 +- .../ContextualMenuCreator.swift | 11 -- ...MainWindowController+ContextualMenus.swift | 154 ++++++++++++++++++ 3 files changed, 158 insertions(+), 15 deletions(-) delete mode 100644 Evergreen/ContextualMenus/ContextualMenuCreator.swift create mode 100644 Evergreen/ContextualMenus/MainWindowController+ContextualMenus.swift diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index 2a6523a5a..cc6dd85df 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -106,7 +106,7 @@ 84B06FFE1ED3818D00F0B54B /* RSTree.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FFA1ED3818000F0B54B /* RSTree.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84B0700A1ED3822600F0B54B /* RSTextDrawing.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B070071ED3821900F0B54B /* RSTextDrawing.framework */; }; 84B0700B1ED3822600F0B54B /* RSTextDrawing.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84B070071ED3821900F0B54B /* RSTextDrawing.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 84B7178C201E66580091657D /* ContextualMenuCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7178B201E66580091657D /* ContextualMenuCreator.swift */; }; + 84B7178C201E66580091657D /* MainWindowController+ContextualMenus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7178B201E66580091657D /* MainWindowController+ContextualMenus.swift */; }; 84B99C671FAE35E600ECDEDB /* FeedListTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C661FAE35E600ECDEDB /* FeedListTreeControllerDelegate.swift */; }; 84B99C691FAE36B800ECDEDB /* FeedListFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C681FAE36B800ECDEDB /* FeedListFolder.swift */; }; 84B99C6B1FAE370B00ECDEDB /* FeedListFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C6A1FAE370B00ECDEDB /* FeedListFeed.swift */; }; @@ -564,7 +564,7 @@ 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSFeedFinder.xcodeproj; path = Frameworks/RSFeedFinder/RSFeedFinder.xcodeproj; sourceTree = ""; }; 84B06FF41ED3818000F0B54B /* RSTree.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSTree.xcodeproj; path = Frameworks/RSTree/RSTree.xcodeproj; sourceTree = ""; }; 84B070011ED3821800F0B54B /* RSTextDrawing.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSTextDrawing.xcodeproj; path = Frameworks/RSTextDrawing/RSTextDrawing.xcodeproj; sourceTree = ""; }; - 84B7178B201E66580091657D /* ContextualMenuCreator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContextualMenuCreator.swift; sourceTree = ""; }; + 84B7178B201E66580091657D /* MainWindowController+ContextualMenus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MainWindowController+ContextualMenus.swift"; sourceTree = ""; }; 84B99C661FAE35E600ECDEDB /* FeedListTreeControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListTreeControllerDelegate.swift; sourceTree = ""; }; 84B99C681FAE36B800ECDEDB /* FeedListFolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListFolder.swift; sourceTree = ""; }; 84B99C6A1FAE370B00ECDEDB /* FeedListFeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListFeed.swift; sourceTree = ""; }; @@ -1085,7 +1085,7 @@ 84B7178A201E66580091657D /* ContextualMenus */ = { isa = PBXGroup; children = ( - 84B7178B201E66580091657D /* ContextualMenuCreator.swift */, + 84B7178B201E66580091657D /* MainWindowController+ContextualMenus.swift */, ); name = ContextualMenus; path = Evergreen/ContextualMenus; @@ -1632,7 +1632,7 @@ 84A14FF320048CA70046AD9A /* SendToMicroBlogCommand.swift in Sources */, 849A97891ED9ECEF007D329B /* ArticleStyle.swift in Sources */, 84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */, - 84B7178C201E66580091657D /* ContextualMenuCreator.swift in Sources */, + 84B7178C201E66580091657D /* MainWindowController+ContextualMenus.swift in Sources */, 842611A21FCB769D0086A189 /* RSHTMLMetadata+Extension.swift in Sources */, 84A1500520048DDF0046AD9A /* SendToMarsEditCommand.swift in Sources */, D5907DB22004BB37005947E5 /* ScriptingObjectContainer.swift in Sources */, diff --git a/Evergreen/ContextualMenus/ContextualMenuCreator.swift b/Evergreen/ContextualMenus/ContextualMenuCreator.swift deleted file mode 100644 index c5b57206b..000000000 --- a/Evergreen/ContextualMenus/ContextualMenuCreator.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// ContextualMenuCreator.swift -// Evergreen -// -// Created by Brent Simmons on 1/28/18. -// Copyright © 2018 Ranchero Software. All rights reserved. -// - -import AppKit - - diff --git a/Evergreen/ContextualMenus/MainWindowController+ContextualMenus.swift b/Evergreen/ContextualMenus/MainWindowController+ContextualMenus.swift new file mode 100644 index 000000000..e7a2d1788 --- /dev/null +++ b/Evergreen/ContextualMenus/MainWindowController+ContextualMenus.swift @@ -0,0 +1,154 @@ +// +// 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 + +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?) { + + } + + @objc func copyStringFromContextualMenu(_ sender: Any?) { + + } + + @objc func markObjectsReadFromContextualMenu(_ sender: Any?) { + + } + + @objc func deleteFromContextualMenu(_ sender: Any?) { + + } + + @objc func renameFromContextualMenu(_ sender: Any?) { + + } +} + +// 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(copyStringFromContextualMenu(_:)), feed.url) + menu.addItem(copyFeedURLItem) + + if let homePageURL = feed.homePageURL { + let item = menuItem(NSLocalizedString("Copy Home Page URL", comment: "Command"), #selector(copyStringFromContextualMenu(_:)), 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()) + } + + return menu.numberOfItems > 0 ? menu : nil + } + + func menuForMultipleObjects(_ objects: [Any]) -> NSMenu? { + + let menu = NSMenu(title: "") + + if anyObjectInArrayHasNonZeroUnreadCount(objects) { + menu.addItem(markAllReadMenuItem(objects)) + menu.addItem(NSMenuItem.separator()) + } + + + 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 menuItem(_ title: String, _ action: Selector, _ representedObject: Any) -> NSMenuItem { + + let item = NSMenuItem(title: title, action: action, keyEquivalent: "") + item.representedObject = representedObject + item.target = self + return item + } +} +