// // Menulet.swift // XCode Perforce // // Created by Rob Crawford on 8/26/16. // Copyright © 2016 Rob Crawford. All rights reserved. // import Cocoa class Menulet: NSObject, NSMenuDelegate { let p4InfoMenuItem = 0 let p4EditMenuItem = 1 let p4AddMenuItem = 2 let p4RevertMenuItem = 3 let p4SubmitMenuItem = 4 let p4SyncMenuItem = 5 let p4ForceSyncMenuItem = 6 var p4Functionatlity: P4Functionality = P4Functionality() var p4Icon: NSImage? @IBOutlet weak var preferencesWindow: NSWindow! @IBOutlet weak var p4PathEditBox: NSTextField! @IBOutlet weak var p4vPathEditBox: NSTextField! var statusItem:NSStatusItem! @IBOutlet weak var menu: NSMenu! @IBAction func p4info(_ sender: AnyObject) { let currentDoc = XCodeHelper.currentProjectURL() if currentDoc == nil { return } if p4Functionatlity.p4ClientSet() == true { let filePath = XCodeHelper.pathToCurrentDocument() as NSString let parentFolder = filePath.deletingLastPathComponent var resultMessage = p4Functionatlity.issueP4Info(forFolder: parentFolder) if resultMessage.isEmpty { resultMessage = "Error detected while attempting to query p4 info" } displayCustomAlertBox("p4 info", informativeText: resultMessage as NSString) } else { displayDefaultP4NotSetError() } } @IBAction func p4List(_ sender: AnyObject) { let currentDoc = XCodeHelper.currentProjectURL() if currentDoc == nil { return } if p4Functionatlity.p4ClientSet() == true { let resultList = p4Functionatlity.p4Opened() var resultMessage=""; if (!(resultList?.isEmpty)!) { for path in resultList! { resultMessage = resultMessage + (path as! String) + "\n" } } if resultMessage.isEmpty { resultMessage = "Error detected while attempting to query p4 info" } displayCustomAlertBox("p4 info", informativeText: resultMessage as NSString) } else { displayDefaultP4NotSetError() } } func p4editFile(_ filePath: String) { let currentDoc = XCodeHelper.currentProjectURL() if currentDoc == nil { return } if p4Functionatlity.p4ClientSet() == true { // let filePath = XCodeHelper.pathToCurrentDocument() let resultMessage = p4Functionatlity.issueP4Edit(forFile: filePath) displayCustomAlertBox("p4 edit", informativeText: resultMessage as NSString) } else { displayDefaultP4NotSetError() } } @IBAction func p4edit(_ sender: AnyObject) { let currentDoc = XCodeHelper.currentProjectURL() if currentDoc == nil { return } if p4Functionatlity.p4ClientSet() == true { if !XCodeHelper.doesCurrentDocumentNeedSave() { let filePath = XCodeHelper.pathToCurrentDocument() let resultMessage = p4Functionatlity.issueP4Edit(forFile: filePath!) displayCustomAlertBox("p4 edit", informativeText: resultMessage as NSString) } else { displayCurrentFileHasNotBeenSavedError(); } } else { displayDefaultP4NotSetError() } } @IBAction func p4add(_ sender: AnyObject) { let currentDoc = XCodeHelper.currentProjectURL() if currentDoc == nil { return } if p4Functionatlity.p4ClientSet() == true { if !XCodeHelper.doesCurrentDocumentNeedSave() { let filePath = XCodeHelper.pathToCurrentDocument() let resultMessage = p4Functionatlity.issueP4Add(forFile: filePath!) displayCustomAlertBox("p4 add", informativeText: resultMessage as NSString) } else { displayCurrentFileHasNotBeenSavedError(); } } else { displayDefaultP4NotSetError() } } @IBAction func p4revert(_ sender: AnyObject) { let currentDoc = XCodeHelper.currentProjectURL() if currentDoc == nil { return } if p4Functionatlity.p4ClientSet() == true { if !XCodeHelper.doesCurrentDocumentNeedSave() { let a = NSAlert() let fileName: NSString = XCodeHelper.pathToCurrentDocument() as! NSString a.addButton(withTitle: "Cancel") a.addButton(withTitle: "Revert") a.messageText = "p4 revert"; a.informativeText = "Are you sure you want to revert " + fileName.lastPathComponent + ", this is not undoable." if p4Icon != nil { a.icon = p4Icon } let response = a.runModal(); if (response == NSAlertSecondButtonReturn) { let filePath = XCodeHelper.pathToCurrentDocument() let resultMessage = p4Functionatlity.issueP4Revert(forFile: filePath!) displayCustomAlertBox("p4 revert", informativeText: resultMessage as NSString) } } else { displayCurrentFileHasNotBeenSavedError(); } } else { displayDefaultP4NotSetError() } } func p4sync(_ sender: AnyObject, forceSync:Bool) { let currentDoc = XCodeHelper.currentProjectURL() if currentDoc == nil { return } var response = NSAlertSecondButtonReturn var fileName: NSString = "" if p4Functionatlity.p4ClientSet() == true { if !XCodeHelper.doesCurrentDocumentNeedSave() { if forceSync == true { let a = NSAlert() fileName = XCodeHelper.pathToCurrentDocument() as! NSString a.addButton(withTitle: "Cancel") a.addButton(withTitle: "Sync") a.messageText = "p4 sync"; a.informativeText = "Are you sure you want to force sync:" + fileName.lastPathComponent + " this will clober any changes that have been made, this is not undoable." if p4Icon != nil { a.icon = p4Icon } response = a.runModal(); } if (response == NSAlertSecondButtonReturn) { let resultMessage = p4Functionatlity.issueP4Sync(forFile: fileName as String, forceSync:forceSync ) var message = "p4 sync" if forceSync { message = "p4 -f sync" } if forceSync { displayCustomAlertBox(message as NSString, informativeText: resultMessage as NSString) } } } else { displayCurrentFileHasNotBeenSavedError(); } } else { displayDefaultP4NotSetError() } } @IBAction func p4sync(_ sender: AnyObject) { p4sync(sender, forceSync: false) } @IBAction func p4forceSync(_ sender: AnyObject) { p4sync(sender, forceSync: true) } @IBAction func p4submit(_ sender: AnyObject) { let currentDoc = XCodeHelper.currentProjectURL() if currentDoc == nil { return } if p4Functionatlity.p4ClientSet() == true { if !XCodeHelper.doesCurrentDocumentNeedSave() { let a = NSAlert() let fileName: NSString = XCodeHelper.pathToCurrentDocument() as! NSString a.messageText = "Submit file: " + fileName.lastPathComponent; a.informativeText = "Please Enter Submit Comment:" a.addButton(withTitle: "Submit") a.addButton(withTitle: "Cancel") if p4Icon != nil { a.icon = p4Icon } let inputTextField = NSTextView(frame: NSRect(x: 0, y: 0, width: 300, height: 24*4)) a.accessoryView = inputTextField let response = a.runModal(); if response == NSAlertFirstButtonReturn { let enteredString = inputTextField.string if (!(enteredString?.isEmpty)!) { let filePath = XCodeHelper.pathToCurrentDocument() let resultMessage = p4Functionatlity.issueP4Submit(forFile: filePath!, withDescription: enteredString!) displayCustomAlertBox("p4 Submit", informativeText: resultMessage as NSString) } else { displayCustomAlertBox("p4 Submit", informativeText: "p4 Submit requires a description!") } } } else { displayCurrentFileHasNotBeenSavedError(); } } else { displayDefaultP4NotSetError() } } func installStatusItem() { if (statusItem == nil) { statusItem = NSStatusBar.system().statusItem(withLength: NSVariableStatusItemLength) statusItem.highlightMode = true statusItem.isEnabled = true statusItem.toolTip = "XCode Perforce" statusItem.title = "" statusItem.menu = menu; let myImage = NSImage.init(named: "AppIcon") myImage!.size = NSMakeSize(16.0, 16.0) statusItem.image = myImage p4Icon = myImage } } override func awakeFromNib() { installStatusItem() } func displayCustomAlertBox(_ messageText:NSString?, informativeText:NSString?) { let alertBox = NSAlert() alertBox.messageText = (messageText as! String) alertBox.informativeText = (informativeText as! String) if p4Icon != nil { alertBox.icon = p4Icon } alertBox.runModal() } func displayDefaultP4NotSetError() { var errorMessage = "" if p4Functionatlity.p4Installed == false { errorMessage = "The p4 command line app is not installed" } if p4Functionatlity.p4vcInstalled == false { if errorMessage.isEmpty == false { errorMessage += "\n" } errorMessage += "The p4vc command line app is not installed" } if p4Functionatlity.p4CONFIG_Set == false { if errorMessage.isEmpty == false { errorMessage += "\n" } errorMessage += "The P4CONFIG environment variable is not set" } displayCustomAlertBox("Error", informativeText: errorMessage as NSString) } func displayCurrentFileHasNotBeenSavedError() { displayCustomAlertBox("Error", informativeText: "The Current Document has been modifed but not saved, please save and run again.") } @IBAction func preferencesCancel(_ sender: AnyObject) { preferencesWindow.orderOut(NSApplication.shared()) NSApplication.shared().stopModal() } @IBAction func preferencesOK(_ sender: AnyObject) { let p4path = self.p4PathEditBox.stringValue let p4vcpath = self.p4vPathEditBox.stringValue if p4path.characters.count != 0{ UserDefaults.standard.set(p4path, forKey: "P4PATH") } if p4vcpath.characters.count != 0 { UserDefaults.standard.set(p4vcpath, forKey: "P4VCPATH") } UserDefaults.standard.synchronize() p4Functionatlity.updateP4Status() p4Functionatlity.updateP4VCStatus() preferencesWindow.orderOut(NSApplication.shared()) NSApplication.shared().stopModal() } @IBAction func doPreferences(_ sender: AnyObject) { self.p4PathEditBox.stringValue = UserDefaults.standard.string(forKey: "P4PATH")! self.p4vPathEditBox.stringValue = UserDefaults.standard.string(forKey: "P4VCPATH")! preferencesWindow.center() preferencesWindow.makeKeyAndOrderFront(NSApplication.shared()); NSApplication.shared().runModal(for: preferencesWindow); } func menuNeedsUpdate(_ menu: NSMenu) { var menuEnabled:Bool = false; let runningApps = NSWorkspace.shared().runningApplications let aeApp = runningApps.filter( { ($0.bundleIdentifier != nil) && ($0.bundleIdentifier! == "com.apple.dt.Xcode") }).first if aeApp != nil { menuEnabled = true; } if menuEnabled == true { if p4Functionatlity.p4ClientSet() == false { menuEnabled = false; } } // if (menuEnabled == true) { // let fileList = p4Functionatlity.p4Opened() as NSArray // let filePath = XCodeHelper.pathToCurrentDocument() as NSString // for index in 0...7 { // let myItem:NSMenuItem = menu.itemArray[index]; // myItem.enabled = menuEnabled; // } // // if fileList.containsObject(filePath) { // menu.itemArray[p4EditMenuItem].enabled = false; // } // else { // menu.itemArray[p4RevertMenuItem].enabled = false; // menu.itemArray[p4SubmitMenuItem].enabled = false; // } // } // else // { for index in 0...7 { let myItem:NSMenuItem = menu.items[index]; myItem.isEnabled = menuEnabled; } // } } }