Add extension management for our two SendToCommand implementations

This commit is contained in:
Maurice Parker 2020-04-08 20:22:13 -05:00
parent 61b755486a
commit d49eabbcb3
13 changed files with 666 additions and 175 deletions

View File

@ -385,16 +385,16 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="7UM-iq-OLB" customClass="PreferencesTableViewBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="44" width="160" height="225"/>
<rect key="frame" x="20" y="44" width="160" height="223"/>
<subviews>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="PaF-du-r3c">
<rect key="frame" x="1" y="0.0" width="158" height="224"/>
<rect key="frame" x="1" y="0.0" width="158" height="222"/>
<clipView key="contentView" id="cil-Gq-akO">
<rect key="frame" x="0.0" y="0.0" width="158" height="224"/>
<rect key="frame" x="0.0" y="0.0" width="158" height="222"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="aTp-KR-y6b">
<rect key="frame" x="0.0" y="0.0" width="159" height="224"/>
<rect key="frame" x="0.0" y="0.0" width="159" height="222"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -501,7 +501,7 @@
<rect key="frame" x="83" y="20" width="97" height="24"/>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Y7D-xQ-wep">
<rect key="frame" x="188" y="20" width="242" height="249"/>
<rect key="frame" x="188" y="20" width="242" height="247"/>
</customView>
</subviews>
<constraints>
@ -532,7 +532,7 @@
</viewController>
<customObject id="AgZ-2t-A2h" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-568" y="727"/>
<point key="canvasLocation" x="-558" y="806"/>
</scene>
<!--Container-->
<scene sceneID="fzS-hg-3TF">
@ -556,16 +556,16 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="pjs-G4-byk" customClass="PreferencesTableViewBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="44" width="160" height="218"/>
<rect key="frame" x="20" y="44" width="160" height="216"/>
<subviews>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="29T-r2-ckC">
<rect key="frame" x="1" y="0.0" width="158" height="217"/>
<rect key="frame" x="1" y="0.0" width="158" height="215"/>
<clipView key="contentView" id="dXw-GY-TP8">
<rect key="frame" x="0.0" y="0.0" width="158" height="217"/>
<rect key="frame" x="0.0" y="0.0" width="158" height="215"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="dfn-Vn-oDp">
<rect key="frame" x="0.0" y="0.0" width="159" height="217"/>
<rect key="frame" x="0.0" y="0.0" width="159" height="215"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -619,10 +619,6 @@
</prototypeCellViews>
</tableColumn>
</tableColumns>
<connections>
<outlet property="dataSource" destination="K4Z-qS-hrR" id="N2L-zD-LMX"/>
<outlet property="delegate" destination="K4Z-qS-hrR" id="EAl-PI-Ebp"/>
</connections>
</tableView>
</subviews>
</clipView>
@ -654,6 +650,9 @@
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="enableExtensionPoints:" target="K4Z-qS-hrR" id="Jlk-S5-Kam"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jfX-DL-TXs">
<rect key="frame" x="51" y="19" width="32" height="26"/>
@ -661,12 +660,15 @@
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="disableExtensionPoint:" target="K4Z-qS-hrR" id="Red-pz-FUE"/>
</connections>
</button>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="sak-nS-Xfu" customClass="PreferencesControlsBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="83" y="20" width="97" height="24"/>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="N1N-pE-gBL">
<rect key="frame" x="188" y="20" width="242" height="242"/>
<rect key="frame" x="188" y="20" width="242" height="240"/>
</customView>
</subviews>
<constraints>
@ -692,12 +694,12 @@
<connections>
<outlet property="deleteButton" destination="jfX-DL-TXs" id="gT1-Dt-vZL"/>
<outlet property="detailView" destination="N1N-pE-gBL" id="PYj-cW-fz1"/>
<outlet property="tableView" destination="dfn-Vn-oDp" id="BAw-X0-nFR"/>
<outlet property="tableView" destination="dfn-Vn-oDp" id="heh-fs-Tqr"/>
</connections>
</viewController>
<customObject id="Cne-wm-w1Q" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-82" y="821"/>
<point key="canvasLocation" x="-36" y="806"/>
</scene>
</scenes>
<resources>

View File

