Browse Source

near 1.5.0

tags/v1.5.0
boB Rudis 5 years ago
parent
commit
6d92394a89
No known key found for this signature in database GPG Key ID: 1D7529BE14E2BBA9
  1. 4
      RSwitch.xcodeproj/project.pbxproj
  2. 15
      RSwitch/Base.lproj/Main.storyboard
  3. 12
      RSwitch/Swift/AppDelegate.swift
  4. 57
      RSwitch/Swift/Menu.swift
  5. 1
      RSwitch/Swift/MenuActions/RStudioServerAction.swift
  6. 15
      RSwitch/Swift/NewSessionViewController.swift
  7. 2
      RSwitch/Swift/Notify.swift
  8. 27
      RSwitch/Swift/Utils/Preferences.swift

4
RSwitch.xcodeproj/project.pbxproj

@ -542,7 +542,7 @@
"$(PROJECT_DIR)/RSwitch/ObjC/ProcInfo", "$(PROJECT_DIR)/RSwitch/ObjC/ProcInfo",
); );
MACOSX_DEPLOYMENT_TARGET = 10.14; MACOSX_DEPLOYMENT_TARGET = 10.14;
MARKETING_VERSION = 1.4.2; MARKETING_VERSION = 1.5.0;
PRODUCT_BUNDLE_IDENTIFIER = is.rud.bob.RSwitch; PRODUCT_BUNDLE_IDENTIFIER = is.rud.bob.RSwitch;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -575,7 +575,7 @@
"$(PROJECT_DIR)/RSwitch/ObjC/ProcInfo", "$(PROJECT_DIR)/RSwitch/ObjC/ProcInfo",
); );
MACOSX_DEPLOYMENT_TARGET = 10.14; MACOSX_DEPLOYMENT_TARGET = 10.14;
MARKETING_VERSION = 1.4.2; MARKETING_VERSION = 1.5.0;
PRODUCT_BUNDLE_IDENTIFIER = is.rud.bob.RSwitch; PRODUCT_BUNDLE_IDENTIFIER = is.rud.bob.RSwitch;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

15
RSwitch/Base.lproj/Main.storyboard

@ -730,7 +730,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundTextured" title="Delete Session" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mLg-dJ-21p"> <buttonCell key="cell" type="roundTextured" title="Delete Session" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mLg-dJ-21p">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="message"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
<connections> <connections>
<action selector="deletePressed:" target="qjv-aN-QDU" id="diI-k3-yQA"/> <action selector="deletePressed:" target="qjv-aN-QDU" id="diI-k3-yQA"/>
@ -822,7 +822,7 @@
<rect key="frame" x="185" y="91" width="275" height="21"/> <rect key="frame" x="185" y="91" width="275" height="21"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="cva-Md-d45"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="cva-Md-d45">
<font key="font" metaFont="message"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
@ -831,7 +831,7 @@
<rect key="frame" x="185" y="56" width="275" height="21"/> <rect key="frame" x="185" y="56" width="275" height="21"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="zy1-gA-fJN"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="zy1-gA-fJN">
<font key="font" metaFont="message"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
@ -841,7 +841,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="VDj-IV-qlo"> <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="VDj-IV-qlo">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="message"/> <font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES"> <string key="keyEquivalent" base64-UTF8="YES">
Gw Gw
</string> </string>
@ -855,7 +855,7 @@ Gw
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mlc-6J-XMQ"> <buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mlc-6J-XMQ">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="message"/> <font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES"> <string key="keyEquivalent" base64-UTF8="YES">
DQ DQ
</string> </string>
@ -948,7 +948,7 @@ DQ
<attributedString key="textStorage"> <attributedString key="textStorage">
<fragment> <fragment>
<string key="content"> <string key="content">
RSwitch v1.4.2 RSwitch v1.5.0
Copyright © 2019 Bob Rudis Copyright © 2019 Bob Rudis
@ -982,7 +982,8 @@ Cgo
<fragment> <fragment>
<string key="content">dial app icon by IconMark from the Noun Project <string key="content">dial app icon by IconMark from the Noun Project
String+Version by DragonCherry String+Version by DragonCherry
ProcInfo by Patrick Wardle </string> ProcInfo by Patrick Wardle
Just by Daniel Duan</string>
<attributes> <attributes>
<color key="NSColor" name="systemBlueColor" catalog="System" colorSpace="catalog"/> <color key="NSColor" name="systemBlueColor" catalog="System" colorSpace="catalog"/>
<font key="NSFont" size="11" name="HelveticaNeue"/> <font key="NSFont" size="11" name="HelveticaNeue"/>

