|  | // 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 "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 "SplashScreenWindowController" | 
|  | } | 
|  |  | 
|  | override func windowDidLoad() { | 
|  | super.windowDidLoad() | 
|  |  | 
|  | splashScreenImageView.image = NSImage(named: "AppIcon") | 
|  |  | 
|  | 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 | 
|  | } | 
|  | } |