@ -70,43 +70,16 @@ extension ExtensionPointAddViewController: NSTableViewDelegate {
return
}
// switch addableAccountTypes[selectedRow] {
// case .onMyMac:
// let accountsAddLocalWindowController = AccountsAddLocalWindowController()
// accountsAddLocalWindowController.runSheetOnWindow(self.view.window!)
// accountsAddWindowController = accountsAddLocalWindowController
// case .cloudKit:
// let accountsAddCloudKitWindowController = AccountsAddCloudKitWindowController()
// accountsAddCloudKitWindowController.runSheetOnWindow(self.view.window!) { response in
// if response == NSApplication.ModalResponse.OK {
// self.restrictAccounts()
// self.tableView.reloadData()
// }
// }
// accountsAddWindowController = accountsAddCloudKitWindowController
// case .feedbin:
// let accountsFeedbinWindowController = AccountsFeedbinWindowController()
// accountsFeedbinWindowController.runSheetOnWindow(self.view.window!)
// accountsAddWindowController = accountsFeedbinWindowController
// case .feedWrangler:
// let accountsFeedWranglerWindowController = AccountsFeedWranglerWindowController()
// accountsFeedWranglerWindowController.runSheetOnWindow(self.view.window!)
// accountsAddWindowController = accountsFeedWranglerWindowController
// case .freshRSS:
// let accountsReaderAPIWindowController = AccountsReaderAPIWindowController()
// accountsReaderAPIWindowController.accountType = .freshRSS
// accountsReaderAPIWindowController.runSheetOnWindow(self.view.window!)
// accountsAddWindowController = accountsReaderAPIWindowController
// case .feedly:
// let addAccount = OAuthAccountAuthorizationOperation(accountType: .feedly)
// addAccount.delegate = self
// addAccount.presentationAnchor = self.view.window!
// MainThreadOperationQueue.shared.add(addAccount)
// case .newsBlur:
// let accountsNewsBlurWindowController = AccountsNewsBlurWindowController()
// accountsNewsBlurWindowController.runSheetOnWindow(self.view.window!)
// accountsAddWindowController = accountsNewsBlurWindowController
// }
let extensionPointType = availableExtensionPointTypes[selectedRow]
switch extensionPointType {
case .marsEdit, .microblog:
let windowController = ExtensionPointEnableBasicWindowController()
windowController.extensionPointType = extensionPointType
windowController.runSheetOnWindow(self.view.window!)
extensionPointAddWindowController = windowController
default:
break
}
tableView.selectRowIndexes([], byExtendingSelection: false)

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ExtensionPointDetailViewController" customModule="NetNewsWire" customModuleProvider="target">
<connections>
<outlet property="descriptionLabel" destination="tK2-QL-hvM" id="5jU-Vz-6us"/>
<outlet property="imageView" destination="I6P-Q2-DtA" id="mBe-xk-jOe"/>
<outlet property="titleLabel" destination="d0R-Cs-axs" id="axb-bi-iwe"/>
<outlet property="view" destination="988-TV-aJt" id="cUJ-Ez-XiC"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<tabView id="988-TV-aJt">
<rect key="frame" x="0.0" y="0.0" width="346" height="300"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<font key="font" metaFont="system"/>
<tabViewItems>
<tabViewItem label="Extension Information" identifier="" id="k6A-mz-zOF">
<view key="view" id="jT6-Hh-gWM">
<rect key="frame" x="10" y="33" width="326" height="254"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="bottom" spacing="19" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Z8D-OO-XZd">
<rect key="frame" x="69" y="200" width="189" height="38"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="I6P-Q2-DtA">
<rect key="frame" x="0.0" y="0.0" width="36" height="36"/>
<constraints>
<constraint firstAttribute="width" constant="36" id="HqU-9L-bqb"/>
<constraint firstAttribute="height" constant="36" id="bpI-uD-bzZ"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="NSAdvanced" id="iCo-JD-zZy"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d0R-Cs-axs">
<rect key="frame" x="53" y="0.0" width="138" height="38"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Extension" id="CGj-bV-rXW">
<font key="font" metaFont="system" size="32"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tK2-QL-hvM">
<rect key="frame" x="31" y="168" width="264" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="260" id="GRp-qY-UP1"/>
</constraints>
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" alignment="left" allowsEditingTextAttributes="YES" id="7dt-TS-iHM">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="tK2-QL-hvM" firstAttribute="top" secondItem="Z8D-OO-XZd" secondAttribute="bottom" constant="16" id="3Ww-vg-yg7"/>
<constraint firstItem="Z8D-OO-XZd" firstAttribute="top" secondItem="jT6-Hh-gWM" secondAttribute="top" constant="16" id="3hP-9H-3IX"/>
<constraint firstItem="tK2-QL-hvM" firstAttribute="centerX" secondItem="jT6-Hh-gWM" secondAttribute="centerX" id="7ik-M6-Wmx"/>
<constraint firstItem="Z8D-OO-XZd" firstAttribute="centerX" secondItem="jT6-Hh-gWM" secondAttribute="centerX" id="XZC-Yp-uT5"/>
</constraints>
</view>
</tabViewItem>
</tabViewItems>
<point key="canvasLocation" x="-195" y="110"/>
</tabView>
</objects>
<resources>
<image name="NSAdvanced" width="32" height="32"/>
</resources>
</document>

View File