12
RSwitch/Swift/AppDelegate.swift

@ -26,8 +26,16 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSToolbarDelegate {
NSApp.activate(ignoringOtherApps: true) NSApp.activate(ignoringOtherApps: true)
} }
@objc func performRStudioCheck(_ sender: NSObject) {
let v = RStudioUtils.latestVersionNumber()
if (!Preferences.lastVersionNotified.isVersion(equalTo: v)) {
Preferences.lastVersionNotified = v
notifyUser(title: "New RStudio Daily version available", text: ("Version: " + v))
}
}
@objc func performTimer(_ sender: Timer) { @objc func performTimer(_ sender: Timer) {
print("timer fired") if (Preferences.hourlyRStudioCheck) { performRStudioCheck(sender) }
} }
var mainStoryboard: NSStoryboard! var mainStoryboard: NSStoryboard!
@ -69,7 +77,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSToolbarDelegate {
} }
func applicationDidFinishLaunching(_ aNotification: Notification) { func applicationDidFinishLaunching(_ aNotification: Notification) {
// dial by IconMark from the Noun Project // dial by IconMark from the Noun Project
statusItem.button?.image = #imageLiteral(resourceName: "RSwitch") statusItem.button?.image = #imageLiteral(resourceName: "RSwitch")
statusItem.menu = statusMenu statusItem.menu = statusMenu

57
RSwitch/Swift/Menu.swift

@ -22,6 +22,18 @@ extension AppDelegate: NSMenuDelegate {
} }
} }
@objc func toggle_hourly_rstudio_check(_ sender: NSMenuItem) {
Preferences.hourlyRStudioCheck = !Preferences.hourlyRStudioCheck
if (Preferences.hourlyRStudioCheck) { performRStudioCheck(sender) }
if let menu = statusItem.menu, let item = menu.item(withTag: 98) {
item.state = Preferences.hourlyRStudioCheck.stateValue
}
}
func menuWillOpen(_ menu: NSMenu) { func menuWillOpen(_ menu: NSMenu) {
@ -52,16 +64,21 @@ extension AppDelegate: NSMenuDelegate {
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
let refsDropdown = NSMenuItem(title: "Reference Desk", action: nil, keyEquivalent: "")
let refsSub = NSMenu()
menu.addItem(refsDropdown)
menu.setSubmenu(refsSub, for: refsDropdown)
// Add items to open various R for macOS pages // Add items to open various R for macOS pages
BrowseMenuAction.populateWebItems(menu: menu) BrowseMenuAction.populateWebItems(menu: refsSub)
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
// Add links to local copies of the R Manuals // Add links to local copies of the R Manuals
BrowseMenuAction.populateLocalRManualsItems(menu: menu) BrowseMenuAction.populateLocalRManualsItems(menu: refsSub)
// Add links to free R online books // Add links to free R online books
BrowseMenuAction.populateRBooksItems(menu: menu) BrowseMenuAction.populateRBooksItems(menu: refsSub)
// Add running apps // Add running apps
populateRunningApps(menu: menu) populateRunningApps(menu: menu)
@ -71,22 +88,32 @@ extension AppDelegate: NSMenuDelegate {
RStudioServerMenuAction.populateRStudioServerSessions(menu: menu, manager: sess) RStudioServerMenuAction.populateRStudioServerSessions(menu: menu, manager: sess)
// Add a Check for update
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: "Check for update…", action: #selector(checkForUpdate), keyEquivalent: ""))
// Add an About item
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: "About RSwitch…", action: #selector(showAbout), keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "RSwitch Help…", action: #selector(rswitch_help), keyEquivalent: ""))
// Toggle Dock Icon // Toggle Dock Icon
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
let item = NSMenuItem(title: "Toggle Dock Icon", action: #selector(toggle_dock_icon), keyEquivalent: "")
item.tag = 99 let prefsDropdown = NSMenuItem(title: "Preferences", action: nil, keyEquivalent: "")
item.target = self let prefSub = NSMenu()
item.state = Preferences.showDockIcon.stateValue
menu.addItem(item) menu.addItem(prefsDropdown)
menu.setSubmenu(prefSub, for: prefsDropdown)
let dockItem = NSMenuItem(title: "Show Dock Icon", action: #selector(toggle_dock_icon), keyEquivalent: "")
dockItem.tag = 99
dockItem.target = self
dockItem.state = Preferences.showDockIcon.stateValue
prefSub.addItem(dockItem)
let rstudioCheckItem = NSMenuItem(title: "Notify me when a new RStudio Daily is available", action: #selector(toggle_hourly_rstudio_check), keyEquivalent: "")
rstudioCheckItem.tag = 98
rstudioCheckItem.target = self
rstudioCheckItem.state = Preferences.hourlyRStudioCheck.stateValue
prefSub.addItem(rstudioCheckItem)
menu.addItem(NSMenuItem(title: "Check for update…", action: #selector(checkForUpdate), keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "About RSwitch…", action: #selector(showAbout), keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "RSwitch Help…", action: #selector(rswitch_help), keyEquivalent: ""))
// Add a Quit item // Add a Quit item
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())

1
RSwitch/Swift/MenuActions/RStudioServerAction.swift

@ -18,7 +18,6 @@ extension AppDelegate {
} }
@objc func activateServerSession(_ sender: NSMenuItem) { @objc func activateServerSession(_ sender: NSMenuItem) {
print("activate Session")
let sess = (sender.representedObject as! RStudioServerSession) let sess = (sender.representedObject as! RStudioServerSession)
sess.show() sess.show()
} }

15
RSwitch/Swift/NewSessionViewController.swift

@ -37,9 +37,18 @@ class NewSessionViewController: NSViewController {
@IBAction func cancelPressed(_ sender: Any) { @IBAction func cancelPressed(_ sender: Any) {
self.view.window?.windowController?.close() self.view.window?.windowController?.close()
} }
override func viewWillAppear() {
nickname.stringValue = ""
serverURL.stringValue = "https://"
super.viewDidAppear()
}
override func viewDidLoad() { override func viewDidLoad() {
print("VIEW IS LOADING")
super.viewDidLoad() super.viewDidLoad()
nickname.delegate = self nickname.delegate = self
@ -61,9 +70,7 @@ extension NewSessionViewController : NSTextFieldDelegate {
let currNames = appDelegate.sess.sessions!.map { let currNames = appDelegate.sess.sessions!.map {
$0.menuTitle $0.menuTitle
} }
print(currNames)
let nickUnique = !(currNames.firstIndex(of: nick) != nil) let nickUnique = !(currNames.firstIndex(of: nick) != nil)
okButton.isEnabled = ((nick.count > 0) && nickUnique && sURL.isValidURL) okButton.isEnabled = ((nick.count > 0) && nickUnique && sURL.isValidURL)

2
RSwitch/Swift/Notify.swift

@ -11,7 +11,7 @@ import Cocoa
extension AppDelegate : NSUserNotificationCenterDelegate { extension AppDelegate : NSUserNotificationCenterDelegate {
func notifyUser(title: String? = nil, subtitle: String? = nil, text: String? = nil) -> Void { func notifyUser(title: String? = nil, subtitle: String? = nil, text: String? = nil) -> Void {
let notification = NSUserNotification() let notification = NSUserNotification()

27
RSwitch/Swift/Utils/Preferences.swift

@ -20,7 +20,9 @@ extension UserDefaults {
enum Key: String { enum Key: String {
case showDockIcon = "showDockIcon" case showDockIcon = "showDockIcon"
case hourlyRStudioCheck = "hourlyRStudioCheck"
case firstRunGone = "firstRunGone" case firstRunGone = "firstRunGone"
case lastVersionNotified = ""
} }
func set<T>(_ value: T, forKey key: Key) { set(value, forKey: key.rawValue) } func set<T>(_ value: T, forKey key: Key) { set(value, forKey: key.rawValue) }
@ -50,6 +52,14 @@ struct DockIcon {
struct Preferences { struct Preferences {
static var hourlyRStudioCheck: Bool {
get { return(defaults.bool(forKey: .hourlyRStudioCheck)) }
set {
defaults.set(newValue, forKey: .hourlyRStudioCheck)
defaults.synchronize()
}
}
static var showDockIcon: Bool { static var showDockIcon: Bool {
get { return(defaults.bool(forKey: .showDockIcon)) } get { return(defaults.bool(forKey: .showDockIcon)) }
set { set {
@ -66,7 +76,22 @@ struct Preferences {
} }
} }
static func restore() { Preferences.showDockIcon = false } static var lastVersionNotified : String {
get {
let x = defaults.string(forKey: .lastVersionNotified)
return((x == nil) ? "" : x!)
}
set {
defaults.set(newValue, forKey: .lastVersionNotified)
defaults.synchronize()
}
}
static func restore() {
Preferences.showDockIcon = false
Preferences.hourlyRStudioCheck = false
Preferences.lastVersionNotified = ""
}
} }

Loading…
Cancel
Save