Enabled "Add to Feeds" button on Feed Directory. Issue #105

This commit is contained in:
Maurice Parker 2018-09-13 10:04:20 -05:00
parent 3a4abb6d6e
commit d34e5916ad
5 changed files with 261 additions and 1 deletions

View File

@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
519B8D332143397200FA689C /* SharingServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519B8D322143397200FA689C /* SharingServiceDelegate.swift */; }; 519B8D332143397200FA689C /* SharingServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519B8D322143397200FA689C /* SharingServiceDelegate.swift */; };
51EC114C2149FE3300B296E3 /* FolderTreeMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EC114B2149FE3300B296E3 /* FolderTreeMenu.swift */; }; 51EC114C2149FE3300B296E3 /* FolderTreeMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EC114B2149FE3300B296E3 /* FolderTreeMenu.swift */; };
51EC11A1214A94AD00B296E3 /* AddFeedFromListSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51EC1193214A94AC00B296E3 /* AddFeedFromListSheet.xib */; };
51EC11A3214A990000B296E3 /* AddFeedFromListWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EC11A2214A990000B296E3 /* AddFeedFromListWindowController.swift */; };
6581C73820CED60100F4AD34 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */; }; 6581C73820CED60100F4AD34 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */; };
6581C73A20CED60100F4AD34 /* SafariExtensionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73920CED60100F4AD34 /* SafariExtensionViewController.swift */; }; 6581C73A20CED60100F4AD34 /* SafariExtensionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73920CED60100F4AD34 /* SafariExtensionViewController.swift */; };
6581C73D20CED60100F4AD34 /* SafariExtensionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */; }; 6581C73D20CED60100F4AD34 /* SafariExtensionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */; };
@ -482,6 +484,8 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
519B8D322143397200FA689C /* SharingServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServiceDelegate.swift; sourceTree = "<group>"; }; 519B8D322143397200FA689C /* SharingServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServiceDelegate.swift; sourceTree = "<group>"; };
51EC114B2149FE3300B296E3 /* FolderTreeMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FolderTreeMenu.swift; path = AddFeed/FolderTreeMenu.swift; sourceTree = "<group>"; }; 51EC114B2149FE3300B296E3 /* FolderTreeMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FolderTreeMenu.swift; path = AddFeed/FolderTreeMenu.swift; sourceTree = "<group>"; };
51EC1194214A94AC00B296E3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = NetNewsWire/Base.lproj/AddFeedFromListSheet.xib; sourceTree = SOURCE_ROOT; };
51EC11A2214A990000B296E3 /* AddFeedFromListWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AddFeedFromListWindowController.swift; path = AddFeed/AddFeedFromListWindowController.swift; sourceTree = "<group>"; };
6581C73320CED60000F4AD34 /* Subscribe to Feed.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Subscribe to Feed.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 6581C73320CED60000F4AD34 /* Subscribe to Feed.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Subscribe to Feed.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
6581C73420CED60100F4AD34 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 6581C73420CED60100F4AD34 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariExtensionHandler.swift; sourceTree = "<group>"; }; 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariExtensionHandler.swift; sourceTree = "<group>"; };
@ -950,6 +954,8 @@
849A97551ED9EAC3007D329B /* Add Feed */ = { 849A97551ED9EAC3007D329B /* Add Feed */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
51EC1193214A94AC00B296E3 /* AddFeedFromListSheet.xib */,
51EC11A2214A990000B296E3 /* AddFeedFromListWindowController.swift */,
849A97A71ED9F9AA007D329B /* AddFeedSheet.xib */, 849A97A71ED9F9AA007D329B /* AddFeedSheet.xib */,
849A97511ED9EAC0007D329B /* AddFeedController.swift */, 849A97511ED9EAC0007D329B /* AddFeedController.swift */,
849A97521ED9EAC0007D329B /* AddFeedWindowController.swift */, 849A97521ED9EAC0007D329B /* AddFeedWindowController.swift */,
@ -1814,6 +1820,7 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
51EC11A1214A94AD00B296E3 /* AddFeedFromListSheet.xib in Resources */,
84EB381F1FBA8B9F000D2111 /* KeyboardShortcuts.html in Resources */, 84EB381F1FBA8B9F000D2111 /* KeyboardShortcuts.html in Resources */,
849A97951ED9EF7A007D329B /* IndeterminateProgressWindow.xib in Resources */, 849A97951ED9EF7A007D329B /* IndeterminateProgressWindow.xib in Resources */,
844B5B651FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist in Resources */, 844B5B651FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist in Resources */,
@ -1943,6 +1950,7 @@
8426118A1FCB67AA0086A189 /* FeedIconDownloader.swift in Sources */, 8426118A1FCB67AA0086A189 /* FeedIconDownloader.swift in Sources */,
84162A152038C12C00035290 /* MarkCommandValidationStatus.swift in Sources */, 84162A152038C12C00035290 /* MarkCommandValidationStatus.swift in Sources */,
84E95D241FB1087500552D99 /* ArticlePasteboardWriter.swift in Sources */, 84E95D241FB1087500552D99 /* ArticlePasteboardWriter.swift in Sources */,
51EC11A3214A990000B296E3 /* AddFeedFromListWindowController.swift in Sources */,
849A975B1ED9EB0D007D329B /* ArticleUtilities.swift in Sources */, 849A975B1ED9EB0D007D329B /* ArticleUtilities.swift in Sources */,
84DAEE301F86CAFE0058304B /* OPMLImporter.swift in Sources */, 84DAEE301F86CAFE0058304B /* OPMLImporter.swift in Sources */,
849A975C1ED9EB0D007D329B /* DefaultFeedsImporter.swift in Sources */, 849A975C1ED9EB0D007D329B /* DefaultFeedsImporter.swift in Sources */,
@ -2117,6 +2125,14 @@
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
51EC1193214A94AC00B296E3 /* AddFeedFromListSheet.xib */ = {
isa = PBXVariantGroup;
children = (
51EC1194214A94AC00B296E3 /* Base */,
);
name = AddFeedFromListSheet.xib;
sourceTree = "<group>";
};
6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */ = { 6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (

View File

@ -49,6 +49,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
private var readerWindows = [NSWindowController]() private var readerWindows = [NSWindowController]()
private var feedListWindowController: NSWindowController? private var feedListWindowController: NSWindowController?
private var addFeedController: AddFeedController? private var addFeedController: AddFeedController?
private var addFeedFromListController: AddFeedFromListWindowController?
private var addFolderWindowController: AddFolderWindowController? private var addFolderWindowController: AddFolderWindowController?
private var keyboardShortcutsWindowController: WebViewWindowController? private var keyboardShortcutsWindowController: WebViewWindowController?
private var inspectorWindowController: InspectorWindowController? private var inspectorWindowController: InspectorWindowController?
@ -101,6 +102,18 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
addFeedController = AddFeedController(hostWindow: window) addFeedController = AddFeedController(hostWindow: window)
addFeedController?.showAddFeedSheet(urlString, name) addFeedController?.showAddFeedSheet(urlString, name)
} }
func showAddFeedFromListOnMainWindow(_ feedListFeeds: [FeedListFeed]) {
addFeedFromListController = AddFeedFromListWindowController(feedListFeeds)
createAndShowMainWindow()
let isDisplayingSheet = mainWindowController?.isDisplayingSheet ?? false
if !isDisplayingSheet, let mainWindow = mainWindowController?.window {
addFeedFromListController!.runSheetOnWindow(mainWindow)
}
}
// MARK: - NSApplicationDelegate // MARK: - NSApplicationDelegate

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AddFeedFromListWindowController" customModule="NetNewsWire" customModuleProvider="target">
<connections>
<outlet property="addButton" destination="dtI-Hu-rFb" id="D11-zR-dWH"/>
<outlet property="addFeedTextField" destination="7If-aT-UTD" id="HMp-AC-iuV"/>
<outlet property="folderPopupButton" destination="6vt-DL-mVR" id="rm7-y9-tBF"/>
<outlet property="window" destination="QvC-M9-y7g" id="7rH-S2-LF4"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Add Feed" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="217"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" misplaced="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="480" height="217"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dNV-oD-vzR">
<rect key="frame" x="18" y="63" width="50" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Folder:" id="Kwx-7B-CIu">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6vt-DL-mVR" userLabel="Folder Popup">
<rect key="frame" x="72" y="58" width="391" height="25"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="tLJ-zY-CcZ" id="0cM-5q-Snl">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="OpL-Uf-woJ">
<items>
<menuItem title="Item 1" state="on" id="tLJ-zY-CcZ"/>
<menuItem title="Item 2" id="APc-af-7Um"/>
<menuItem title="Item 3" id="j09-9b-bGs"/>
</items>
</menu>
</popUpButtonCell>
</popUpButton>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hXq-IS-19x">
<rect key="frame" x="302" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Dop-HC-6Q9">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancel:" target="-2" id="tcT-tt-t99"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dtI-Hu-rFb">
<rect key="frame" x="384" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Add" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6NK-Ql-drk">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="addFeed:" target="-2" id="Ilv-Un-eDp"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7If-aT-UTD">
<rect key="frame" x="18" y="98" width="82" height="17"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Add feed(s)?" id="CRI-fB-GoB">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="dNV-oD-vzR" firstAttribute="baseline" secondItem="6vt-DL-mVR" secondAttribute="baseline" id="14b-jN-4Y6"/>
<constraint firstItem="hXq-IS-19x" firstAttribute="centerY" secondItem="dtI-Hu-rFb" secondAttribute="centerY" id="6FR-Hu-qkL"/>
<constraint firstAttribute="bottom" secondItem="dtI-Hu-rFb" secondAttribute="bottom" constant="20" symbolic="YES" id="6ac-2K-RnD"/>
<constraint firstItem="7If-aT-UTD" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="89w-ob-4GI"/>
<constraint firstItem="dtI-Hu-rFb" firstAttribute="leading" secondItem="hXq-IS-19x" secondAttribute="trailing" constant="12" symbolic="YES" id="Djw-dV-x3S"/>
<constraint firstItem="6vt-DL-mVR" firstAttribute="leading" secondItem="dNV-oD-vzR" secondAttribute="trailing" constant="8" symbolic="YES" id="E9B-wf-c92"/>
<constraint firstItem="dtI-Hu-rFb" firstAttribute="width" secondItem="hXq-IS-19x" secondAttribute="width" id="J80-aG-OjE"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="7If-aT-UTD" secondAttribute="trailing" constant="20" symbolic="YES" id="Lhg-Q2-wh5"/>
<constraint firstItem="dtI-Hu-rFb" firstAttribute="top" secondItem="6vt-DL-mVR" secondAttribute="bottom" constant="20" symbolic="YES" id="YTA-Ca-UMg"/>
<constraint firstItem="dtI-Hu-rFb" firstAttribute="leading" secondItem="hXq-IS-19x" secondAttribute="trailing" constant="12" symbolic="YES" id="ahD-oU-iFu"/>
<constraint firstItem="hXq-IS-19x" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="dIj-8p-5kK"/>
<constraint firstAttribute="trailing" secondItem="dtI-Hu-rFb" secondAttribute="trailing" constant="20" symbolic="YES" id="kEo-af-SUe"/>
<constraint firstAttribute="trailing" secondItem="6vt-DL-mVR" secondAttribute="trailing" constant="20" symbolic="YES" id="suO-dd-E0b"/>
<constraint firstItem="7If-aT-UTD" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="uWY-iC-9nq"/>
<constraint firstItem="dNV-oD-vzR" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="vee-7b-pH8"/>
<constraint firstItem="6vt-DL-mVR" firstAttribute="top" secondItem="7If-aT-UTD" secondAttribute="bottom" constant="16" id="y91-8q-6dz"/>
</constraints>
</view>
<point key="canvasLocation" x="189" y="-767.5"/>
</window>
</objects>
</document>

View File

@ -76,8 +76,10 @@ extension FeedListViewController {
} }
@IBAction func addToFeeds(_ sender: Any?) { @IBAction func addToFeeds(_ sender: Any?) {
let selectedFeeds = selectedObjects.map { $0 as! FeedListFeed }
appDelegate.showAddFeedFromListOnMainWindow(selectedFeeds)
} }
} }
// MARK: - NSOutlineViewDataSource // MARK: - NSOutlineViewDataSource