@ -0,0 +1,37 @@
//
// ExtensionPointDetailViewController.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/8/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Cocoa
class ExtensionPointDetailViewController: NSViewController {
@IBOutlet weak var imageView: NSImageView!
@IBOutlet weak var titleLabel: NSTextField!
@IBOutlet weak var descriptionLabel: NSTextField!
private var extensionPointWindowController: NSWindowController?
private var extensionPointID: ExtensionPointIdentifer?
init(extensionPointID: ExtensionPointIdentifer) {
super.init(nibName: "ExtensionPointDetail", bundle: nil)
self.extensionPointID = extensionPointID
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func viewDidLoad() {
super.viewDidLoad()
guard let extensionPointID = extensionPointID else { return }
imageView.image = extensionPointID.templateImage
titleLabel.stringValue = extensionPointID.title
descriptionLabel.attributedStringValue = extensionPointID.description
}
}

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ExtensionPointEnableBasicWindowController" customModule="NetNewsWire" customModuleProvider="target">
<connections>
<outlet property="descriptionLabel" destination="thC-ep-vXS" id="o9I-vp-z54"/>
<outlet property="imageView" destination="LSA-B8-aGZ" id="AN5-t1-d52"/>
<outlet property="titleLabel" destination="iAC-tU-rvZ" id="vMx-2H-b44"/>
<outlet property="window" destination="HNe-Jr-kev" id="C8n-l1-WhI"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="HNe-Jr-kev">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="407" height="156"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" wantsLayer="YES" id="qAd-AQ-5ue">
<rect key="frame" x="0.0" y="0.0" width="407" height="156"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="bottom" spacing="19" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nLd-4a-dQg">
<rect key="frame" x="109" y="89" width="189" height="51"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="LSA-B8-aGZ">
<rect key="frame" x="0.0" y="0.0" width="36" height="36"/>
<constraints>
<constraint firstAttribute="width" constant="36" id="SuU-du-YHk"/>
<constraint firstAttribute="height" constant="36" id="qxc-dc-d8U"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="NSAdvanced" id="5qe-pZ-t40"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iAC-tU-rvZ">
<rect key="frame" x="53" y="13" width="138" height="38"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Extension" id="kuv-Xu-aIk">
<font key="font" metaFont="system" size="32"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sGb-z5-IdF">
<rect key="frame" x="312" y="13" width="81" height="32"/>
<buttonCell key="cell" type="push" title="Enable" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Oh8-q3-Aup">
<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="enable:" target="-2" id="BN5-u0-DNe"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aKy-4s-WDM">
<rect key="frame" x="231" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="2nM-LA-6fh">
<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="WK9-uJ-mIw"/>
</connections>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="thC-ep-vXS">
<rect key="frame" x="52" y="57" width="304" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="300" id="igx-s6-xe9"/>
</constraints>
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" alignment="left" allowsEditingTextAttributes="YES" id="aUU-dO-RNt">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="iAC-tU-rvZ" firstAttribute="top" secondItem="qAd-AQ-5ue" secondAttribute="top" constant="16" id="Cxn-GQ-jzh"/>
<constraint firstAttribute="bottom" secondItem="sGb-z5-IdF" secondAttribute="bottom" constant="20" id="Moe-ce-JeY"/>
<constraint firstAttribute="trailing" secondItem="sGb-z5-IdF" secondAttribute="trailing" constant="20" id="OdS-3p-qyB"/>
<constraint firstItem="sGb-z5-IdF" firstAttribute="leading" secondItem="aKy-4s-WDM" secondAttribute="trailing" constant="11" id="QPh-zm-9uL"/>
<constraint firstItem="thC-ep-vXS" firstAttribute="centerX" secondItem="qAd-AQ-5ue" secondAttribute="centerX" id="fC4-fE-SyO"/>
<constraint firstItem="aKy-4s-WDM" firstAttribute="centerY" secondItem="sGb-z5-IdF" secondAttribute="centerY" id="naD-Tq-iwx"/>
<constraint firstItem="thC-ep-vXS" firstAttribute="top" secondItem="nLd-4a-dQg" secondAttribute="bottom" constant="16" id="qRM-G0-del"/>
<constraint firstItem="aKy-4s-WDM" firstAttribute="top" secondItem="thC-ep-vXS" secondAttribute="bottom" constant="16" id="vrt-3v-j4f"/>
<constraint firstItem="nLd-4a-dQg" firstAttribute="centerX" secondItem="qAd-AQ-5ue" secondAttribute="centerX" id="xXl-e5-lnN"/>
</constraints>
</view>
<connections>
<outlet property="delegate" destination="-2" id="fo9-G5-zJh"/>
</connections>
<point key="canvasLocation" x="103.5" y="89.5"/>
</window>
</objects>
<resources>
<image name="NSAdvanced" width="32" height="32"/>
</resources>
</document>

View File

@ -0,0 +1,61 @@
//
// ExtensionPointEnableBasicWindowController.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/8/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Cocoa
class ExtensionPointEnableBasicWindowController: NSWindowController {
@IBOutlet weak var imageView: NSImageView!
@IBOutlet weak var titleLabel: NSTextField!
@IBOutlet weak var descriptionLabel: NSTextField!
var extensionPointType: ExtensionPointType?
private weak var hostWindow: NSWindow?
convenience init() {
self.init(windowNibName: NSNib.Name("ExtensionPointEnableBasic"))
}
override func windowDidLoad() {
super.windowDidLoad()
guard let extensionPointType = extensionPointType else { return }
imageView.image = extensionPointType.templateImage
titleLabel.stringValue = extensionPointType.title
descriptionLabel.attributedStringValue = extensionPointType.description
}
// MARK: API
func runSheetOnWindow(_ hostWindow: NSWindow) {
self.hostWindow = hostWindow
hostWindow.beginSheet(window!)
}
// MARK: Actions
@IBAction func cancel(_ sender: Any) {
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.cancel)
}
@IBAction func enable(_ sender: Any) {
guard let extensionPointType = extensionPointType else { return }
switch extensionPointType {
case .marsEdit:
ExtensionPointManager.shared.activateExtensionPoint(ExtensionPointIdentifer.marsEdit)
case .microblog:
ExtensionPointManager.shared.activateExtensionPoint(ExtensionPointIdentifer.microblog)
default:
assertionFailure("Unknown extension point.")
}
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.OK)
}
}

View File

@ -0,0 +1,41 @@
//
// ExtensionPointMarsEditWindowController.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/8/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Cocoa
class ExtensionPointEnableMarsEditWindowController: NSWindowController {
private weak var hostWindow: NSWindow?
convenience init() {
self.init(windowNibName: NSNib.Name("ExtensionPointMarsEdit"))
}
override func windowDidLoad() {
super.windowDidLoad()
}
// MARK: API
func runSheetOnWindow(_ hostWindow: NSWindow) {
self.hostWindow = hostWindow
hostWindow.beginSheet(window!)
}
// MARK: Actions
@IBAction func cancel(_ sender: Any) {
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.cancel)
}
@IBAction func enable(_ sender: Any) {
ExtensionPointManager.shared.activateExtensionPoint(ExtensionPointIdentifer.marsEdit)
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.OK)
}
}

View File

