XcodePerforcePlugin.swift #7

  • //
  • guest/
  • jaime_rios/
  • XcodePerforcePlugin/
  • XcodePerforcePlugin/
  • XcodePerforcePlugin.swift
  • View
  • Commits
  • Open Download .zip Download (11 KB)
// Created by Jaime O. Rios

import AppKit

var sharedPlugin: XcodePerforcePlugin?

class XcodePerforcePlugin: NSObject
{
    var bundle: NSBundle
    var p4Functionatlity: P4Functionality = P4Functionality()
    var pathForIconResource: NSString?
    var p4Icon: NSImage?

    init(bundle: NSBundle)
    {
        self.bundle = bundle

        super.init()
    
        let myPlugin = NSBundle(forClass: XcodePerforcePlugin.self)
        pathForIconResource = myPlugin.pathForResource("plugin_icons", ofType:"icns")
        
        if(pathForIconResource != nil)
        {
            p4Icon = NSImage(contentsOfFile: pathForIconResource! as String)
        }
        
        createMenuItems()
    }

    deinit
    {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    func createMenuItems()
    {
        var item = NSApp.mainMenu!!.itemWithTitle("Source Control")
        if item != nil
        {
            p4SettingsSetUpMenu(item)
            p4InfoSetUpMenu(item)
            p4EditSetUpMenu(item)
            p4AddSetUpMenu(item)
            p4RevertSetUpMenu(item)
            p4vcRevGraphSetUpMenu(item)
            p4vcTimeLapseSetUpMenu(item)
            //p4MergeDiffSetUpMenu(item)
        }
    }

    func p4SettingsSetUpMenu(let item : NSMenuItem?)
    {
        var menuItem = NSMenuItem(title:"Perforce plugin settings", action:"p4Settings", keyEquivalent:"")
        menuItem.target = self
        item!.submenu!.addItem(NSMenuItem.separatorItem())
        item!.submenu!.addItem(menuItem)
    }
    
    func p4Settings()
    {
        p4Functionatlity.checkSettings()
        var attr          = p4Functionatlity.p4Installed

        let p4Installed   = String("p4 installed: \t" + (attr ? "YES": "NO") + "\n")

        var value         = p4Functionatlity.p4Path
        var valueStr      = (value != nil ? value : "Unknown")
        let p4Path        = String("p4 path: \t\t" + valueStr + "\n")

        attr              = p4Functionatlity.p4vcInstalled
        let p4vcInstalled = String("p4vc installed: \t" + (attr ? "YES": "NO") + "\n")

        value             = p4Functionatlity.p4vcPath
        valueStr          = (value != nil ? value : "Unknown")
        let p4vcPath      = String("p4vc path: \t" + valueStr + "\n")

        attr              = p4Functionatlity.P4CONFIG_Set
        let p4ConfigSet   = String("P4CONFIG set: " + (attr ? "YES": "NO") + "\n")

        value             = p4Functionatlity.p4ClientName
        let p4ClientName  = String("P4CLIENT name: " + value + "\n")
        
        let combinedString = p4Installed + p4Path + p4vcInstalled + p4vcPath + p4ConfigSet + p4ClientName
        displayCustomAlertBox("Perforce plugin settings", informativeText: combinedString)
    }
    
    
    // MARK: -
    func p4EditSetUpMenu(let item : NSMenuItem?)
    {
        var menuItem    = NSMenuItem(title:"p4 - edit", action:"p4Edit", keyEquivalent:"")
        menuItem.target = self
        item!.submenu!.addItem(menuItem)
    }
    
    /**
    Precondition(s):
    - valid filepath
    - p4 command line app installed
    - P4CONFIG environment variable set
    */
    func p4Edit()
    {
        let currentDoc = getCurrentXcodeDocument()
        if(currentDoc.result == false)
        {
            return
        }
        
        if (p4Functionatlity.p4ClientSet() == true)
        {
            let filePath             = currentDoc.document?.fileURL?.path
            let resultMessage        = p4Functionatlity.issueP4EditForFile(filePath)
            displayCustomAlertBox("p4 edit", informativeText: resultMessage)
        }
        else
        {
            displayDefaultP4NotSetError()
        }
    }
    
    func p4AddSetUpMenu(let item : NSMenuItem?)
    {
        var menuItem = NSMenuItem(title:"p4 - add", action:"p4Add", keyEquivalent:"")
        menuItem.target = self
        item!.submenu!.addItem(menuItem)
    }
    
    func p4Add()
    {
        let currentDoc = getCurrentXcodeDocument()
        if(currentDoc.result == false)
        {
            return
        }
        
        if (p4Functionatlity.p4ClientSet() == true)
        {
            let filePath             = currentDoc.document?.fileURL?.path
            let resultMessage        = p4Functionatlity.issueP4AddForFile(filePath)

            displayCustomAlertBox("p4 add", informativeText: resultMessage)
        }
        else
        {
            displayDefaultP4NotSetError()
        }
    }
    
    func p4RevertSetUpMenu(let item : NSMenuItem?)
    {
        var menuItem = NSMenuItem(title:"p4 - revert", action:"p4Revert", keyEquivalent:"")
        menuItem.target = self
        item!.submenu!.addItem(menuItem)
    }
    
    func p4Revert()
    {
        let currentDoc = getCurrentXcodeDocument()
        if(currentDoc.result == false)
        {
            return
        }
        
        if (p4Functionatlity.p4ClientSet() == true)
        {
            let filePath             = currentDoc.document?.fileURL?.path
            let resultMessage        = p4Functionatlity.issueP4RevertForFile(filePath)
            displayCustomAlertBox("p4 revert", informativeText: resultMessage)
        }
        else
        {
            displayDefaultP4NotSetError()
        }
    }
    
    func p4InfoSetUpMenu(let item : NSMenuItem?)
    {
        var menuItem = NSMenuItem(title:"p4 - info", action:"p4Info", keyEquivalent:"")
        menuItem.target = self
        item!.submenu!.addItem(menuItem)
    }
    
    /**
    Precondition(s):
    - Plugin is able to query the current file that is in focus within
    Xcode 
    -- The parent folder is used as part of the 'p4 info' command call
    
    Postcondition(s):
    - p4 info message for current file's parent folder
    
    */
    func p4Info()
    {
        let currentDoc = getCurrentXcodeDocument()
        if(currentDoc.result == false)
        {
            return
        }
        
        if (p4Functionatlity.p4ClientSet() == true)
        {
            let filePath             = currentDoc.document?.fileURL?.path
            let parentFolder         = filePath?.stringByDeletingLastPathComponent
            var resultMessage        = p4Functionatlity.issueP4InfoForFolder(parentFolder)
            
            if(resultMessage.isEmpty)
            {
                resultMessage = "Error detected while attempting to query p4 info"
            }
            
            displayCustomAlertBox("p4 info", informativeText: resultMessage)
        }
        else
        {
            displayDefaultP4NotSetError()
        }
    }
    
    // MARK: -
    func p4vcRevGraphSetUpMenu(let item : NSMenuItem?)
    {
        var menuItem = NSMenuItem(title:"p4vc - revgraph", action:"p4vcRevGraph", keyEquivalent:"")
        menuItem.target = self
        item!.submenu!.addItem(menuItem)
    }
    
    func p4vcRevGraph()
    {
        let currentDoc = getCurrentXcodeDocument()
        if(currentDoc.result == false)
        {
            return
        }
        
        if (p4Functionatlity.p4ClientSet() == true && p4Functionatlity.p4vcInstalled == true)
        {
            let filePath      = currentDoc.document?.fileURL?.path
            let parentFolder  = filePath?.stringByDeletingLastPathComponent

            let p4InfoErr     = p4Functionatlity.issueP4InfoForFolder(parentFolder)
            var resultMessage = "Unable to connect to perforce server"
            
            if(p4InfoErr.isEmpty == false)
            {
                resultMessage = p4Functionatlity.displayP4VCRevGraphForFileAtPath(filePath)
            }
            
            if (resultMessage.isEmpty == false)
            {
                displayCustomAlertBox("p4vc revgraph", informativeText: resultMessage)
            }
        }
        else
        {
            displayDefaultP4NotSetError()
        }
    }
    
    func p4vcTimeLapseSetUpMenu(let item : NSMenuItem?)
    {
        var menuItem = NSMenuItem(title:"p4vc - timelapse", action:"p4vcTimeLapse", keyEquivalent:"")
        menuItem.target = self
        item!.submenu!.addItem(menuItem)
    }
    
    func p4vcTimeLapse()
    {
        let currentDoc = getCurrentXcodeDocument()
        if(currentDoc.result == false)
        {
            return
        }
        
        if (p4Functionatlity.p4ClientSet() == true && p4Functionatlity.p4vcInstalled == true)
        {
            let filePath      = currentDoc.document?.fileURL?.path
            let parentFolder  = filePath?.stringByDeletingLastPathComponent
            
            let p4InfoErr     = p4Functionatlity.issueP4InfoForFolder(parentFolder)
            var resultMessage = "Unable to connect to perforce server"
            
            if(p4InfoErr.isEmpty == false)
            {
                resultMessage = p4Functionatlity.displayP4VCTimeLapseForFileAtPath(filePath)
            }
            
            if(resultMessage.isEmpty == false)
            {
                displayCustomAlertBox("p4vc revgraph", informativeText: resultMessage)
            }
        }
        else
        {
            displayDefaultP4NotSetError()
        }
    }
    
    // MARK: -
    func p4MergeDiffSetUpMenu(let item : NSMenuItem?)
    {
        var menuItem = NSMenuItem(title:"p4merge - diff", action:"p4MergeDiff", keyEquivalent:"")
        menuItem.target = self
        item!.submenu!.addItem(menuItem)
    }
    
    func p4MergeDiff()
    {
        
    }
    // MARK: -
    
    func getCurrentXcodeDocument() -> (result:Bool, document:IDESourceCodeDocument?)
    {
        var result          = false
        let currentXcodeDoc = P4XcodeHelper.currentSourceCodeDocument()
        
        if (currentXcodeDoc != nil)
        {
            result = true
        }
        else
        {
            var alertBox             = NSAlert()
            alertBox.messageText     = "Error"
            alertBox.informativeText = "Unable to acquire a valid file path from Xcode"
            alertBox.runModal()
            
            displayCustomAlertBox("Error", informativeText: "Unable to acquire a valid file path from Xcode")
        }
        
        return (result, currentXcodeDoc)
    }
    
    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)
    }
    
    func displayCustomAlertBox(messageText:NSString?, informativeText:NSString?)
    {
        var alertBox             = NSAlert()
        alertBox.messageText     = (messageText as! String)
        alertBox.informativeText = (informativeText as! String)
        if(p4Icon != nil)
        {
            alertBox.icon = p4Icon
        }
        alertBox.runModal()
    }
}