View File

@ -0,0 +1,122 @@
//
// AddFeedFromListWindowController.swift
// NetNewsWire
//
// Created by Maurice Parker on 9/13/18.
// Copyright © 2018 Ranchero Software, LLC. All rights reserved.
//
import AppKit
import RSCore
import RSTree
import Articles
import Account
class AddFeedFromListWindowController : NSWindowController {
@IBOutlet weak var addFeedTextField: NSTextField!
@IBOutlet weak var folderPopupButton: NSPopUpButton!
private var feedListFeeds: [FeedListFeed]?
private var hostWindow: NSWindow!
private var folderTreeController: TreeController?
convenience init(_ feedListFeeds: [FeedListFeed]) {
self.init(windowNibName: NSNib.Name(rawValue: "AddFeedFromListSheet"))
self.feedListFeeds = feedListFeeds
}
func runSheetOnWindow(_ w: NSWindow) {
hostWindow = w
if let sheetWindow = self.window {
hostWindow.beginSheet(sheetWindow) { (returnCode: NSApplication.ModalResponse) -> Void in
}
}
}
override func windowDidLoad() {
guard let feedListFeeds = feedListFeeds else {
assertionFailure("Feeds should have been passed in the initializer")
return
}
if feedListFeeds.count == 1 {
addFeedTextField.stringValue = "Add \"\(feedListFeeds.first!.nameForDisplay)\"?"
} else {
addFeedTextField.stringValue = "Add \(feedListFeeds.count) feeds?"
}
let rootNode = Node(representedObject: AccountManager.shared.localAccount, parent: nil)
rootNode.canHaveChildNodes = true
folderTreeController = TreeController(delegate: FolderTreeControllerDelegate(), rootNode: rootNode)
folderPopupButton.menu = FolderTreeMenu.createFolderPopupMenu(with: folderTreeController!.rootNode)
}
// MARK: Actions
@IBAction func cancel(_ sender: Any?) {
if let sheetWindow = window {
hostWindow.endSheet(sheetWindow, returnCode: NSApplication.ModalResponse.cancel)
}
}
@IBAction func addFeed(_ sender: Any?) {
guard let container = folderPopupButton.selectedItem?.representedObject as? Container else {
assertionFailure("Expected the folderPopupButton to have a container.")
return
}
guard let feedListFeeds = feedListFeeds else {
assertionFailure("Feeds should have been passed in the initializer")
return
}
var account: Account?
var folder: Folder?
if container is Folder {
folder = (container as! Folder)
account = folder!.account
} else {
account = (container as! Account)
}
for feedListFeed in feedListFeeds {
if account!.hasFeed(withURL: feedListFeed.url) {
continue
}
guard let feed = account!.createFeed(with: feedListFeed.nameForDisplay, editedName: nil, url: feedListFeed.url) else {
continue
}
guard let url = URL(string: feedListFeed.url) else {
assertionFailure("Malformed URL string: \(feedListFeed.url).")
continue
}
if account!.addFeed(feed, to: folder) {
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
}
InitialFeedDownloader.download(url) { (parsedFeed) in
if let parsedFeed = parsedFeed {
account!.update(feed, with: parsedFeed, {})
}
}
}
if let sheetWindow = window {
hostWindow.endSheet(sheetWindow, returnCode: NSApplication.ModalResponse.OK)
}
}
}