@ -14,22 +14,42 @@ final class ExtensionPointPreferencesViewController: NSViewController {
@IBOutlet weak var detailView: NSView!
@IBOutlet weak var deleteButton: NSButton!
private var sortedAccounts = [String]()
private var activeExtensionPointIDs = [ExtensionPointIdentifer]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
NotificationCenter.default.addObserver(self, selector: #selector(activeExtensionPointsDidChange(_:)), name: .ActiveExtensionPointsDidChange, object: nil)
showController(ExtensionPointAddViewController())
// Fix tableView frame  for some reason IB wants it 1pt wider than the clip view. This leads to unwanted horizontal scrolling.
var rTable = tableView.frame
rTable.size.width = tableView.superview!.frame.size.width
tableView.frame = rTable
activeExtensionPointIDs = Array(ExtensionPointManager.shared.activeExtensionPoints.keys)
tableView.reloadData()
}
@IBAction func enableExtensionPoints(_ sender: Any) {
tableView.selectRowIndexes([], byExtendingSelection: false)
showController(ExtensionPointAddViewController())
}
@IBAction func disableExtensionPoint(_ sender: Any) {
guard tableView.selectedRow != -1 else {
return
}
let extensionPointID = activeExtensionPointIDs[tableView.selectedRow]
ExtensionPointManager.shared.deactivateExtensionPoint(extensionPointID)
showController(ExtensionPointAddViewController())
}
}
// MARK: - NSTableViewDataSource
@ -37,11 +57,11 @@ final class ExtensionPointPreferencesViewController: NSViewController {
extension ExtensionPointPreferencesViewController: NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return sortedAccounts.count
return activeExtensionPointIDs.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return sortedAccounts[row]
return activeExtensionPointIDs[row]
}
}
@ -53,9 +73,9 @@ extension ExtensionPointPreferencesViewController: NSTableViewDelegate {
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "Cell"), owner: nil) as? NSTableCellView {
let account = sortedAccounts[row]
// cell.textField?.stringValue = account.nameForDisplay
// cell.imageView?.image = account.smallIcon?.image
let extensionPointID = activeExtensionPointIDs[row]
cell.textField?.stringValue = extensionPointID.title
cell.imageView?.image = extensionPointID.templateImage
return cell
}
return nil
@ -63,6 +83,17 @@ extension ExtensionPointPreferencesViewController: NSTableViewDelegate {
func tableViewSelectionDidChange(_ notification: Notification) {
let selectedRow = tableView.selectedRow
if tableView.selectedRow == -1 {
deleteButton.isEnabled = false
return
} else {
deleteButton.isEnabled = true
}
let extensionPointID = activeExtensionPointIDs[selectedRow]
let controller = ExtensionPointDetailViewController(extensionPointID: extensionPointID)
showController(controller)
}
@ -72,6 +103,12 @@ extension ExtensionPointPreferencesViewController: NSTableViewDelegate {
private extension ExtensionPointPreferencesViewController {
@objc func activeExtensionPointsDidChange(_ note: Notification) {
activeExtensionPointIDs = Array(ExtensionPointManager.shared.activeExtensionPoints.keys).sorted(by: { $0.title < $1.title })
tableView.reloadData()
showController(ExtensionPointAddViewController())
}
func showController(_ controller: NSViewController) {
if let controller = children.first {

View File

@ -36,9 +36,6 @@
510C43F4243C11FE009F70C3 /* ExtensionPointAddTableCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C43F2243C11FE009F70C3 /* ExtensionPointAddTableCellView.swift */; };
510C43F7243D035C009F70C3 /* ExtensionPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C43F6243D035C009F70C3 /* ExtensionPoint.swift */; };
510C43F8243D035C009F70C3 /* ExtensionPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C43F6243D035C009F70C3 /* ExtensionPoint.swift */; };
510C43F9243D035C009F70C3 /* ExtensionPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C43F6243D035C009F70C3 /* ExtensionPoint.swift */; };
510C43FA243D0445009F70C3 /* SendToMarsEditCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A1500420048DDF0046AD9A /* SendToMarsEditCommand.swift */; };
510C43FB243D0445009F70C3 /* SendToMicroBlogCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */; };
51102165233A7D6C0007A5F7 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */; };
511076F7243BDA8100D97C8C /* FeedProvider.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51107672243BCE0500D97C8C /* FeedProvider.framework */; };
511076F8243BDA8200D97C8C /* FeedProvider.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 51107672243BCE0500D97C8C /* FeedProvider.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@ -121,10 +118,27 @@
51554C31228B71A10055115A /* SyncDatabase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
515A50E6243D07A90089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; };
515A50E7243D07A90089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; };
515A50E8243D07A90089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; };
515A5107243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */; };
515A5108243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */; };
515A5109243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */; };
515A5148243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5147243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift */; };
515A5149243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5147243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift */; };
515A5168243E66910089E588 /* ExtensionPointEnableBasic.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A5167243E66910089E588 /* ExtensionPointEnableBasic.xib */; };
515A5169243E66910089E588 /* ExtensionPointEnableBasic.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A5167243E66910089E588 /* ExtensionPointEnableBasic.xib */; };
515A516E243E7F950089E588 /* ExtensionPointDetail.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A516D243E7F950089E588 /* ExtensionPointDetail.xib */; };
515A516F243E7F950089E588 /* ExtensionPointDetail.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A516D243E7F950089E588 /* ExtensionPointDetail.xib */; };
515A5171243E802B0089E588 /* ExtensionPointDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */; };
515A5172243E802B0089E588 /* ExtensionPointDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */; };
515A5174243E8FEA0089E588 /* ExtensionPointType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5173243E8FEA0089E588 /* ExtensionPointType.swift */; };
515A5175243E8FEA0089E588 /* ExtensionPointType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5173243E8FEA0089E588 /* ExtensionPointType.swift */; };
515A5177243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */; };
515A5178243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */; };
515A517B243E90260089E588 /* ExtensionPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C43F6243D035C009F70C3 /* ExtensionPoint.swift */; };
515A517C243E90260089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; };
515A517D243E90260089E588 /* ExtensionPointType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5173243E8FEA0089E588 /* ExtensionPointType.swift */; };
515A517E243E90260089E588 /* SendToMarsEditCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A1500420048DDF0046AD9A /* SendToMarsEditCommand.swift */; };
515A517F243E90260089E588 /* SendToMicroBlogCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */; };
515A5180243E90260089E588 /* TwitterFeedProvider+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */; };
515A5181243E90260089E588 /* ExtensionPointIdentifer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */; };
515D4FC123257A3200EE1167 /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; };
515D4FCA23257CB500EE1167 /* Node-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97971ED9EFAA007D329B /* Node-Extensions.swift */; };
515D4FCC2325815A00EE1167 /* SafariExt.js in Resources */ = {isa = PBXBuildFile; fileRef = 515D4FCB2325815A00EE1167 /* SafariExt.js */; };
@ -1361,6 +1375,12 @@
51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SyncDatabase.xcodeproj; path = Frameworks/SyncDatabase/SyncDatabase.xcodeproj; sourceTree = SOURCE_ROOT; };
515A50E5243D07A90089E588 /* ExtensionPointManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointManager.swift; sourceTree = "<group>"; };
515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TwitterFeedProvider+Extensions.swift"; sourceTree = "<group>"; };
515A5147243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointEnableBasicWindowController.swift; sourceTree = "<group>"; };
515A5167243E66910089E588 /* ExtensionPointEnableBasic.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtensionPointEnableBasic.xib; sourceTree = "<group>"; };
515A516D243E7F950089E588 /* ExtensionPointDetail.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtensionPointDetail.xib; sourceTree = "<group>"; };
515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointDetailViewController.swift; sourceTree = "<group>"; };
515A5173243E8FEA0089E588 /* ExtensionPointType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointType.swift; sourceTree = "<group>"; };
515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointIdentifer.swift; sourceTree = "<group>"; };
515D4FCB2325815A00EE1167 /* SafariExt.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SafariExt.js; sourceTree = "<group>"; };
515D4FCD2325909200EE1167 /* NetNewsWire_iOS_ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetNewsWire_iOS_ShareExtension.entitlements; sourceTree = "<group>"; };
515D4FCE2325B3D000EE1167 /* NetNewsWire_iOSshareextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSshareextension_target.xcconfig; sourceTree = "<group>"; };
@ -1822,7 +1842,9 @@
isa = PBXGroup;
children = (
510C43F6243D035C009F70C3 /* ExtensionPoint.swift */,
515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */,
515A50E5243D07A90089E588 /* ExtensionPointManager.swift */,
515A5173243E8FEA0089E588 /* ExtensionPointType.swift */,
84A1500420048DDF0046AD9A /* SendToMarsEditCommand.swift */,
84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */,
515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */,
@ -1844,7 +1866,11 @@
510C43EC243C0973009F70C3 /* ExtensionPointAdd.xib */,
510C43F2243C11FE009F70C3 /* ExtensionPointAddTableCellView.swift */,
510C43EF243C0A80009F70C3 /* ExtensionPointAddViewController.swift */,
515A5167243E66910089E588 /* ExtensionPointEnableBasic.xib */,
515A5147243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift */,
51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */,
515A516D243E7F950089E588 /* ExtensionPointDetail.xib */,
515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */,
);
path = ExtensionPoints;
sourceTree = "<group>";
@ -3574,6 +3600,7 @@
65ED4057235DEF6C0081F399 /* AccountsDetail.xib in Resources */,
65ED4058235DEF6C0081F399 /* main.js in Resources */,
65ED40A1235DEFF00081F399 /* container-migration.plist in Resources */,
515A5169243E66910089E588 /* ExtensionPointEnableBasic.xib in Resources */,
65ED4059235DEF6C0081F399 /* AccountsAddLocal.xib in Resources */,
65ED405A235DEF6C0081F399 /* main_mac.js in Resources */,
65ED405B235DEF6C0081F399 /* KeyboardShortcuts.html in Resources */,
@ -3592,6 +3619,7 @@
65ED4068235DEF6C0081F399 /* MainWindow.storyboard in Resources */,
BDCB516824282C8A00102A80 /* AccountsNewsBlur.xib in Resources */,
3B826DCD2385C89600FC1ADB /* AccountsFeedWrangler.xib in Resources */,
515A516F243E7F950089E588 /* ExtensionPointDetail.xib in Resources */,
65ED4069235DEF6C0081F399 /* AccountsReaderAPI.xib in Resources */,
65ED406A235DEF6C0081F399 /* newsfoot.js in Resources */,
5103A9992421643300410853 /* blank.html in Resources */,
@ -3666,6 +3694,7 @@
5144EA362279FC3D00D19003 /* AccountsAddLocal.xib in Resources */,
5142194B2353C1CF00E07E2C /* main_mac.js in Resources */,
84C9FC8C22629E8F00D921D6 /* KeyboardShortcuts.html in Resources */,
515A5168243E66910089E588 /* ExtensionPointEnableBasic.xib in Resources */,
5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */,
844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */,
5103A9F4242258C600410853 /* AccountsAddCloudKit.xib in Resources */,
@ -3686,6 +3715,7 @@
510C43ED243C0973009F70C3 /* ExtensionPointAdd.xib in Resources */,
BDCB516724282C8A00102A80 /* AccountsNewsBlur.xib in Resources */,
5103A9982421643300410853 /* blank.html in Resources */,
515A516E243E7F950089E588 /* ExtensionPointDetail.xib in Resources */,
84BAE64921CEDAF20046DB56 /* CrashReporterWindow.xib in Resources */,
84C9FC8E22629E8F00D921D6 /* Credits.rtf in Resources */,
84BBB12D20142A4700F054F5 /* Inspector.storyboard in Resources */,
@ -3880,7 +3910,9 @@
65ED3FC7235DEF6C0081F399 /* Reachability.swift in Sources */,
65ED3FC8235DEF6C0081F399 /* SidebarCellLayout.swift in Sources */,
65ED3FC9235DEF6C0081F399 /* SmartFeedPasteboardWriter.swift in Sources */,
515A5149243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift in Sources */,
65ED3FCA235DEF6C0081F399 /* SmartFeedsController.swift in Sources */,
515A5178243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */,
65ED3FCB235DEF6C0081F399 /* SidebarViewController.swift in Sources */,
65ED3FCD235DEF6C0081F399 /* SidebarOutlineView.swift in Sources */,
65ED3FCE235DEF6C0081F399 /* DetailKeyboardDelegate.swift in Sources */,
@ -3890,6 +3922,7 @@
65ED3FD2235DEF6C0081F399 /* AccountsAddViewController.swift in Sources */,
65ED3FD3235DEF6C0081F399 /* NSScriptCommand+NetNewsWire.swift in Sources */,
65ED3FD4235DEF6C0081F399 /* Article+Scriptability.swift in Sources */,
515A5172243E802B0089E588 /* ExtensionPointDetailViewController.swift in Sources */,
65ED3FD5235DEF6C0081F399 /* SmartFeed.swift in Sources */,
65ED3FD6235DEF6C0081F399 /* MarkStatusCommand.swift in Sources */,
65ED3FD7235DEF6C0081F399 /* NSApplication+Scriptability.swift in Sources */,
@ -3929,6 +3962,7 @@
65ED3FF7235DEF6C0081F399 /* SearchFeedDelegate.swift in Sources */,
65ED3FF8235DEF6C0081F399 /* ErrorHandler.swift in Sources */,
65ED3FF9235DEF6C0081F399 /* ActivityManager.swift in Sources */,
515A5175243E8FEA0089E588 /* ExtensionPointType.swift in Sources */,
65ED3FFA235DEF6C0081F399 /* WebFeedInspectorViewController.swift in Sources */,
65ED3FFB235DEF6C0081F399 /* AccountsReaderAPIWindowController.swift in Sources */,
65ED3FFC235DEF6C0081F399 /* AccountsAddLocalWindowController.swift in Sources */,
@ -4028,7 +4062,6 @@
512DD4C92430086400C17B1F /* CloudKitAccountViewController.swift in Sources */,
840D617F2029031C009BC708 /* AppDelegate.swift in Sources */,
51236339236915B100951F16 /* RoundedProgressView.swift in Sources */,
510C43F9243D035C009F70C3 /* ExtensionPoint.swift in Sources */,
512E08E72268801200BDCFDD /* WebFeedTreeControllerDelegate.swift in Sources */,
51C452A422650A2D00C03939 /* ArticleUtilities.swift in Sources */,
51EF0F79227716380050506E /* ColorHash.swift in Sources */,
@ -4037,7 +4070,6 @@
B2B80778239C4C7000F191E0 /* RSImage-AppIcons.swift in Sources */,
518ED21D23D0F26000E0A862 /* UIViewController-Extensions.swift in Sources */,
51A9A5F52380F6A60033AADF /* ModalNavigationController.swift in Sources */,
510C43FB243D0445009F70C3 /* SendToMicroBlogCommand.swift in Sources */,
51EAED96231363EF00A9EEE3 /* NonIntrinsicButton.swift in Sources */,
51C4527B2265091600C03939 /* MasterUnreadIndicatorView.swift in Sources */,
5186A635235EF3A800C97195 /* VibrantLabel.swift in Sources */,
@ -4056,7 +4088,6 @@
513146B2235A81A400387FDC /* AddWebFeedIntentHandler.swift in Sources */,
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */,
51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */,
515A5109243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift in Sources */,
51C452A522650A2D00C03939 /* SmallIconProvider.swift in Sources */,
51AB8AB323B7F4C6008F147D /* WebViewController.swift in Sources */,
516A09392360A2AE00EAE89B /* SettingsAccountTableViewCell.swift in Sources */,
@ -4077,7 +4108,6 @@
51EF0F77227716200050506E /* FaviconGenerator.swift in Sources */,
51938DF3231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift in Sources */,
51C4525A226508D600C03939 /* UIStoryboard-Extensions.swift in Sources */,
510C43FA243D0445009F70C3 /* SendToMarsEditCommand.swift in Sources */,
51BB7C272335A8E5008E8144 /* ArticleActivityItemSource.swift in Sources */,
51F85BF52273625800C787DC /* Bundle-Extensions.swift in Sources */,
51C452A622650A3500C03939 /* Node-Extensions.swift in Sources */,
@ -4122,10 +4152,12 @@
C5A6ED6D23C9B0C800AB6BE2 /* UIActivityViewController-Extensions.swift in Sources */,
5108F6D42375EEEF001ABC45 /* TimelinePreviewTableViewController.swift in Sources */,
84CAFCA522BC8C08007694F0 /* FetchRequestQueue.swift in Sources */,
515A517B243E90260089E588 /* ExtensionPoint.swift in Sources */,
51C4529C22650A1000C03939 /* SingleFaviconDownloader.swift in Sources */,
51E595A6228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */,
51F9F3F723DF6DB200A314FD /* ArticleIconSchemeHandler.swift in Sources */,
512AF9C2236ED52C0066F8BE /* ImageHeaderView.swift in Sources */,
515A5181243E90260089E588 /* ExtensionPointIdentifer.swift in Sources */,
51A1699F235E10D700EB091F /* AboutViewController.swift in Sources */,
51C45290226509C100C03939 /* PseudoFeed.swift in Sources */,
51C452A922650DC600C03939 /* ArticleRenderer.swift in Sources */,
@ -4134,6 +4166,7 @@
512E094D2268B8AB00BDCFDD /* DeleteCommand.swift in Sources */,
5110C37D2373A8D100A9C04F /* InspectorIconHeaderView.swift in Sources */,
51F85BFB2275D85000C787DC /* Array-Extensions.swift in Sources */,
515A5180243E90260089E588 /* TwitterFeedProvider+Extensions.swift in Sources */,
51C452AC22650FD200C03939 /* AppNotifications.swift in Sources */,
51EF0F7E2277A57D0050506E /* MasterTimelineAccessibilityCellLayout.swift in Sources */,
51A1699B235E10D700EB091F /* AccountInspectorViewController.swift in Sources */,
@ -4151,9 +4184,10 @@
514219372352510100E07E2C /* ImageScrollView.swift in Sources */,
516AE9B32371C372007DEEAA /* MasterFeedTableViewSectionHeaderLayout.swift in Sources */,
51DC370B2405BC9A0095D371 /* PreloadedWebView.swift in Sources */,
515A50E8243D07A90089E588 /* ExtensionPointManager.swift in Sources */,
515A517D243E90260089E588 /* ExtensionPointType.swift in Sources */,
C5A6ED5223C9AF4300AB6BE2 /* TitleActivityItemSource.swift in Sources */,
51DC37092402F1470095D371 /* MasterFeedDataSourceOperation.swift in Sources */,
515A517E243E90260089E588 /* SendToMarsEditCommand.swift in Sources */,
51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */,
84DEE56622C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */,
512E09012268907400BDCFDD /* MasterFeedTableViewSectionHeader.swift in Sources */,
@ -4167,8 +4201,10 @@
51C452A322650A1E00C03939 /* HTMLMetadataDownloader.swift in Sources */,
51C4528D2265095F00C03939 /* AddFolderViewController.swift in Sources */,
51DC37072402153E0095D371 /* UpdateSelectionOperation.swift in Sources */,
515A517F243E90260089E588 /* SendToMicroBlogCommand.swift in Sources */,
51C452782265091600C03939 /* MasterTimelineCellData.swift in Sources */,
5148F4552336DB7000F8CD8B /* MasterTimelineTitleView.swift in Sources */,
515A517C243E90260089E588 /* ExtensionPointManager.swift in Sources */,
51627A6723861DA3007B3B4B /* MasterFeedViewController+Drag.swift in Sources */,
51FFF0C4235EE8E5002762AA /* VibrantButton.swift in Sources */,
513228FC233037630033D4ED /* Reachability.swift in Sources */,
@ -4189,6 +4225,7 @@
files = (
84F204E01FAACBB30076E152 /* ArticleArray.swift in Sources */,
848B937221C8C5540038DC0D /* CrashReporter.swift in Sources */,
515A5171243E802B0089E588 /* ExtensionPointDetailViewController.swift in Sources */,
847CD6CA232F4CBF00FAC46D /* IconView.swift in Sources */,
84BBB12E20142A4700F054F5 /* InspectorWindowController.swift in Sources */,
51EF0F7A22771B890050506E /* ColorHash.swift in Sources */,
@ -4225,6 +4262,7 @@
849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */,
515A50E6243D07A90089E588 /* ExtensionPointManager.swift in Sources */,
51E595A5228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */,
515A5177243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */,
849A97651ED9EB96007D329B /* WebFeedTreeControllerDelegate.swift in Sources */,
849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */,
51FE10092346739D0056195D /* ActivityType.swift in Sources */,
@ -4262,6 +4300,7 @@
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */,
5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */,
84AD1EAA2031617300BC20B7 /* PasteboardFolder.swift in Sources */,
515A5148243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift in Sources */,
5103A9F724225E4C00410853 /* AccountsAddCloudKitWindowController.swift in Sources */,
5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */,
84AD1EBC2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift in Sources */,
@ -4309,6 +4348,7 @@
510C43F0243C0A80009F70C3 /* ExtensionPointAddViewController.swift in Sources */,
849A97781ED9EC04007D329B /* TimelineCellLayout.swift in Sources */,
84E8E0EB202F693600562D8F /* DetailWebView.swift in Sources */,
515A5174243E8FEA0089E588 /* ExtensionPointType.swift in Sources */,
849A976C1ED9EBC8007D329B /* TimelineTableRowView.swift in Sources */,
849A977B1ED9EC04007D329B /* UnreadIndicatorView.swift in Sources */,
51FA73A72332BE880090D516 /* ExtractedArticle.swift in Sources */,

View File

@ -9,99 +9,6 @@
import Foundation
import RSCore
enum ExtensionPointType {
case marsEdit
case microblog
case twitter
var title: String {
switch self {
case .marsEdit:
return NSLocalizedString("MarsEdit", comment: "MarsEdit")
case .microblog:
return NSLocalizedString("Micro.blog", comment: "Micro.blog")
case .twitter:
return NSLocalizedString("Twitter", comment: "Twitter")
}
}
var templateImage: RSImage {
switch self {
case .marsEdit:
return AppAssets.extensionPointMarsEdit
case .microblog:
return AppAssets.extensionPointMicroblog
case .twitter:
return AppAssets.extensionPointTwitter
}
}
}
enum ExtensionPointIdentifer: Hashable {
case marsEdit
case microblog
case twitter(String)
var title: String {
switch self {
case .marsEdit:
return ExtensionPointType.marsEdit.title
case .microblog:
return ExtensionPointType.microblog.title
case .twitter(let username):
return "\(ExtensionPointType.microblog.title) (\(username))"
}
}
public var userInfo: [AnyHashable: AnyHashable] {
switch self {
case .marsEdit:
return [
"type": "marsEdit"
]
case .microblog:
return [
"type": "microblog"
]
case .twitter(let username):
return [
"type": "feed",
"username": username
]
}
}
public init?(userInfo: [AnyHashable: AnyHashable]) {
guard let type = userInfo["type"] as? String else { return nil }
switch type {
case "marsEdit":
self = ExtensionPointIdentifer.marsEdit
case "microblog":
self = ExtensionPointIdentifer.microblog
case "twitter":
guard let username = userInfo["username"] as? String else { return nil }
self = ExtensionPointIdentifer.twitter(username)
default:
return nil
}
}
public func hash(into hasher: inout Hasher) {
switch self {
case .marsEdit:
hasher.combine("marsEdit")
case .microblog:
hasher.combine("microblog")
case .twitter(let username):
hasher.combine("twitter")
hasher.combine(username)
}
}
}
protocol ExtensionPoint {
var extensionPointType: ExtensionPointType { get }

View File

@ -0,0 +1,92 @@
//
// ExtensionPointIdentifer.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/8/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
import RSCore
enum ExtensionPointIdentifer: Hashable {
case marsEdit
case microblog
case twitter(String)
var title: String {
switch self {
case .marsEdit:
return ExtensionPointType.marsEdit.title
case .microblog:
return ExtensionPointType.microblog.title
case .twitter(let username):
return "\(ExtensionPointType.microblog.title) (\(username))"
}
}
var templateImage: RSImage {
return type.templateImage
}
var description: NSAttributedString {
return type.description
}
var type: ExtensionPointType {
switch self {
case .marsEdit:
return ExtensionPointType.marsEdit
case .microblog:
return ExtensionPointType.microblog
case .twitter:
return ExtensionPointType.twitter
}
}
public var userInfo: [AnyHashable: AnyHashable] {
switch self {
case .marsEdit:
return [
"type": "marsEdit"
]
case .microblog:
return [
"type": "microblog"
]
case .twitter(let username):
return [
"type": "feed",
"username": username
]
}
}
public init?(userInfo: [AnyHashable: AnyHashable]) {
guard let type = userInfo["type"] as? String else { return nil }
switch type {
case "marsEdit":
self = ExtensionPointIdentifer.marsEdit
case "microblog":
self = ExtensionPointIdentifer.microblog
case "twitter":
guard let username = userInfo["username"] as? String else { return nil }
self = ExtensionPointIdentifer.twitter(username)
default:
return nil
}
}
public func hash(into hasher: inout Hasher) {
switch self {
case .marsEdit:
hasher.combine("marsEdit")
case .microblog:
hasher.combine("microblog")
case .twitter(let username):
hasher.combine("twitter")
hasher.combine(username)
}
}
}

View File

@ -10,12 +10,32 @@ import Foundation
import FeedProvider
import RSCore
public extension Notification.Name {
static let ActiveExtensionPointsDidChange = Notification.Name(rawValue: "ActiveExtensionPointsDidChange")
}
final class ExtensionPointManager {
static let shared = ExtensionPointManager()
var activeExtensionPoints = [ExtensionPointIdentifer: ExtensionPoint]()
let availableExtensionPointTypes: [ExtensionPointType]
let possibleExtensionPointTypes: [ExtensionPointType]
var availableExtensionPointTypes: [ExtensionPointType] {
let activeExtensionPointTypes = Set(activeExtensionPoints.keys.compactMap({ $0.type }))
var available = [ExtensionPointType]()
for possibleExtensionPointType in possibleExtensionPointTypes {
if possibleExtensionPointType.isSinglton {
if !activeExtensionPointTypes.contains(possibleExtensionPointType) {
available.append(possibleExtensionPointType)
}
} else {
available.append(possibleExtensionPointType)
}
}
return available
}
var activeSendToCommands: [SendToCommand] {
return activeExtensionPoints.values.compactMap({ return $0 as? SendToCommand })
@ -28,18 +48,18 @@ final class ExtensionPointManager {
init() {
#if os(macOS)
#if DEBUG
availableExtensionPointTypes = [.marsEdit, .microblog, .twitter]
possibleExtensionPointTypes = [.marsEdit, .microblog, .twitter]
#else
availableExtensionPointTypes = [.marsEdit, .microblog, .twitter]
possibleExtensionPointTypes = [.marsEdit, .microblog, .twitter]
#endif
#else
#if DEBUG
availableExtensionPoints = [.twitter]
possibleExtensionPointTypes = [.twitter]
#else
availableExtensionPoints = [.twitter]
possibleExtensionPointTypes = [.twitter]
#endif
#endif
loadExtensionPointIDs()
loadExtensionPoints()
}
func activateExtensionPoint(_ extensionPointID: ExtensionPointIdentifer) {
@ -56,7 +76,7 @@ final class ExtensionPointManager {
private extension ExtensionPointManager {
func loadExtensionPointIDs() {
func loadExtensionPoints() {
if let extensionPointUserInfos = AppDefaults.activeExtensionPointIDs {
for extensionPointUserInfo in extensionPointUserInfos {
if let extensionPointID = ExtensionPointIdentifer(userInfo: extensionPointUserInfo) {
@ -68,6 +88,7 @@ private extension ExtensionPointManager {
func saveExtensionPointIDs() {
AppDefaults.activeExtensionPointIDs = activeExtensionPoints.keys.map({ $0.userInfo })
NotificationCenter.default.post(name: .ActiveExtensionPointsDidChange, object: nil, userInfo: nil)
}
func extensionPoint(for extensionPointID: ExtensionPointIdentifer) -> ExtensionPoint {

View File

@ -2,13 +2,94 @@
// ExtensionPointType.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/7/20.
// Created by Maurice Parker on 4/8/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
import RSCore
enum ExtensionPoint: Int, Codable {
case sentToCommand = 1
case feedProvider = 2
enum ExtensionPointType {
case marsEdit
case microblog
case twitter
var isSinglton: Bool {
switch self {
case .marsEdit, .microblog:
return true
default:
return false
}
}
var title: String {
switch self {
case .marsEdit:
return NSLocalizedString("MarsEdit", comment: "MarsEdit")
case .microblog:
return NSLocalizedString("Micro.blog", comment: "Micro.blog")
case .twitter:
return NSLocalizedString("Twitter", comment: "Twitter")
}
}
var templateImage: RSImage {
switch self {
case .marsEdit:
return AppAssets.extensionPointMarsEdit
case .microblog:
return AppAssets.extensionPointMicroblog
case .twitter:
return AppAssets.extensionPointTwitter
}
}
var description: NSAttributedString {
switch self {
case .marsEdit:
let attrString = makeAttrString("This extension enables share menu functionality to send selected article text to MarsEdit. You need the MarsEdit application for this to work.")
let range = NSRange(location: 81, length: 8)
attrString.beginEditing()
attrString.addAttribute(NSAttributedString.Key.link, value: "https://red-sweater.com/marsedit/", range: range)
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
attrString.endEditing()
return attrString
case .microblog:
let attrString = makeAttrString("This extension enables share menu functionality to send selected article text to Micro.blog. You need the Micro.blog application for this to work.")
let range = NSRange(location: 81, length: 10)
attrString.beginEditing()
attrString.addAttribute(NSAttributedString.Key.link, value: "https://micro.blog", range: range)
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
attrString.endEditing()
return attrString
case .twitter:
let attrString = makeAttrString("This extension enables you to subscribe to Twitter URL's as if they were RSS feeds.")
let range = NSRange(location: 43, length: 7)
attrString.beginEditing()
attrString.addAttribute(NSAttributedString.Key.link, value: "https://twitter.com", range: range)
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
attrString.endEditing()
return attrString
}
}
}
private extension ExtensionPointType {
func makeAttrString(_ text: String) -> NSMutableAttributedString {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attrs = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: NSFont.systemFont(ofSize: NSFont.systemFontSize),
NSAttributedString.Key.foregroundColor: NSColor.textColor
]
return NSMutableAttributedString(string: text, attributes: attrs)
}
}