diff --git a/Boop/Boop/AppDelegate.swift b/Boop/Boop/AppDelegate.swift
index bff23474..94899a9e 100644
--- a/Boop/Boop/AppDelegate.swift
+++ b/Boop/Boop/AppDelegate.swift
@@ -17,8 +17,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var closePickerMenuItem: NSMenuItem!
@IBOutlet weak var popoverViewController: PopoverViewController!
+ @IBOutlet weak var mainViewController: MainViewController!
@IBOutlet weak var scriptManager: ScriptManager!
@IBOutlet weak var editor: SyntaxTextView!
+ @IBOutlet weak var statusView: StatusView!
// Frame auto save name for app window frame restoration.
private static let appWindowName = "boop.app.window"
@@ -42,6 +44,18 @@ class AppDelegate: NSObject, NSApplicationDelegate {
return true
}
+ func application(_ sender: NSApplication, openFile filename: String) -> Bool {
+
+ let text=try? String(contentsOf: URL(fileURLWithPath: filename))
+
+ if text == nil {
+ self.statusView.setStatus(.error("Failed to load file: '\(filename)'."))
+ } else {
+ editor.text = text!
+ }
+ return true
+ }
+
@IBAction func showPreferencesWindow(_ sender: NSMenuItem) {
let controller = NSStoryboard.init(name: "Preferences", bundle: nil).instantiateInitialController() as? NSWindowController
diff --git a/Boop/Boop/Boop.entitlements b/Boop/Boop/Boop.entitlements
index 6abec674..09dedc8e 100644
--- a/Boop/Boop/Boop.entitlements
+++ b/Boop/Boop/Boop.entitlements
@@ -10,5 +10,7 @@
com.apple.security.network.client
+ com.apple.security.files.user-selected.read-write
+
diff --git a/Boop/Boop/BoopRelease.entitlements b/Boop/Boop/BoopRelease.entitlements
index 6abec674..09dedc8e 100644
--- a/Boop/Boop/BoopRelease.entitlements
+++ b/Boop/Boop/BoopRelease.entitlements
@@ -10,5 +10,7 @@
com.apple.security.network.client
+ com.apple.security.files.user-selected.read-write
+
diff --git a/Boop/Boop/Controllers/MainViewController.swift b/Boop/Boop/Controllers/MainViewController.swift
index 762b7f49..48cb72dc 100644
--- a/Boop/Boop/Controllers/MainViewController.swift
+++ b/Boop/Boop/Controllers/MainViewController.swift
@@ -10,7 +10,8 @@ import Cocoa
import SavannaKit
class MainViewController: NSViewController {
-
+
+ @IBOutlet weak var statusView: StatusView!
@IBOutlet weak var editorView: SyntaxTextView!
@IBOutlet weak var updateBuddy: UpdateBuddy!
@IBOutlet weak var checkUpdateMenuItem: NSMenuItem!
@@ -67,6 +68,54 @@ class MainViewController: NSViewController {
@IBAction func checkForUpdates(_ sender: Any) {
updateBuddy.check()
}
+
+ @IBAction func openFile(sender: AnyObject) {
+
+ let dialog = NSOpenPanel();
+
+ dialog.title = "Choose a file";
+ dialog.showsResizeIndicator = true;
+ dialog.showsHiddenFiles = false;
+ dialog.canChooseDirectories = false;
+ dialog.canCreateDirectories = false;
+ dialog.allowsMultipleSelection = false;
+
+ if (dialog.runModal() == NSApplication.ModalResponse.OK) {
+ if let pathUrl = dialog.url { // Pathname of the file
+ let text=try? String(contentsOf: pathUrl)
+
+ if text == nil {
+ self.statusView.setStatus(.error("Failed to load file: '\(pathUrl.path)'."))
+ } else {
+ editorView.text = text!
+ }
+ }
+ }
+ }
+
+ @IBAction func saveFileAs(sender: AnyObject) {
+
+ let dialog = NSSavePanel();
+
+ dialog.title = "Save content as…";
+ dialog.showsResizeIndicator = true;
+ dialog.showsHiddenFiles = false;
+ dialog.showsTagField = false;
+ dialog.canCreateDirectories = true;
+ dialog.nameFieldStringValue = "Untitled.txt"
+
+ if (dialog.runModal() == NSApplication.ModalResponse.OK) {
+ if let pathUrl = dialog.url { // Pathname of the file
+ let textView = editorView.contentTextView
+ let textData=textView.textStorage?.string.data(using: .utf8)
+ do {
+ try textData?.write(to: pathUrl)
+ } catch let error as NSError {
+ self.statusView.setStatus(.error("Failed to save content to file '\(pathUrl.path)'. (Reason: \(error.localizedFailureReason!))"))
+ }
+ }
+ }
+ }
}
extension MainViewController: SyntaxTextViewDelegate {
diff --git a/Boop/Boop/Info.plist b/Boop/Boop/Info.plist
index 5753c31a..82199edc 100644
--- a/Boop/Boop/Info.plist
+++ b/Boop/Boop/Info.plist
@@ -28,6 +28,17 @@
MainMenu
NSPrincipalClass
NSApplication
+ CFBundleDocumentTypes
+
+
+ CFBundleTypeRole
+ Viewer
+ CFBundleTypeExtensions
+
+ *
+
+
+
NSServices
diff --git a/Boop/Boop/System/Models/Script.swift b/Boop/Boop/System/Models/Script.swift
index eaa3b1ba..8d00f492 100644
--- a/Boop/Boop/System/Models/Script.swift
+++ b/Boop/Boop/System/Models/Script.swift
@@ -97,7 +97,7 @@ extension Script: Fuseable {
}
}
-protocol ScriptDelegate: class {
+protocol ScriptDelegate: AnyObject {
func onScriptError(message: String)
func onScriptInfo(message: String)
}
diff --git a/Boop/UI/Base.lproj/MainMenu.xib b/Boop/UI/Base.lproj/MainMenu.xib
index f132c070..20005497 100644
--- a/Boop/UI/Base.lproj/MainMenu.xib
+++ b/Boop/UI/Base.lproj/MainMenu.xib
@@ -1,8 +1,8 @@
-
+
-
+
@@ -27,6 +27,7 @@
+
@@ -58,6 +59,7 @@
+
@@ -123,14 +125,9 @@
-
-
@@ -509,7 +512,7 @@ Gw
-
+