Restore two-step process for OPML exporting.
This commit is contained in:
parent
1c06eb27e8
commit
f8376b807a
|
@ -57,7 +57,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
|||
private var addFeedController: AddFeedController?
|
||||
private var addFolderWindowController: AddFolderWindowController?
|
||||
private var importOPMLController: ImportOPMLWindowController?
|
||||
private var exportOPMLController: ExportOPMLController?
|
||||
private var exportOPMLController: ExportOPMLWindowController?
|
||||
private var keyboardShortcutsWindowController: WebViewWindowController?
|
||||
private var inspectorWindowController: InspectorWindowController?
|
||||
private var crashReportWindowController: CrashReportWindowController? // For testing only
|
||||
|
@ -438,7 +438,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
|||
return
|
||||
}
|
||||
|
||||
exportOPMLController = ExportOPMLController()
|
||||
exportOPMLController = ExportOPMLWindowController()
|
||||
exportOPMLController?.runSheetOnWindow(mainWindowController!.window!)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15400" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15400"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="ExportOPMLAccessoryViewController" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="accountPopUpButton" destination="bK0-BJ-siH" id="jce-mY-Lnu"/>
|
||||
<outlet property="view" destination="c22-O7-iKe" id="F7r-Bu-0DA"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="c22-O7-iKe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="481" height="127"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="lED-IQ-gZC">
|
||||
<rect key="frame" x="67" y="20" width="347" height="87"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="56R-DT-OD3">
|
||||
<rect key="frame" x="-2" y="3" width="63" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Account:" id="qLW-sa-J1x">
|
||||
<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="bK0-BJ-siH" userLabel="Account Popup">
|
||||
<rect key="frame" x="65" y="-3" width="285" 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="9GQ-mj-Tcp" id="oI2-rj-A5N">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="J4i-mi-ts0">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="9GQ-mj-Tcp"/>
|
||||
<menuItem title="Item 2" id="ngU-na-xcU"/>
|
||||
<menuItem title="Item 3" id="20Y-AP-vVO"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="accountSelected:" target="-2" id="lQN-hm-7Cz"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="xQI-ze-ZFc">
|
||||
<rect key="frame" x="-2" y="39" width="351" height="48"/>
|
||||
<textFieldCell key="cell" selectable="YES" id="q1a-Rk-oL6">
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="title">Choose the account with the subscriptions you’d like to export. Subscriptions are exported in the standard OPML format, which most RSS readers can import.</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="xQI-ze-ZFc" secondAttribute="trailing" id="6MA-XB-o9x"/>
|
||||
<constraint firstItem="xQI-ze-ZFc" firstAttribute="leading" secondItem="lED-IQ-gZC" secondAttribute="leading" id="8x9-3N-8Jg"/>
|
||||
<constraint firstItem="bK0-BJ-siH" firstAttribute="leading" secondItem="56R-DT-OD3" secondAttribute="trailing" constant="8" symbolic="YES" id="AW6-Od-DFn"/>
|
||||
<constraint firstItem="56R-DT-OD3" firstAttribute="top" secondItem="xQI-ze-ZFc" secondAttribute="bottom" constant="20" id="MLg-wk-R1I"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bK0-BJ-siH" secondAttribute="trailing" id="MVl-Gh-JDy"/>
|
||||
<constraint firstItem="bK0-BJ-siH" firstAttribute="firstBaseline" secondItem="56R-DT-OD3" secondAttribute="firstBaseline" id="Njd-pZ-Q9q"/>
|
||||
<constraint firstItem="56R-DT-OD3" firstAttribute="leading" secondItem="lED-IQ-gZC" secondAttribute="leading" id="O48-xY-l3w"/>
|
||||
<constraint firstItem="xQI-ze-ZFc" firstAttribute="top" secondItem="lED-IQ-gZC" secondAttribute="top" id="TYW-C0-9VM"/>
|
||||
<constraint firstAttribute="bottom" secondItem="bK0-BJ-siH" secondAttribute="bottom" id="Uas-t1-rR1"/>
|
||||
<constraint firstAttribute="width" constant="347" id="cOZ-Ot-MMd"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="lED-IQ-gZC" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="c22-O7-iKe" secondAttribute="leading" constant="20" symbolic="YES" id="0F9-Th-uQH"/>
|
||||
<constraint firstItem="lED-IQ-gZC" firstAttribute="centerX" secondItem="c22-O7-iKe" secondAttribute="centerX" id="3jU-jT-k8m"/>
|
||||
<constraint firstItem="lED-IQ-gZC" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" constant="20" id="908-Vf-gWh"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="xQI-ze-ZFc" secondAttribute="trailing" id="9c9-5Z-2j3"/>
|
||||
<constraint firstAttribute="bottom" secondItem="lED-IQ-gZC" secondAttribute="bottom" constant="20" id="ppg-6J-6ti"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="139" y="194"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
|
@ -1,62 +0,0 @@
|
|||
//
|
||||
// ExportOPMLAccessoryViewController.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Nate Weaver on 2019-10-20.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import Account
|
||||
|
||||
protocol ExportOPMLAccessoryViewControllerDelegate: class {
|
||||
func selectedAccountDidChange(_ accessoryViewController: ExportOPMLAccessoryViewController)
|
||||
}
|
||||
|
||||
class ExportOPMLAccessoryViewController: NSViewController {
|
||||
|
||||
@IBOutlet weak var accountPopUpButton: NSPopUpButton!
|
||||
weak var delegate: ExportOPMLAccessoryViewControllerDelegate?
|
||||
|
||||
var selectedAccount: Account? {
|
||||
accountPopUpButton.selectedItem?.representedObject as? Account
|
||||
}
|
||||
|
||||
init(delegate: ExportOPMLAccessoryViewControllerDelegate) {
|
||||
super.init(nibName: "ExportOPMLAccessoryView", bundle: nil)
|
||||
self.delegate = delegate
|
||||
}
|
||||
|
||||
init() {
|
||||
preconditionFailure("init() without delegate not implemented by design.")
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
preconditionFailure("ExportOPMLAccessoryView.init(coder) not implemented by design.")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
accountPopUpButton.removeAllItems()
|
||||
|
||||
let menu = NSMenu()
|
||||
accountPopUpButton.menu = menu
|
||||
|
||||
for oneAccount in AccountManager.shared.sortedAccounts {
|
||||
|
||||
let oneMenuItem = NSMenuItem()
|
||||
oneMenuItem.title = oneAccount.nameForDisplay
|
||||
oneMenuItem.representedObject = oneAccount
|
||||
menu.addItem(oneMenuItem)
|
||||
|
||||
if oneAccount.accountID == AppDefaults.exportOPMLAccountID {
|
||||
accountPopUpButton.select(oneMenuItem)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func accountSelected(_ popUpButton: NSPopUpButton) {
|
||||
delegate!.selectedAccountDidChange(self)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
//
|
||||
// ExportOPMLController.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 5/1/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import Account
|
||||
|
||||
class ExportOPMLController {
|
||||
|
||||
weak var savePanel: NSSavePanel?
|
||||
|
||||
func runSheetOnWindow(_ hostWindow: NSWindow) {
|
||||
|
||||
let accessoryViewController = ExportOPMLAccessoryViewController(delegate: self)
|
||||
let panel = NSSavePanel()
|
||||
panel.allowedFileTypes = ["opml"]
|
||||
panel.allowsOtherFileTypes = false
|
||||
panel.prompt = NSLocalizedString("Export OPML", comment: "Export OPML")
|
||||
panel.title = NSLocalizedString("Export OPML", comment: "Export OPML")
|
||||
panel.nameFieldLabel = NSLocalizedString("Export to:", comment: "Export OPML")
|
||||
panel.message = NSLocalizedString("Choose a location for the exported OPML file.", comment: "Export OPML")
|
||||
panel.isExtensionHidden = false
|
||||
panel.accessoryView = accessoryViewController.view
|
||||
|
||||
updateNameFieldStringValueIfAppropriate(savePanel: panel, from: accessoryViewController, force: true)
|
||||
|
||||
savePanel = panel
|
||||
|
||||
panel.beginSheetModal(for: hostWindow) { result in
|
||||
if result == NSApplication.ModalResponse.OK, let url = panel.url {
|
||||
DispatchQueue.main.async {
|
||||
guard let account = accessoryViewController.selectedAccount else {
|
||||
return
|
||||
}
|
||||
let filename = url.lastPathComponent
|
||||
let opmlString = OPMLExporter.OPMLString(with: account, title: filename)
|
||||
do {
|
||||
try opmlString.write(to: url, atomically: true, encoding: .utf8)
|
||||
}
|
||||
catch let error as NSError {
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ExportOPMLController: ExportOPMLAccessoryViewControllerDelegate {
|
||||
|
||||
func selectedAccountDidChange(_ accessoryViewController: ExportOPMLAccessoryViewController) {
|
||||
if let savePanel = savePanel {
|
||||
self.updateNameFieldStringValueIfAppropriate(savePanel: savePanel, from: accessoryViewController)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension ExportOPMLController {
|
||||
|
||||
func updateNameFieldStringValueIfAppropriate(savePanel panel: NSSavePanel, from accessoryViewController: ExportOPMLAccessoryViewController, force: Bool = false) {
|
||||
|
||||
if !force && !panel.nameFieldStringValue.hasPrefix("Subscriptions-") {
|
||||
return
|
||||
}
|
||||
|
||||
guard let account = accessoryViewController.selectedAccount else {
|
||||
return
|
||||
}
|
||||
let accountName = account.nameForDisplay.replacingOccurrences(of: " ", with: "").trimmingCharacters(in: .whitespaces)
|
||||
panel.nameFieldStringValue = "Subscriptions-\(accountName).opml"
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="ExportOPMLWindowController" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="accountPopUpButton" destination="bbC-2g-e3k" id="sK9-0j-WyF"/>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="Z1E-pd-3QE"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="355" height="180"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" wantsLayer="YES" misplaced="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="391" height="171"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="mvx-54-DH0">
|
||||
<rect key="frame" x="18" y="100" width="355" height="51"/>
|
||||
<textFieldCell key="cell" selectable="YES" id="7Ap-KG-Lc7">
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="title">Choose the account with the subscriptions you’d like to export. Subscriptions are exported in the standard OPML format, which most RSS readers can import.</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xJz-HU-L4i">
|
||||
<rect key="frame" x="18" y="63" width="63" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Account:" id="Dao-jI-G6i">
|
||||
<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="bbC-2g-e3k" userLabel="Account Popup">
|
||||
<rect key="frame" x="85" y="58" width="289" 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="MJb-Bf-UJG" id="xZd-AP-nuM">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="TP8-jd-M1D">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="MJb-Bf-UJG"/>
|
||||
<menuItem title="Item 2" id="7U3-Y5-qeM"/>
|
||||
<menuItem title="Item 3" id="Uii-dd-siy"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<button horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eZ4-Ej-Hks">
|
||||
<rect key="frame" x="229" y="13" width="148" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Export as OPML…" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bRz-cx-bmm">
|
||||
<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="exportOPML:" target="-2" id="Lcs-Xm-HfK"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PPB-R8-A9a">
|
||||
<rect key="frame" x="81" y="13" width="148" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6lK-bV-Vwd">
|
||||
<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="oun-pb-pQs"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="mvx-54-DH0" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="6SB-1X-jS4"/>
|
||||
<constraint firstItem="xJz-HU-L4i" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="8TB-fT-THB"/>
|
||||
<constraint firstItem="PPB-R8-A9a" firstAttribute="leading" secondItem="bbC-2g-e3k" secondAttribute="leading" id="9zJ-1D-4cz"/>
|
||||
<constraint firstAttribute="bottom" secondItem="eZ4-Ej-Hks" secondAttribute="bottom" constant="20" symbolic="YES" id="ES8-CX-Cvn"/>
|
||||
<constraint firstItem="bbC-2g-e3k" firstAttribute="leading" secondItem="xJz-HU-L4i" secondAttribute="trailing" constant="8" symbolic="YES" id="IAs-Eg-vxH"/>
|
||||
<constraint firstItem="eZ4-Ej-Hks" firstAttribute="top" secondItem="bbC-2g-e3k" secondAttribute="bottom" constant="20" symbolic="YES" id="KLL-J1-sDN"/>
|
||||
<constraint firstItem="eZ4-Ej-Hks" firstAttribute="leading" secondItem="PPB-R8-A9a" secondAttribute="trailing" constant="12" symbolic="YES" id="Lfs-g3-crb"/>
|
||||
<constraint firstItem="PPB-R8-A9a" firstAttribute="centerY" secondItem="eZ4-Ej-Hks" secondAttribute="centerY" id="OVP-4p-nXp"/>
|
||||
<constraint firstAttribute="trailing" secondItem="eZ4-Ej-Hks" secondAttribute="trailing" constant="20" symbolic="YES" id="RDU-0d-O0Q"/>
|
||||
<constraint firstItem="xJz-HU-L4i" firstAttribute="top" secondItem="mvx-54-DH0" secondAttribute="bottom" constant="20" id="Rxj-lF-b8R"/>
|
||||
<constraint firstItem="bbC-2g-e3k" firstAttribute="firstBaseline" secondItem="xJz-HU-L4i" secondAttribute="firstBaseline" id="TjR-gN-xrt"/>
|
||||
<constraint firstAttribute="trailing" secondItem="mvx-54-DH0" secondAttribute="trailing" constant="20" symbolic="YES" id="VBk-HZ-2xv"/>
|
||||
<constraint firstItem="eZ4-Ej-Hks" firstAttribute="width" secondItem="PPB-R8-A9a" secondAttribute="width" id="WOT-NI-xD8"/>
|
||||
<constraint firstItem="mvx-54-DH0" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="l2i-jP-HX1"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bbC-2g-e3k" secondAttribute="trailing" constant="20" symbolic="YES" id="uZb-X0-fUh"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<point key="canvasLocation" x="81.5" y="102"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// ExportOPMLWindowController.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 5/1/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import Account
|
||||
|
||||
class ExportOPMLWindowController: NSWindowController {
|
||||
|
||||
@IBOutlet weak var accountPopUpButton: NSPopUpButton!
|
||||
private weak var hostWindow: NSWindow?
|
||||
|
||||
convenience init() {
|
||||
self.init(windowNibName: NSNib.Name("ExportOPMLSheet"))
|
||||
}
|
||||
|
||||
override func windowDidLoad() {
|
||||
accountPopUpButton.removeAllItems()
|
||||
|
||||
let menu = NSMenu()
|
||||
accountPopUpButton.menu = menu
|
||||
|
||||
for oneAccount in AccountManager.shared.sortedAccounts {
|
||||
|
||||
let oneMenuItem = NSMenuItem()
|
||||
oneMenuItem.title = oneAccount.nameForDisplay
|
||||
oneMenuItem.representedObject = oneAccount
|
||||
menu.addItem(oneMenuItem)
|
||||
|
||||
if oneAccount.accountID == AppDefaults.exportOPMLAccountID {
|
||||
accountPopUpButton.select(oneMenuItem)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: API
|
||||
|
||||
func runSheetOnWindow(_ hostWindow: NSWindow) {
|
||||
|
||||
self.hostWindow = hostWindow
|
||||
|
||||
if AccountManager.shared.accounts.count == 1 {
|
||||
let account = AccountManager.shared.accounts.first!
|
||||
exportOPML(account: account)
|
||||
} else {
|
||||
hostWindow.beginSheet(window!)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Actions
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.cancel)
|
||||
}
|
||||
|
||||
@IBAction func exportOPML(_ sender: Any) {
|
||||
|
||||
guard let menuItem = accountPopUpButton.selectedItem else {
|
||||
return
|
||||
}
|
||||
|
||||
let account = menuItem.representedObject as! Account
|
||||
AppDefaults.exportOPMLAccountID = account.accountID
|
||||
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
exportOPML(account: account)
|
||||
|
||||
}
|
||||
|
||||
func exportOPML(account: Account) {
|
||||
|
||||
let panel = NSSavePanel()
|
||||
panel.allowedFileTypes = ["opml"]
|
||||
panel.allowsOtherFileTypes = false
|
||||
panel.prompt = NSLocalizedString("Export OPML", comment: "Export OPML")
|
||||
panel.title = NSLocalizedString("Export OPML", comment: "Export OPML")
|
||||
panel.nameFieldLabel = NSLocalizedString("Export to:", comment: "Export OPML")
|
||||
panel.message = NSLocalizedString("Choose a location for the exported OPML file.", comment: "Export OPML")
|
||||
panel.isExtensionHidden = false
|
||||
|
||||
let accountName = account.nameForDisplay.replacingOccurrences(of: " ", with: "").trimmingCharacters(in: .whitespaces)
|
||||
panel.nameFieldStringValue = "Subscriptions-\(accountName).opml"
|
||||
|
||||
panel.beginSheetModal(for: hostWindow!) { result in
|
||||
if result == NSApplication.ModalResponse.OK, let url = panel.url {
|
||||
DispatchQueue.main.async {
|
||||
let filename = url.lastPathComponent
|
||||
let opmlString = OPMLExporter.OPMLString(with: account, title: filename)
|
||||
do {
|
||||
try opmlString.write(to: url, atomically: true, encoding: String.Encoding.utf8)
|
||||
}
|
||||
catch let error as NSError {
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,6 @@
|
|||
5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA372279FC6200D19003 /* AccountsAddLocalWindowController.swift */; };
|
||||
5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */; };
|
||||
5144EA40227A37EC00D19003 /* ImportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */; };
|
||||
5144EA43227A380F00D19003 /* ExportOPMLController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA42227A380F00D19003 /* ExportOPMLController.swift */; };
|
||||
5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */; };
|
||||
5144EA52227B8E4500D19003 /* AccountsFeedbin.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */; };
|
||||
51543685228F6753005E1CDF /* DetailAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51543684228F6753005E1CDF /* DetailAccountViewController.swift */; };
|
||||
|
@ -231,6 +230,8 @@
|
|||
849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A979E1ED9F130007D329B /* SidebarCell.swift */; };
|
||||
849A97A31ED9F180007D329B /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; };
|
||||
849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 849C64671ED37A5D003D8FC0 /* Assets.xcassets */; };
|
||||
849C78902362AAFC009A71E4 /* ExportOPMLSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 849C78872362AAFB009A71E4 /* ExportOPMLSheet.xib */; };
|
||||
849C78922362AB04009A71E4 /* ExportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C78912362AB04009A71E4 /* ExportOPMLWindowController.swift */; };
|
||||
849EE70F203919360082A1EA /* AppAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE70E203919360082A1EA /* AppAssets.swift */; };
|
||||
849EE72120391F560082A1EA /* SharingServicePickerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */; };
|
||||
84A14FF320048CA70046AD9A /* SendToMicroBlogCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */; };
|
||||
|
@ -312,8 +313,6 @@
|
|||
84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; };
|
||||
84FB9A301EDCD6C4003D53B9 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */; };
|
||||
B24C4F7B235D39D40000B924 /* ExportOPMLAccessoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B24C4F7A235D39D40000B924 /* ExportOPMLAccessoryViewController.swift */; };
|
||||
B24C4F85235D39F30000B924 /* ExportOPMLAccessoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B24C4F84235D39F30000B924 /* ExportOPMLAccessoryView.xib */; };
|
||||
D553738B20186C20006D8857 /* Article+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553737C20186C1F006D8857 /* Article+Scriptability.swift */; };
|
||||
D57BE6E0204CD35F00D11AAC /* NSScriptCommand+NetNewsWire.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57BE6DF204CD35F00D11AAC /* NSScriptCommand+NetNewsWire.swift */; };
|
||||
D5907D7F2004AC00005947E5 /* NSApplication+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */; };
|
||||
|
@ -687,7 +686,6 @@
|
|||
5144EA372279FC6200D19003 /* AccountsAddLocalWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsAddLocalWindowController.swift; sourceTree = "<group>"; };
|
||||
5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ImportOPMLSheet.xib; sourceTree = "<group>"; };
|
||||
5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportOPMLWindowController.swift; sourceTree = "<group>"; };
|
||||
5144EA42227A380F00D19003 /* ExportOPMLController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportOPMLController.swift; sourceTree = "<group>"; };
|
||||
5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsFeedbinWindowController.swift; sourceTree = "<group>"; };
|
||||
5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsFeedbin.xib; sourceTree = "<group>"; };
|
||||
51543684228F6753005E1CDF /* DetailAccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailAccountViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -850,6 +848,8 @@
|
|||
849C64601ED37A5D003D8FC0 /* NetNewsWire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetNewsWire.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
849C64671ED37A5D003D8FC0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
849C64711ED37A5D003D8FC0 /* NetNewsWireTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NetNewsWireTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
849C78872362AAFB009A71E4 /* ExportOPMLSheet.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ExportOPMLSheet.xib; sourceTree = "<group>"; };
|
||||
849C78912362AB04009A71E4 /* ExportOPMLWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExportOPMLWindowController.swift; sourceTree = "<group>"; };
|
||||
849EE70E203919360082A1EA /* AppAssets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAssets.swift; sourceTree = "<group>"; };
|
||||
849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServicePickerDelegate.swift; sourceTree = "<group>"; };
|
||||
84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToMicroBlogCommand.swift; sourceTree = "<group>"; };
|
||||
|
@ -925,8 +925,6 @@
|
|||
84F9EAE4213660A100CF2DE4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Frameworks/Vendor/Sparkle.framework; sourceTree = SOURCE_ROOT; };
|
||||
84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaviconURLFinder.swift; sourceTree = "<group>"; };
|
||||
B24C4F7A235D39D40000B924 /* ExportOPMLAccessoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportOPMLAccessoryViewController.swift; sourceTree = "<group>"; };
|
||||
B24C4F84235D39F30000B924 /* ExportOPMLAccessoryView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExportOPMLAccessoryView.xib; sourceTree = "<group>"; };
|
||||
B24EFD482330FF99006C6242 /* NetNewsWire-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NetNewsWire-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
B24EFD5923310109006C6242 /* WKPreferencesPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKPreferencesPrivate.h; sourceTree = "<group>"; };
|
||||
D553737C20186C1F006D8857 /* Article+Scriptability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Article+Scriptability.swift"; sourceTree = "<group>"; };
|
||||
|
@ -1037,9 +1035,8 @@
|
|||
children = (
|
||||
5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */,
|
||||
5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */,
|
||||
5144EA42227A380F00D19003 /* ExportOPMLController.swift */,
|
||||
B24C4F7A235D39D40000B924 /* ExportOPMLAccessoryViewController.swift */,
|
||||
B24C4F84235D39F30000B924 /* ExportOPMLAccessoryView.xib */,
|
||||
849C78872362AAFB009A71E4 /* ExportOPMLSheet.xib */,
|
||||
849C78912362AB04009A71E4 /* ExportOPMLWindowController.swift */,
|
||||
);
|
||||
path = OPML;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1992,12 +1989,12 @@
|
|||
ORGANIZATIONNAME = "Ranchero Software";
|
||||
TargetAttributes = {
|
||||
6581C73220CED60000F4AD34 = {
|
||||
DevelopmentTeam = M72QZ9W58G;
|
||||
ProvisioningStyle = Automatic;
|
||||
DevelopmentTeam = M8L2WTLA8W;
|
||||
ProvisioningStyle = Manual;
|
||||
};
|
||||
840D617B2029031C009BC708 = {
|
||||
CreatedOnToolsVersion = 9.3;
|
||||
DevelopmentTeam = M72QZ9W58G;
|
||||
DevelopmentTeam = M8L2WTLA8W;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.BackgroundModes = {
|
||||
|
@ -2013,8 +2010,8 @@
|
|||
};
|
||||
849C645F1ED37A5D003D8FC0 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
DevelopmentTeam = M72QZ9W58G;
|
||||
ProvisioningStyle = Automatic;
|
||||
DevelopmentTeam = M8L2WTLA8W;
|
||||
ProvisioningStyle = Manual;
|
||||
SystemCapabilities = {
|
||||
com.apple.HardenedRuntime = {
|
||||
enabled = 1;
|
||||
|
@ -2023,7 +2020,7 @@
|
|||
};
|
||||
849C64701ED37A5D003D8FC0 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
DevelopmentTeam = M72QZ9W58G;
|
||||
DevelopmentTeam = 9C84TZ7Q6Z;
|
||||
ProvisioningStyle = Automatic;
|
||||
TestTargetID = 849C645F1ED37A5D003D8FC0;
|
||||
};
|
||||
|
@ -2289,8 +2286,8 @@
|
|||
5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */,
|
||||
844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */,
|
||||
84A3EE5F223B667F00557320 /* DefaultFeeds.opml in Resources */,
|
||||
B24C4F85235D39F30000B924 /* ExportOPMLAccessoryView.xib in Resources */,
|
||||
8459D0F92355794C0050076F /* NNW3OpenPanelAccessoryView.xib in Resources */,
|
||||
849C78902362AAFC009A71E4 /* ExportOPMLSheet.xib in Resources */,
|
||||
84C9FC8222629E4800D921D6 /* Preferences.storyboard in Resources */,
|
||||
849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */,
|
||||
848362FD2262A30800DA1D35 /* styleSheet.css in Resources */,
|
||||
|
@ -2479,6 +2476,7 @@
|
|||
84F2D53A1FC2308B00998D64 /* UnreadFeed.swift in Sources */,
|
||||
845A29221FC9251E007B49E3 /* SidebarCellLayout.swift in Sources */,
|
||||
84AD1EBA2031649C00BC20B7 /* SmartFeedPasteboardWriter.swift in Sources */,
|
||||
849C78922362AB04009A71E4 /* ExportOPMLWindowController.swift in Sources */,
|
||||
84CC88181FE59CBF00644329 /* SmartFeedsController.swift in Sources */,
|
||||
849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */,
|
||||
849A97641ED9EB96007D329B /* SidebarOutlineView.swift in Sources */,
|
||||
|
@ -2500,7 +2498,6 @@
|
|||
849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */,
|
||||
840BEE4121D70E64009BBAFA /* CrashReportWindowController.swift in Sources */,
|
||||
8426118A1FCB67AA0086A189 /* FeedIconDownloader.swift in Sources */,
|
||||
B24C4F7B235D39D40000B924 /* ExportOPMLAccessoryViewController.swift in Sources */,
|
||||
84C9FC7B22629E1200D921D6 /* AccountsControlsBackgroundView.swift in Sources */,
|
||||
84162A152038C12C00035290 /* MarkCommandValidationStatus.swift in Sources */,
|
||||
84E95D241FB1087500552D99 /* ArticlePasteboardWriter.swift in Sources */,
|
||||
|
@ -2511,7 +2508,6 @@
|
|||
849A97891ED9ECEF007D329B /* ArticleStyle.swift in Sources */,
|
||||
84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */,
|
||||
84B7178C201E66580091657D /* SidebarViewController+ContextualMenus.swift in Sources */,
|
||||
5144EA43227A380F00D19003 /* ExportOPMLController.swift in Sources */,
|
||||
842611A21FCB769D0086A189 /* RSHTMLMetadata+Extension.swift in Sources */,
|
||||
84A1500520048DDF0046AD9A /* SendToMarsEditCommand.swift in Sources */,
|
||||
D5907DB22004BB37005947E5 /* ScriptingObjectContainer.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue