| // Copyright 2016 The Tulsi Authors. All rights reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| import Cocoa | |
| /// View controller for the "recent document" rows in the tableview in the splash screen. | |
| final class SplashScreenRecentDocumentViewController : NSViewController { | |
| @IBOutlet weak var icon : NSImageView! | |
| @IBOutlet weak var filename : NSTextField! | |
| @IBOutlet weak var path: NSTextField! | |
| var url: URL? | |
| override var nibName: NSNib.Name? { | |
| return NSNib.Name(rawValue: "SplashScreenRecentDocumentView") | |
| } | |
| override func viewDidLoad() { | |
| guard let url = url else { return } | |
| icon.image = NSWorkspace.shared.icon(forFile: url.path) | |
| filename.stringValue = (url.lastPathComponent as NSString).deletingPathExtension | |
| path.stringValue = ((url.path as NSString).deletingLastPathComponent as NSString).abbreviatingWithTildeInPath | |
| } | |
| } | |
| /// Window controller for the splash screen. | |
| final class SplashScreenWindowController: NSWindowController, NSTableViewDelegate, NSTableViewDataSource { | |
| @IBOutlet var recentDocumentsArrayController: NSArrayController! | |
| @IBOutlet weak var splashScreenImageView: NSImageView! | |
| @objc dynamic var applicationVersion: String = "" | |
| @objc dynamic var recentDocumentViewControllers = [SplashScreenRecentDocumentViewController]() | |
| override var windowNibName: NSNib.Name? { | |
| return NSNib.Name(rawValue: "SplashScreenWindowController") | |
| } | |
| override func windowDidLoad() { | |
| super.windowDidLoad() | |
| splashScreenImageView.image = NSApplication.shared.applicationIconImage | |
| if let cfBundleVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { | |
| applicationVersion = cfBundleVersion | |
| } | |
| recentDocumentViewControllers = getRecentDocumentViewControllers() | |
| } | |
| @IBAction func createNewDocument(_ sender: NSButton) { | |
| let documentController = NSDocumentController.shared | |
| do { | |
| try documentController.openUntitledDocumentAndDisplay(true) | |
| } catch let e as NSError { | |
| let alert = NSAlert() | |
| alert.messageText = e.localizedFailureReason ?? e.localizedDescription | |
| alert.informativeText = e.localizedRecoverySuggestion ?? "" | |
| alert.runModal() | |
| } | |
| } | |
| @IBAction func didDoubleClickRecentDocument(_ sender: NSTableView) { | |
| let clickedRow = sender.clickedRow | |
| guard clickedRow >= 0 else { return } | |
| let documentController = NSDocumentController.shared | |
| let viewController = recentDocumentViewControllers[clickedRow] | |
| guard let url = viewController.url else { return } | |
| documentController.openDocument(withContentsOf: url, display: true) { | |
| (_: NSDocument?, _: Bool, _: Error?) in | |
| } | |
| } | |
| func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { | |
| return recentDocumentViewControllers[row].view | |
| } | |
| func numberOfRows(in tableView: NSTableView) -> Int { | |
| return recentDocumentViewControllers.count | |
| } | |
| // MARK: - Private methods | |
| private func getRecentDocumentViewControllers() -> [SplashScreenRecentDocumentViewController] { | |
| let projectExtension = TulsiProjectDocument.getTulsiBundleExtension() | |
| let documentController = NSDocumentController.shared | |
| var recentDocumentViewControllers = [SplashScreenRecentDocumentViewController]() | |
| var recentDocumentURLs = Set<URL>() | |
| let fileManager = FileManager.default | |
| for url in documentController.recentDocumentURLs { | |
| let path = url.path | |
| guard path.contains(projectExtension) else { continue } | |
| if !fileManager.isReadableFile(atPath: path) { | |
| continue | |
| } | |
| var components: [String] = url.pathComponents | |
| var i = components.count - 1 | |
| repeat { | |
| if (components[i] as NSString).pathExtension == projectExtension { | |
| break | |
| } | |
| i -= 1 | |
| } while i > 0 | |
| let projectURL: URL | |
| if i == components.count - 1 { | |
| projectURL = url | |
| } else { | |
| let projectComponents = [String](components.prefix(i + 1)) | |
| projectURL = NSURL.fileURL(withPathComponents: projectComponents)! as URL | |
| } | |
| if (recentDocumentURLs.contains(projectURL)) { | |
| continue; | |
| } | |
| recentDocumentURLs.insert(projectURL); | |
| let viewController = SplashScreenRecentDocumentViewController() | |
| viewController.url = projectURL; | |
| recentDocumentViewControllers.append(viewController) | |
| } | |
| return recentDocumentViewControllers | |
| } | |
| } |