From 6879c172c27932ce62d698f60601718d5c4839a0 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Wed, 20 Dec 2017 12:59:31 -0800 Subject: [PATCH] Make a bunch of progress on keyboard commands. --- Evergreen.xcodeproj/project.pbxproj | 44 +++++++++ Evergreen/Base.lproj/MainWindow.storyboard | 14 ++- .../Keyboard/MainWIndowKeyboardHandler.swift | 36 ++++++++ .../MainWindow/KeyboardDelegateProtocol.swift | 4 +- .../MainWindow/MainWindowController.swift | 53 ++++++++--- .../Keyboard/SidebarKeyboardDelegate.swift | 42 +++++++++ .../Sidebar/SidebarOutlineView.swift | 36 +------- .../Sidebar/SidebarViewController.swift | 32 +++++-- .../Keyboard/TimelineKeyboardDelegate.swift | 26 ++++++ .../Timeline/TimelineTableView.swift | 11 +-- .../Timeline/TimelineViewController.swift | 89 ++----------------- 11 files changed, 247 insertions(+), 140 deletions(-) create mode 100644 Evergreen/MainWindow/Keyboard/MainWIndowKeyboardHandler.swift create mode 100644 Evergreen/MainWindow/Sidebar/Keyboard/SidebarKeyboardDelegate.swift create mode 100644 Evergreen/MainWindow/Timeline/Keyboard/TimelineKeyboardDelegate.swift diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index 35afe0ff2..9fc66957e 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -18,6 +18,11 @@ 842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */; }; 842E45E71ED8C747000A8B52 /* DB5.plist in Resources */ = {isa = PBXBuildFile; fileRef = 842E45E61ED8C747000A8B52 /* DB5.plist */; }; 84411E711FE5FBFA004B527F /* SmallIconProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84411E701FE5FBFA004B527F /* SmallIconProvider.swift */; }; + 844B5B591FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B5B581FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift */; }; + 844B5B5B1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B5B5A1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift */; }; + 844B5B651FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 844B5B641FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist */; }; + 844B5B671FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B5B661FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift */; }; + 844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 844B5B681FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist */; }; 84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */; }; 845213231FCA5B11003B6E93 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845213221FCA5B10003B6E93 /* ImageDownloader.swift */; }; 845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */; }; @@ -419,6 +424,11 @@ 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowSplitView.swift; sourceTree = ""; }; 842E45E61ED8C747000A8B52 /* DB5.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = DB5.plist; path = Evergreen/Resources/DB5.plist; sourceTree = ""; }; 84411E701FE5FBFA004B527F /* SmallIconProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallIconProvider.swift; sourceTree = ""; }; + 844B5B581FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarKeyboardDelegate.swift; sourceTree = ""; }; + 844B5B5A1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineKeyboardDelegate.swift; sourceTree = ""; }; + 844B5B641FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = GlobalKeyboardShortcuts.plist; sourceTree = ""; }; + 844B5B661FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWIndowKeyboardHandler.swift; sourceTree = ""; }; + 844B5B681FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SidebarKeyboardShortcuts.plist; sourceTree = ""; }; 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListControlsView.swift; sourceTree = ""; }; 845213221FCA5B10003B6E93 /* ImageDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageDownloader.swift; sourceTree = ""; }; 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleFaviconDownloader.swift; sourceTree = ""; }; @@ -572,6 +582,7 @@ 842E45E21ED8C681000A8B52 /* KeyboardDelegateProtocol.swift */, 849A975D1ED9EB72007D329B /* MainWindowController.swift */, 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */, + 844B5B6B1FEA224B00C7C76A /* Keyboard */, 849A975F1ED9EB95007D329B /* Sidebar */, 849A97681ED9EBC8007D329B /* Timeline */, 849A977C1ED9EC42007D329B /* Detail */, @@ -583,6 +594,32 @@ path = Evergreen/MainWindow; sourceTree = ""; }; + 844B5B6A1FEA224000C7C76A /* Keyboard */ = { + isa = PBXGroup; + children = ( + 844B5B581FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift */, + 844B5B681FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist */, + ); + path = Keyboard; + sourceTree = ""; + }; + 844B5B6B1FEA224B00C7C76A /* Keyboard */ = { + isa = PBXGroup; + children = ( + 844B5B661FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift */, + 844B5B641FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist */, + ); + path = Keyboard; + sourceTree = ""; + }; + 844B5B6C1FEA282400C7C76A /* Keyboard */ = { + isa = PBXGroup; + children = ( + 844B5B5A1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift */, + ); + path = Keyboard; + sourceTree = ""; + }; 845213211FCA5B10003B6E93 /* Images */ = { isa = PBXGroup; children = ( @@ -685,6 +722,7 @@ 849A97631ED9EB96007D329B /* UnreadCountView.swift */, 845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */, 849A97821ED9EC63007D329B /* SidebarStatusBarView.swift */, + 844B5B6A1FEA224000C7C76A /* Keyboard */, 845A29251FC928C7007B49E3 /* Cell */, ); path = Sidebar; @@ -697,6 +735,7 @@ 84F204DF1FAACBB30076E152 /* ArticleArray.swift */, 849A97691ED9EBC8007D329B /* TimelineTableRowView.swift */, 849A976A1ED9EBC8007D329B /* TimelineTableView.swift */, + 844B5B6C1FEA282400C7C76A /* Keyboard */, 84E95D231FB1087500552D99 /* ArticlePasteboardWriter.swift */, 8414AD241FCF5A1E00955102 /* TimelineHeaderView.swift */, 849A976F1ED9EC04007D329B /* Cell */, @@ -1316,11 +1355,13 @@ files = ( 84EB381F1FBA8B9F000D2111 /* KeyboardShortcuts.html in Resources */, 849A97951ED9EF7A007D329B /* IndeterminateProgressWindow.xib in Resources */, + 844B5B651FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist in Resources */, 849A978F1ED9EE72007D329B /* DefaultFeeds.plist in Resources */, 849A979D1ED9EFEB007D329B /* template.html in Resources */, 849A97A91ED9F9AA007D329B /* AddFeedSheet.xib in Resources */, 84AFBB3E1FBE770200BA41CF /* PanicButtonWindow.xib in Resources */, 842E45E71ED8C747000A8B52 /* DB5.plist in Resources */, + 844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */, 849A97AC1ED9F9BC007D329B /* AddFolderSheet.xib in Resources */, 849A97AF1ED9FA08007D329B /* FeedList.storyboard in Resources */, 84E95CF71FABB3C800552D99 /* FeedList.plist in Resources */, @@ -1351,6 +1392,7 @@ 84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */, 84E46C7D1F75EF7B005ECFB3 /* AppDefaults.swift in Sources */, 842E45CE1ED8C308000A8B52 /* AppNotifications.swift in Sources */, + 844B5B5B1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift in Sources */, 84DAEE321F870B390058304B /* DockBadge.swift in Sources */, 842E45DD1ED8C54B000A8B52 /* Browser.swift in Sources */, 842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */, @@ -1389,6 +1431,7 @@ 84F2D5381FC22FCC00998D64 /* TodayFeedDelegate.swift in Sources */, 845213231FCA5B11003B6E93 /* ImageDownloader.swift in Sources */, 849A97431ED9EAA9007D329B /* AddFolderWindowController.swift in Sources */, + 844B5B671FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift in Sources */, 849A97921ED9EF65007D329B /* IndeterminateProgressWindowController.swift in Sources */, 849A97801ED9EC42007D329B /* DetailViewController.swift in Sources */, 8426119E1FCB6ED40086A189 /* HTMLMetadataDownloader.swift in Sources */, @@ -1408,6 +1451,7 @@ 84B99C691FAE36B800ECDEDB /* FeedListFolder.swift in Sources */, 84F204DE1FAACB8B0076E152 /* FeedListTimelineViewController.swift in Sources */, 84411E711FE5FBFA004B527F /* SmallIconProvider.swift in Sources */, + 844B5B591FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift in Sources */, 849A97A31ED9F180007D329B /* FolderTreeControllerDelegate.swift in Sources */, 845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */, 849A97851ED9ECCD007D329B /* PreferencesWindowController.swift in Sources */, diff --git a/Evergreen/Base.lproj/MainWindow.storyboard b/Evergreen/Base.lproj/MainWindow.storyboard index 99fa02762..e22bbca18 100644 --- a/Evergreen/Base.lproj/MainWindow.storyboard +++ b/Evergreen/Base.lproj/MainWindow.storyboard @@ -284,7 +284,7 @@ - + @@ -352,6 +352,7 @@ + @@ -435,6 +436,11 @@ + + + + + @@ -547,6 +553,7 @@ + @@ -582,6 +589,11 @@ + + + + + diff --git a/Evergreen/MainWindow/Keyboard/MainWIndowKeyboardHandler.swift b/Evergreen/MainWindow/Keyboard/MainWIndowKeyboardHandler.swift new file mode 100644 index 000000000..b8ac2678f --- /dev/null +++ b/Evergreen/MainWindow/Keyboard/MainWIndowKeyboardHandler.swift @@ -0,0 +1,36 @@ +// +// MainWIndowKeyboardHandler.swift +// Evergreen +// +// Created by Brent Simmons on 12/19/17. +// Copyright © 2017 Ranchero Software. All rights reserved. +// + +import Cocoa +import RSCore + +final class MainWindowKeyboardHandler: KeyboardDelegate { + + static let shared = MainWindowKeyboardHandler() + let globalShortcuts: Set + + init() { + + let f = Bundle.main.path(forResource: "GlobalKeyboardShortcuts", ofType: "plist")! + let rawShortcuts = NSArray(contentsOfFile: f)! as! [[String: Any]] + + self.globalShortcuts = Set(rawShortcuts.flatMap { KeyboardShortcut(dictionary: $0) }) + } + + func keydown(_ event: NSEvent, in view: NSView) -> Bool { + + let key = KeyboardKey(with: event) + guard let matchingShortcut = KeyboardShortcut.findMatchingShortcut(in: globalShortcuts, key: key) else { + return false + } + + matchingShortcut.perform(with: view) + return true + } +} + diff --git a/Evergreen/MainWindow/KeyboardDelegateProtocol.swift b/Evergreen/MainWindow/KeyboardDelegateProtocol.swift index 2d6ac192a..2c288e42b 100644 --- a/Evergreen/MainWindow/KeyboardDelegateProtocol.swift +++ b/Evergreen/MainWindow/KeyboardDelegateProtocol.swift @@ -10,8 +10,8 @@ import Cocoa let keypadEnter: unichar = 3 -protocol KeyboardDelegate: class { +@objc protocol KeyboardDelegate: class { // Return true if handled. - func handleKeydownEvent(_: NSEvent, sender: AnyObject) -> Bool + func keydown(_: NSEvent, in view: NSView) -> Bool } diff --git a/Evergreen/MainWindow/MainWindowController.swift b/Evergreen/MainWindow/MainWindowController.swift index fef4527df..a6b3ea5b0 100644 --- a/Evergreen/MainWindow/MainWindowController.swift +++ b/Evergreen/MainWindow/MainWindowController.swift @@ -118,21 +118,41 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { return true } - // MARK: Actions - - @IBAction func showAddFolderWindow(_ sender: AnyObject) { + // MARK: - Actions + + @IBAction func scrollOrGoToNextUnread(_ sender: Any?) { + +// guard let detailViewController = detailViewController else { +// return +// } +// +// if detailViewController.canScrollWebView() { +// detailViewController.scrollPageDown(sender) +// return +// } + + nextUnread(sender) + } + + + @IBAction func showAddFolderWindow(_ sender: Any) { appDelegate.showAddFolderSheetOnWindow(window!) } - @IBAction func openArticleInBrowser(_ sender: AnyObject?) { + @IBAction func openArticleInBrowser(_ sender: Any?) { if let link = currentLink { Browser.open(link) } } - - @IBAction func nextUnread(_ sender: AnyObject?) { + + @IBAction func openInBrowser(_ sender: Any?) { + + openArticleInBrowser(sender) + } + + @IBAction func nextUnread(_ sender: Any?) { guard let timelineViewController = timelineViewController, let sidebarViewController = sidebarViewController else { return @@ -153,17 +173,28 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { } } - @IBAction func markAllAsRead(_ sender: AnyObject?) { + @IBAction func markAllAsRead(_ sender: Any?) { timelineViewController?.markAllAsRead() } - @IBAction func markRead(_ sender: AnyObject?) { + @IBAction func markRead(_ sender: Any?) { - timelineViewController?.markSelectedArticlesAsRead(sender!) + timelineViewController?.markSelectedArticlesAsRead(sender) } - - @IBAction func toggleSidebar(_ sender: AnyObject?) { + + @IBAction func markUnread(_ sender: Any?) { + + timelineViewController?.markSelectedArticlesAsUnread(sender) + } + + @IBAction func markUnreadAndGoToNextUnread(_ sender: Any?) { + + markUnread(sender) + nextUnread(sender) + } + + @IBAction func toggleSidebar(_ sender: Any?) { splitViewController!.toggleSidebar(sender) } diff --git a/Evergreen/MainWindow/Sidebar/Keyboard/SidebarKeyboardDelegate.swift b/Evergreen/MainWindow/Sidebar/Keyboard/SidebarKeyboardDelegate.swift new file mode 100644 index 000000000..e048db67a --- /dev/null +++ b/Evergreen/MainWindow/Sidebar/Keyboard/SidebarKeyboardDelegate.swift @@ -0,0 +1,42 @@ +// +// SidebarKeyboardDelegate.swift +// Evergreen +// +// Created by Brent Simmons on 12/19/17. +// Copyright © 2017 Ranchero Software. All rights reserved. +// + +import Cocoa +import RSCore + +@objc final class SidebarKeyboardDelegate: NSObject, KeyboardDelegate { + + @IBOutlet weak var sidebarViewController: SidebarViewController? + let shortcuts: Set + + override init() { + + let f = Bundle.main.path(forResource: "SidebarKeyboardShortcuts", ofType: "plist")! + let rawShortcuts = NSArray(contentsOfFile: f)! as! [[String: Any]] + + self.shortcuts = Set(rawShortcuts.flatMap { KeyboardShortcut(dictionary: $0) }) + + super.init() + } + + func keydown(_ event: NSEvent, in view: NSView) -> Bool { + + if MainWindowKeyboardHandler.shared.keydown(event, in: view) { + return true + } + + let key = KeyboardKey(with: event) + guard let matchingShortcut = KeyboardShortcut.findMatchingShortcut(in: shortcuts, key: key) else { + return false + } + + matchingShortcut.perform(with: view) + return true + } +} + diff --git a/Evergreen/MainWindow/Sidebar/SidebarOutlineView.swift b/Evergreen/MainWindow/Sidebar/SidebarOutlineView.swift index 6e497a7c6..b154d410d 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarOutlineView.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarOutlineView.swift @@ -13,47 +13,17 @@ import RSTree class SidebarOutlineView : NSOutlineView { weak var sidebarViewController: SidebarViewController? + @IBOutlet var keyboardDelegate: KeyboardDelegate! //MARK: NSResponder override func keyDown(with event: NSEvent) { - - guard !event.rs_keyIsModified() else { - super.keyDown(with: event) - return - } - - let ch = Int(event.rs_unmodifiedCharacter()) - if ch == NSNotFound { - super.keyDown(with: event) - return - } - - var isNavigationKey = false - var keyHandled = false - switch(ch) { - - case NSRightArrowFunctionKey: - isNavigationKey = true - keyHandled = true - - case NSDeleteFunctionKey, Int(kDeleteKeyCode): - keyHandled = true - sidebarViewController?.delete(event) - - default: - keyHandled = false - } - - if isNavigationKey { - NotificationCenter.default.post(name: .AppNavigationKeyPressed, object: self, userInfo: [UserInfoKey.navigationKeyPressed: ch]) + if keyboardDelegate.keydown(event, in: self) { return } - if !keyHandled { - super.keyDown(with: event) - } + super.keyDown(with: event) } override func frameOfCell(atColumn column: Int, row: Int) -> NSRect { diff --git a/Evergreen/MainWindow/Sidebar/SidebarViewController.swift b/Evergreen/MainWindow/Sidebar/SidebarViewController.swift index e65e833f4..7b1e97f28 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarViewController.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarViewController.swift @@ -125,6 +125,14 @@ import RSCore animatingChanges = false } + @IBAction func openInBrowser(_ sender: Any?) { + + guard let feed = singleSelectedFeed, let homePageURL = feed.homePageURL else { + return + } + Browser.open(homePageURL) + } + // MARK: Navigation @@ -243,14 +251,26 @@ import RSCore private extension SidebarViewController { var selectedNodes: [Node] { - get { - if let nodes = outlineView.selectedItems as? [Node] { - return nodes - } - return [Node]() + if let nodes = outlineView.selectedItems as? [Node] { + return nodes } + return [Node]() } - + + var singleSelectedNode: Node? { + guard selectedNodes.count == 1 else { + return nil + } + return selectedNodes.first! + } + + var singleSelectedFeed: Feed? { + guard let node = singleSelectedNode else { + return nil + } + return node.representedObject as? Feed + } + func rebuildTreeAndReloadDataIfNeeded() { if !animatingChanges && !BatchUpdate.shared.isPerforming { diff --git a/Evergreen/MainWindow/Timeline/Keyboard/TimelineKeyboardDelegate.swift b/Evergreen/MainWindow/Timeline/Keyboard/TimelineKeyboardDelegate.swift new file mode 100644 index 000000000..134269dbe --- /dev/null +++ b/Evergreen/MainWindow/Timeline/Keyboard/TimelineKeyboardDelegate.swift @@ -0,0 +1,26 @@ +// +// TimelineKeyboardDelegate.swift +// Evergreen +// +// Created by Brent Simmons on 12/19/17. +// Copyright © 2017 Ranchero Software. All rights reserved. +// + +import Cocoa +import RSCore + +// Doesn’t have any shortcuts of its own — they’re all in MainWindowKeyboardHandler. + +@objc final class TimelineKeyboardDelegate: NSObject, KeyboardDelegate { + + @IBOutlet weak var timelineViewController: TimelineViewController? + + override init() { + super.init() + } + + func keydown(_ event: NSEvent, in view: NSView) -> Bool { + + return MainWindowKeyboardHandler.shared.keydown(event, in: view) + } +} diff --git a/Evergreen/MainWindow/Timeline/TimelineTableView.swift b/Evergreen/MainWindow/Timeline/TimelineTableView.swift index 332201e8e..386541047 100644 --- a/Evergreen/MainWindow/Timeline/TimelineTableView.swift +++ b/Evergreen/MainWindow/Timeline/TimelineTableView.swift @@ -10,18 +10,15 @@ import Cocoa class TimelineTableView: NSTableView { - weak var keyboardDelegate: KeyboardDelegate? + @IBOutlet var keyboardDelegate: KeyboardDelegate! //MARK: NSResponder override func keyDown(with event: NSEvent) { - - if let keyboardDelegate = keyboardDelegate { - if keyboardDelegate.handleKeydownEvent(event, sender: self) { - return; - } + + if keyboardDelegate.keydown(event, in: self) { + return } - super.keyDown(with: event) } diff --git a/Evergreen/MainWindow/Timeline/TimelineViewController.swift b/Evergreen/MainWindow/Timeline/TimelineViewController.swift index 77f97ddb9..5676c22a5 100644 --- a/Evergreen/MainWindow/Timeline/TimelineViewController.swift +++ b/Evergreen/MainWindow/Timeline/TimelineViewController.swift @@ -12,7 +12,7 @@ import RSTextDrawing import Data import Account -class TimelineViewController: NSViewController, KeyboardDelegate, UndoableCommandRunner { +class TimelineViewController: NSViewController, UndoableCommandRunner { @IBOutlet var tableView: TimelineTableView! @@ -22,6 +22,12 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman } } + var hasAtLeastOneSelectedArticle: Bool { + get { + return tableView.selectedRow != -1 + } + } + var undoableCommands = [UndoableCommand]() private var cellAppearance: TimelineCellAppearance! private var showFeedNames = false @@ -68,7 +74,6 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman tableView.rowHeight = calculateRowHeight() tableView.target = self tableView.doubleAction = #selector(openArticleInBrowser(_:)) - tableView.keyboardDelegate = self tableView.setDraggingSourceOperationMask(.copy, forLocal: false) if !didRegisterForNotifications { @@ -159,7 +164,7 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman } } - @IBAction func markSelectedArticlesAsRead(_ sender: AnyObject?) { + @IBAction func markSelectedArticlesAsRead(_ sender: Any?) { guard let undoManager = undoManager, let markReadCommand = MarkReadOrUnreadCommand(initialArticles: selectedArticles, markingRead: true, undoManager: undoManager) else { return @@ -167,7 +172,7 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman runCommand(markReadCommand) } - @IBAction func markSelectedArticlesAsUnread(_ sender: AnyObject) { + @IBAction func markSelectedArticlesAsUnread(_ sender: Any?) { guard let undoManager = undoManager, let markUnreadCommand = MarkReadOrUnreadCommand(initialArticles: selectedArticles, markingRead: false, undoManager: undoManager) else { return @@ -250,76 +255,6 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman } } - // MARK: - KeyboardDelegate - - func handleKeydownEvent(_ event: NSEvent, sender: AnyObject) -> Bool { - - guard !event.rs_keyIsModified() else { - return false - } - - let ch = Int(event.rs_unmodifiedCharacter()) - if ch == NSNotFound { - return false - } - - let hasSelectedArticle = hasAtLeastOneSelectedArticle - var keyHandled = false - var isNavigationKey = false - - var shouldOpenInBrowser = false - - switch(ch) { - - case KeyboardConstant.lineFeedKey: - shouldOpenInBrowser = true - keyHandled = true - - case KeyboardConstant.returnKey: - shouldOpenInBrowser = true - keyHandled = true - - case "r".keyboardIntegerValue: - markSelectedArticlesAsRead(sender) - keyHandled = true - - case "u".keyboardIntegerValue: - markSelectedArticlesAsUnread(sender) - keyHandled = true - - case NSLeftArrowFunctionKey: - isNavigationKey = true - keyHandled = true - - default: - keyHandled = false - } - - if !keyHandled { - let chUnichar = event.rs_unmodifiedCharacter() - - switch(chUnichar) { - - case keypadEnter: - shouldOpenInBrowser = true - keyHandled = true - - default: - keyHandled = false - } - } - - if isNavigationKey { - NotificationCenter.default.post(name: .AppNavigationKeyPressed, object: self.tableView, userInfo: [UserInfoKey.navigationKeyPressed: ch]) - } - - if shouldOpenInBrowser && hasSelectedArticle { - openArticleInBrowser(self) - } - - return keyHandled - } - // MARK: - Reloading Data private func cellForRowView(_ rowView: NSView) -> NSView? { @@ -501,12 +436,6 @@ extension TimelineViewController: NSTableViewDelegate { private extension TimelineViewController { - var hasAtLeastOneSelectedArticle: Bool { - get { - return tableView.selectedRow != -1 - } - } - func emptyTheTimeline() { if !articles.isEmpty {