# Change User Description Committed
#12 20141 Jaime Rios Merging using M_robc_apple-to_jaime_rios_XcodePerforcePlugin
#11 19863 Jaime Rios Fixed warning generated by Xcode regarding deprecated selector call usage in Swift
#10 15948 Jaime Rios Added p4vc submit functionality; violated rule 0; updated plist for xcode 7 uuid; fixed errors encountered by xcode related to optionals and interoperability with Obj-C++ code.
#9 15115 Jaime Rios Modified plist for Xcode 6.4 and Xcode 7 Beta; updated code changes in Swift; added notes about UUID for self.
#8 13723 Jaime Rios Fixed problem with menu items not being created because mainMenu is not available at startup for Xcode 6.3.2.
#7 13687 Jaime Rios Added Xcode 6.3.2 support; minor editing changes; fixes for Swift compiler errors.
#6 12123 Jaime Rios Added compatibility for Xcode 6.2; modified the menu layout; added additional screenshot; updated URL for Alcatraz Package Manager.
#5 11740 Jaime Rios Updated readme text with additional known issues; refactored p4 revert function; added perforce icon to alert message.
#4 11739 Jaime Rios Merging

//guest/matt_attaway/XcodePerforcePlugin/...

to //guest/jaime_rios/XcodePerforcePlugin/...
#3 11734 Jaime Rios Modified p4vc functions in Swift code to only show a dialog box if there is an error.
#2 11733 Jaime Rios Refactored code to have more functionality within Swift code; fixed perforce connection bugs.
#1 11694 Jaime Rios Initial add of XcodePerforcePlugin project to guest depot.