using UnityEditor; using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text.RegularExpressions; using System.Linq; using System.IO; using Perforce.P4; using log4net; namespace P4Connect { [Serializable] public class ConfigAsset : ScriptableObject { // These are the config values // We serialize this Class and place it in the P4Connect/Editor Asset Hierarchy public string ServerURI; public string Username; public string Password; public string Workspace; public bool UnityVSSupport; public bool PerforceEnabled; public bool IncludeProjectFiles; public bool IncludeSolutionFiles; public bool ShowPaths; public bool AskBeforeCheckout; public bool DisplayStatusIcons; public string Hostname; public string Charset; public string DiffToolPathname; public bool DisplayP4Timings; public bool DisplayP4Commands; public bool CheckStatusForMenus; public int CheckStatusForMenusMaxItems; public int ConnectionTimeOut; public bool WarnOnSpecialCharacters; public bool UseIgnore; public string IgnoreName; public bool EnableLog; public Logger.LogLevel ConsoleLogLevel; public string LogPath; public string IgnoreLines; // Copy the contents of this ConfigAsset into the P4Connect Config class. public void CopyAssetToConfig() { Config.ServerURI = ServerURI; Config.Username = Username; Config.Password = Password; Config.Workspace = Workspace; Config.UnityVSSupport = UnityVSSupport; Config.PerforceEnabled = PerforceEnabled; Config.IncludeProjectFiles = IncludeProjectFiles; Config.IncludeSolutionFiles = IncludeSolutionFiles; Config.ShowPaths = ShowPaths; Config.AskBeforeCheckout = AskBeforeCheckout; Config.DisplayStatusIcons = DisplayStatusIcons; Config.Hostname = Hostname; Config.Charset = Charset; Config.DiffToolPathname = DiffToolPathname; Config.DisplayP4Timings = DisplayP4Timings; Config.DisplayP4Commands = DisplayP4Commands; Config.CheckStatusForMenus = CheckStatusForMenus; Config.CheckStatusForMenusMaxItems = CheckStatusForMenusMaxItems; Config.ConnectionTimeOut = ConnectionTimeOut; Config.WarnOnSpecialCharacters = WarnOnSpecialCharacters; Config.UseIgnore = UseIgnore; Config.IgnoreName = IgnoreName; Config.EnableLog = EnableLog; Config.ConsoleLogLevel = ConsoleLogLevel; Config.LogPath = LogPath; Config.IgnoreLines = IgnoreLines; } // Seed a ConfigAsset with data from the Config Class public void CopyConfigToAsset() { ServerURI = Config.ServerURI; Username = Config.Username; Password = Config.Password; Workspace = Config.Workspace; UnityVSSupport = Config.UnityVSSupport; PerforceEnabled = Config.PerforceEnabled; IncludeProjectFiles = Config.IncludeProjectFiles; IncludeSolutionFiles = Config.IncludeSolutionFiles; ShowPaths = Config.ShowPaths; AskBeforeCheckout = Config.AskBeforeCheckout; DisplayStatusIcons = Config.DisplayStatusIcons; Hostname = Config.Hostname; Charset = Config.Charset; DiffToolPathname = Config.DiffToolPathname; DisplayP4Timings = Config.DisplayP4Timings; DisplayP4Commands = Config.DisplayP4Commands; CheckStatusForMenus = Config.CheckStatusForMenus; CheckStatusForMenusMaxItems = Config.CheckStatusForMenusMaxItems; ConnectionTimeOut = Config.ConnectionTimeOut; WarnOnSpecialCharacters = Config.WarnOnSpecialCharacters; UseIgnore = Config.UseIgnore; IgnoreName = Config.IgnoreName; EnableLog = Config.EnableLog; ConsoleLogLevel = Config.ConsoleLogLevel; LogPath = Config.LogPath; IgnoreLines = Config.IgnoreLines; } } // This Editor window allows the user to set and store // Perforce connection settings that will be used to // Check out files on Save / Move / Delete / etc... // The connection parameters are saved as Editor Preferences // which means they go the registry. public class Config : EditorWindow { private static readonly ILog log = LogManager.GetLogger(typeof(Config)); static string P4CONFIG_DEFAULT = ".p4config"; // Event triggered when the configuration changes public delegate void OnPrefsChanged(); public static event OnPrefsChanged PrefsChanged; #region Properties // Give access to the Server URI public static string ServerURI { get; set; } // Give access to the User Name public static string Username { get; set; } // Give access to the Password public static string Password { get; set; } // Give access to the Workspace Name public static string Workspace { get; set; } // Give access to whether we integrate with UnityVS public static bool UnityVSSupport { get; set; } // Give access to whether the integration is turned on or not public static bool PerforceEnabled { get; set; } // Give access to whether we check out solution files public static bool IncludeSolutionFiles { get; set; } // Give access to whether we check out project files public static bool IncludeProjectFiles { get; set; } // Give access to whether we print out paths or just filenames public static bool ShowPaths { get; set; } // Give access to whether we automatically check out on edit public static bool AskBeforeCheckout { get; set; } // Give access to whether we want to display Icons in the Project view public static bool DisplayStatusIcons { get; set; } // Whether to override P4Host public static bool OverrideHostname { get; set; } // The host name, if different than the local machine public static string Hostname { get; set; } // Whether to override P4Charset public static bool OverrideCharset { get; set; } // The host name, if different than the local machine public static string Charset { get; set; } // The location of the Diff tool public static string DiffToolPathname { get; set; } // Whether or not to display timing info for debugging public static bool DisplayP4Timings { get; set; } // Whether to display the commands sent to P4 public static bool DisplayP4Commands { get; set; } // Whether or not to check the status of files before showing the contextual menu public static bool CheckStatusForMenus { get; set; } // Whether or not to warn when adding files with special characters public static bool WarnOnSpecialCharacters { get; set; } // Whether or not to check the status of files before showing the contextual menu public static int CheckStatusForMenusMaxItems { get; set; } // How many files to submit at once public static int OperationBatchCount { get; set; } // How long to keep connections open public static int ConnectionTimeOut { get; set; } // Enable the Ignore file public static bool UseIgnore { get; set; } // Provide an Ignore file name public static string IgnoreName { get; set; } // Enable log4net Logging public static bool EnableLog { get; set; } // What log level to display in the console? public static Logger.LogLevel ConsoleLogLevel { get; set; } // Where to save log output public static string LogPath { get; set; } // Additional Ignore Lines public static string IgnoreLines { get; set; } #endregion static bool FoundConfigAsset; // Helper property to indicate that P4 can be used public static bool ValidConfiguration { get { return PerforceEnabled && _CurrentState == ConfigurationState.SettingsValid; } } public const string P4BridgeDLLName = "p4bridge.dll"; public const string P4BridgeDYLIBName = "libp4bridge.dylib"; public const int MaxPendingItems = 200; #region Registry Names // These are the names under which the connection settings are stored in the registry public const string ServerURIPrefName = "ServerURI"; public const string UserNamePrefName = "UserName"; public const string PasswordPrefName = "Password"; public const string WorkspacePrefName = "Workspace"; public const string PerforceEnabledPrefName = "Enabled"; public const string UnityVSSupportPrefName = "UnityVSSupport"; public const string IncludeProjectFilesPrefName = "IncludeProjectFiles"; public const string IncludeSolutionFilesPrefName = "IncludeSolutionFiles"; public const string ShowPathsPrefName = "ShowPaths"; public const string AskBeforeCheckoutPrefName = "AskBeforeCheckout"; public const string DisplayStatusIconsPrefName = "DisplayStatusIcons"; public const string HostnamePrefName = "Hostname"; public const string DiffToolPathnamePrefName = "DiffToolPathname"; public const string DisplayP4TimingsPrefName = "DisplayTimings"; public const string DisplayP4CommandsPrefName = "DisplayCommands"; public const string CheckStatusForMenusPrefName = "CheckStatusForMenus"; public const string CheckStatusForMenusMaxItemsPrefName = "CheckStatusForMenusMaxItems"; public const string OperationBatchCountPrefName = "OperationBatchCount"; public const string ConnectionTimeOutPrefName = "ConnectionTimeOut"; public const string OverrideHostnamePrefName = "OverrideHostname"; public const string WarnOnSpecialCharactersPrefName = "WarnOnSpecialCharacters"; public const string UseIgnorePrefName = "UseIgnore"; public const string IgnoreNamePrefName = "IgnoreName"; public const string EnableLogPrefName = "EnableLog"; public const string ConsoleLogLevelPrefName = "ConsoleLogLevel"; public const string LogPathPrefName = "LogPath"; public const string IgnoreLinesPrefName = "IgnoreLines"; #endregion // Used to create controls //static GUIContent _RevertSettings = new GUIContent("Revert", "Revert settings to previously saved value"); //static GUIContent _SaveSettings = new GUIContent("Save", "Saves the current settings"); static GUILayoutOption _ButtonWidth = GUILayout.MaxWidth(50.0f); static GUILayoutOption _RevertSaveButtonWidth = GUILayout.MaxWidth(80.0f); static GUILayoutOption _WideButtonWidth = GUILayout.MaxWidth(100.0f); static GUILayoutOption _LabelWidth = GUILayout.MaxWidth(300.0f); static GUILayoutOption _BoxWidth = GUILayout.MaxWidth(200.0f); // The current state of the configuration, whether it is valid to be used enum ConfigurationState { Unknown = 0, MetaFilesInvalid, MetaFilesValid, P4ConfigValid, ServerInvalid, ServerValid, UsernamePassInvalid, UsernamePassValid, WorkspaceInvalid, WorkspaceValid, ProjectRootInvalid, ProjectRootValid, SettingsValid, } // The current state of the configuration, whether it is valid to be used static ConfigurationState _CurrentState = ConfigurationState.Unknown; bool _Repaint = false; /// <summary> /// Set some default configuration values /// </summary> static Config() { ResetValues(); } static void ResetValues() { // Set some default values ServerURI = "YourServer:1666"; Username = "YourUsername"; Password = ""; Workspace = "Username_Workspace_Machine"; UseIgnore = true; UnityVSSupport = false; PerforceEnabled = true; IncludeProjectFiles = false; IncludeSolutionFiles = false; ShowPaths = false; AskBeforeCheckout = false; DisplayStatusIcons = true; Hostname = ""; Charset = ""; DiffToolPathname = ""; DisplayP4Timings = false; DisplayP4Commands = false; CheckStatusForMenus = true; CheckStatusForMenusMaxItems = 10; ConnectionTimeOut = 30; WarnOnSpecialCharacters = true; FoundConfigAsset = false; UseIgnore = false; IgnoreName = ".p4ignore"; EnableLog = false; LogPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\p4connect.log"; ConsoleLogLevel = Logger.LogLevel.Info; IgnoreLines = ""; } // Add menu item to show the configuration panel [MenuItem("Edit/Perforce Settings", false, 300)] public static void ShowWindow() { // Show existing window instance. If one doesn't exist, make one. Config window = EditorWindow.GetWindow<Config>("P4 Settings"); window.name = "P4 Settings"; window.title = "P4 Settings"; window.minSize = new UnityEngine.Vector2(500.0f, 500.0f); } /// <summary> /// Static Constructor, reads connection settings from Prefs at least once /// </summary> public static void Initialize() { FoundConfigAsset = readConfigAsset(); if (! FoundConfigAsset) { ReadPrefs(); // Get EditorPrefs if the asset doesn't exist. } CachedSerializationMode = EditorSettings.serializationMode; CheckSettings(); // Try to connect. } /// <summary> /// Forces the config to be invalid, usually after an error /// </summary> public static void NeedToCheckSettings() { _CurrentState = ConfigurationState.Unknown; Debug.LogWarning("P4Connect - Perforce integration is enabled but inactive. Go to Edit->Perforce Settings to update your settings"); } /// <summary> /// Checks the that settings are valid /// </summary> public static void CheckSettings() { if (PerforceEnabled) { // We only display a message when something changes ConfigurationState prevState = _CurrentState; _CurrentState = ConfigurationState.Unknown; // Check the config UpdateConfigState(); // If the state is different then when we started if (_CurrentState != prevState) { Icons.UpdateDisplay(); if (_CurrentState != ConfigurationState.SettingsValid) { Debug.LogWarning("P4Connect - Perforce integration is enabled but inactive. Go to Edit->Perforce Settings to update your settings"); } else if (prevState != ConfigurationState.SettingsValid) { Debug.Log("P4Connect - Perforce Integration is Active"); } } if (_CurrentState == ConfigurationState.SettingsValid) { SetProjectRootDirectory(); } } } /// <summary> /// Updates the current configuration state after checking all the settings /// </summary> public static void UpdateConfigState() { switch (_CurrentState) { case ConfigurationState.Unknown: // The unknown state starts by checking the meta files goto case ConfigurationState.MetaFilesInvalid; case ConfigurationState.MetaFilesInvalid: if (P4Connect.VerifySettings.CheckMetaFiles()) { // Meta files are valid, move on _CurrentState = ConfigurationState.MetaFilesValid; goto case ConfigurationState.MetaFilesValid; } else { // Stay in this state _CurrentState = ConfigurationState.MetaFilesInvalid; break; } case ConfigurationState.MetaFilesValid: goto case ConfigurationState.ServerInvalid; case ConfigurationState.ServerInvalid: if (P4Connect.VerifySettings.CheckServerURI()) { // Server is valid, move on _CurrentState = ConfigurationState.ServerValid; goto case ConfigurationState.ServerValid; } else { // Stay here _CurrentState = ConfigurationState.ServerInvalid; break; } case ConfigurationState.ServerValid: goto case ConfigurationState.UsernamePassInvalid; case ConfigurationState.UsernamePassInvalid: if (P4Connect.VerifySettings.CheckUsernamePassword()) { // Username / Password is valid, move on _CurrentState = ConfigurationState.UsernamePassValid; goto case ConfigurationState.UsernamePassValid; } else { // Stay here _CurrentState = ConfigurationState.UsernamePassInvalid; break; } case ConfigurationState.UsernamePassValid: goto case ConfigurationState.WorkspaceInvalid; case ConfigurationState.WorkspaceInvalid: if (P4Connect.VerifySettings.CheckWorkspace()) { // Workspace is valid _CurrentState = ConfigurationState.WorkspaceValid; goto case ConfigurationState.WorkspaceValid; } else { // Stay here _CurrentState = ConfigurationState.WorkspaceInvalid; break; } case ConfigurationState.WorkspaceValid: goto case ConfigurationState.ProjectRootInvalid; case ConfigurationState.ProjectRootInvalid: if (P4Connect.VerifySettings.CheckProjectRoot()) { // Root is valid _CurrentState = ConfigurationState.ProjectRootValid; goto case ConfigurationState.ProjectRootValid; } else { // Stay here _CurrentState = ConfigurationState.ProjectRootInvalid; break; } case ConfigurationState.ProjectRootValid: _CurrentState = ConfigurationState.SettingsValid; goto case ConfigurationState.SettingsValid; case ConfigurationState.SettingsValid: break; } // Clean up the connection PerforceConnection.ForceCloseConnection(); } public static void SetProjectRootDirectory() { if (Config.ValidConfiguration) { Engine.PerformConnectionOperation(con => { // project root in perforce syntax var spec = FileSpec.LocalSpec(System.IO.Path.Combine(Main.RootPath, "...")); //log.DebugFormat("spec: {0}", spec.ToString()); var mappings = con.P4Client.GetClientFileMappings(spec); //log.DebugFormat("mappings: {0}", Logger.FileSpecListToString(mappings)); if (mappings != null && mappings.Count > 0) { // string ProjectRoot; string clientProjectRoot = mappings[0].ClientPath.Path; //log.DebugFormat("clientProjectRoot: {0} ", clientProjectRoot); int projectRootOffset = clientProjectRoot.ToLowerInvariant().IndexOf(Config.Workspace.ToLowerInvariant()); //log.DebugFormat("projectRootOffset: {0}", projectRootOffset); if (projectRootOffset != -1) { //ProjectRoot = clientProjectRoot.Substring(projectRootOffset + Config.Workspace.Length); //log.DebugFormat("ProjectRoot1: {0} ", ProjectRoot); //ProjectRoot = ProjectRoot.TrimStart(System.IO.Path.DirectorySeparatorChar, '/'); //if (ProjectRoot.EndsWith("...")) // ProjectRoot = ProjectRoot.Substring(0, ProjectRoot.Length - 3); //ProjectRoot = ProjectRoot.TrimEnd(System.IO.Path.DirectorySeparatorChar, '/'); //ProjectRoot = ProjectRoot.Replace('/', System.IO.Path.DirectorySeparatorChar); //log.Debug("SetProjectRootDirectory - ProjectRoot: " + ProjectRoot); } else { Debug.LogError("P4Connect - Your Project does not appear to be under your workspace root."); } } }); } } Vector2 scroll = new Vector2(0,0); // Track scroll position in the additional ignore TextArea /// <summary> /// Called by Unity when the windows needs to be updated /// </summary> void OnGUI() { // Add a global checkbox to turn perforce integration on/off PerforceEnabled = EditorGUILayout.BeginToggleGroup("Enable Perforce Integration", PerforceEnabled); if (PerforceEnabled) { float checkWidth = 16.0f; float intWidth = 30.0f; float buttonWidth = 80.0f; float textWidth = 250.0f; float secondtextWidth = 200.0f; float pathWidth = 300.0f; EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical("box"); GUILayout.Label("Load Settings"); EditorGUI.BeginDisabledGroup(_CurrentState == ConfigurationState.SettingsValid); { if (GUILayout.Button("From Defaults", EditorStyles.miniButton, _BoxWidth)) { ResetValues(); Repaint(); } if (GUILayout.Button("From P4 Environment", EditorStyles.miniButton, _BoxWidth)) { ReadEnvironment(); Repaint(); } if (GUILayout.Button("From P4Config", EditorStyles.miniButton, _BoxWidth)) { string configName = Environment.GetEnvironmentVariable("P4CONFIG"); if (string.IsNullOrEmpty(configName)) { configName = P4CONFIG_DEFAULT; // If not in environment, use the default. } string p4configFile = FindP4ConfigFile(configName); if (string.IsNullOrEmpty(p4configFile)) { Debug.Log("P4Config file " + configName + " Not Found"); } else { LoadP4ConfigFile(p4configFile); Debug.Log("P4Config Found at: " + Path.GetFullPath(p4configFile)); } Repaint(); } if (GUILayout.Button("From Editor Prefs", EditorStyles.miniButton, _BoxWidth)) { ReadPrefs(); Repaint(); } } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndVertical(); GUILayout.FlexibleSpace(); EditorGUILayout.BeginVertical("box"); GUILayout.Label("Save Settings"); if (GUILayout.Button("Clear Editor Prefs", EditorStyles.miniButton, _BoxWidth)) { if (EditorUtility.DisplayDialog("Remove All EditorPrefs", "Are you sure you want to remove ALL editorPrefs?","OK","Cancel")) { EditorPrefs.DeleteAll(); //DeleteAllEditorPrefs(); // This call doesn't work on all entries } } if (GUILayout.Button("To EditorPrefs", EditorStyles.miniButton, _BoxWidth)) { WritePrefs(); } if (GUILayout.Button("To Asset", EditorStyles.miniButton, _BoxWidth)) { writeConfigAsset(); // This will create a config asset! } EditorGUILayout.EndVertical(); } EditorGUILayout.EndHorizontal(); GUILayout.BeginVertical("Box"); GUILayout.Label("Connection Settings", EditorStyles.boldLabel); // Disable connection settings if already connected EditorGUI.BeginDisabledGroup(_CurrentState == ConfigurationState.SettingsValid); { EditorGUILayout.BeginHorizontal(); { // The edit field for the server ServerURI = EditorGUILayout.TextField("\tServer URI", ServerURI); } EditorGUILayout.EndHorizontal(); if (_CurrentState == ConfigurationState.ServerInvalid) { EditorGUILayout.HelpBox("Invalid Server URI", MessageType.Error); } EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical(); Username = EditorGUILayout.TextField("\tUsername", Username); Password = EditorGUILayout.PasswordField("\tPassword", Password); EditorGUILayout.EndVertical(); } EditorGUILayout.EndHorizontal(); if (_CurrentState == ConfigurationState.UsernamePassInvalid) { EditorGUILayout.HelpBox("Invalid Username / Password", MessageType.Error); } EditorGUILayout.BeginHorizontal(); { Workspace = EditorGUILayout.TextField("\tWorkspace", Workspace); } EditorGUILayout.EndHorizontal(); if (_CurrentState == ConfigurationState.WorkspaceInvalid) { EditorGUILayout.HelpBox("Invalid Workspace", MessageType.Error); } if (_CurrentState == ConfigurationState.ProjectRootInvalid) { // The project isn't under the workspace root string perforcePath = "//" + Workspace + "/..."; string rootPath = P4Connect.Main.RootPath; EditorGUILayout.HelpBox("Invalid Workspace. The client path:\n" + "\t" + perforcePath + "\n" + "maps to this folder:\n" + "\t" + VerifySettings.LastWorkspaceMapping + "\n" + "which is not a parent directory of the project's root:\n" + "\t" + rootPath, MessageType.Error); } EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tP4HOST variable", GUILayout.Width(textWidth)); OverrideHostname = EditorGUILayout.Toggle(OverrideHostname, GUILayout.Width(checkWidth)); GUILayout.Label("\tHostname", GUILayout.Width(secondtextWidth)); Hostname = EditorGUILayout.TextField(Hostname, GUILayout.Width(120.0f)); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tP4CHARSET variable", GUILayout.Width(textWidth)); OverrideCharset = EditorGUILayout.Toggle(OverrideCharset, GUILayout.Width(checkWidth)); GUILayout.Label("\tCharset", GUILayout.Width(secondtextWidth)); Charset = EditorGUILayout.TextField(Charset, GUILayout.Width(120.0f)); } EditorGUILayout.EndHorizontal(); } EditorGUI.EndDisabledGroup(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button((_CurrentState == ConfigurationState.SettingsValid ? "Disconnect" : "Connect"), EditorStyles.miniButton, _BoxWidth)) { if (_CurrentState == ConfigurationState.SettingsValid) _CurrentState = ConfigurationState.Unknown; else { CheckSettings(); } } EditorGUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.Label("Interface", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tDisplay Status Icons", GUILayout.Width(textWidth)); DisplayStatusIcons = EditorGUILayout.Toggle(DisplayStatusIcons, GUILayout.Width(checkWidth)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tShow File Paths in Console", GUILayout.Width(textWidth)); ShowPaths = EditorGUILayout.Toggle(ShowPaths, GUILayout.Width(checkWidth)); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tDiff Tool Executable", GUILayout.Width(textWidth)); DiffToolPathname = EditorGUILayout.TextField("", DiffToolPathname); if (GUILayout.Button("Browse...", EditorStyles.miniButton, GUILayout.Width(buttonWidth))) { GUI.FocusControl(""); DiffToolPathname = EditorUtility.OpenFilePanel("Choose Diff Tool Executable", System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles), ""); } } EditorGUILayout.EndHorizontal(); GUILayout.Label("Behaviour", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tAsk before checkout on edit", GUILayout.Width(textWidth)); AskBeforeCheckout = EditorGUILayout.Toggle(AskBeforeCheckout, GUILayout.Width(checkWidth)); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tShow warning when adding files with reserved characters (@#*%)", GUILayout.Width(textWidth)); WarnOnSpecialCharacters = EditorGUILayout.Toggle(WarnOnSpecialCharacters, GUILayout.Width(checkWidth)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tInclude Solution Files", GUILayout.Width(textWidth)); IncludeSolutionFiles = EditorGUILayout.Toggle(IncludeSolutionFiles, GUILayout.Width(checkWidth)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tInclude Projects Files", GUILayout.Width(textWidth)); IncludeProjectFiles = EditorGUILayout.Toggle(IncludeProjectFiles, GUILayout.Width(checkWidth)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tIntegrate with UnityVS", GUILayout.Width(textWidth)); UnityVSSupport = EditorGUILayout.Toggle(UnityVSSupport, GUILayout.Width(checkWidth)); EditorGUILayout.EndHorizontal(); GUILayout.Label("Advanced", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tGray out invalid menu options", GUILayout.Width(textWidth)); CheckStatusForMenus = EditorGUILayout.Toggle(CheckStatusForMenus, GUILayout.Width(checkWidth)); GUILayout.Label("Don't check if more than", GUILayout.Width(secondtextWidth)); CheckStatusForMenusMaxItems = EditorGUILayout.IntField(CheckStatusForMenusMaxItems, GUILayout.Width(intWidth)); GUILayout.Label("files selected"); GUILayout.FlexibleSpace(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tClose Perforce connection after", GUILayout.Width(textWidth)); ConnectionTimeOut = EditorGUILayout.IntField(ConnectionTimeOut, GUILayout.Width(intWidth)); GUILayout.Label("seconds"); GUILayout.FlexibleSpace(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tDisplay P4 Timings", GUILayout.Width(textWidth)); DisplayP4Timings = EditorGUILayout.Toggle(DisplayP4Timings, GUILayout.Width(checkWidth)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tEnable P4Ignore", GUILayout.Width(textWidth)); UseIgnore = EditorGUILayout.Toggle(UseIgnore, GUILayout.Width(checkWidth)); GUILayout.Label("\tP4Ignore File", GUILayout.Width(secondtextWidth)); IgnoreName = EditorGUILayout.TextField(IgnoreName, GUILayout.Width(pathWidth)); if (GUILayout.Button("Browse...", EditorStyles.miniButton, GUILayout.Width(buttonWidth))) { GUI.FocusControl(""); IgnoreName = EditorUtility.OpenFilePanel("Choose P4Ignore File", Main.RootPath, ""); UseIgnore = true; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tEnable Logging", GUILayout.Width(textWidth)); EnableLog = EditorGUILayout.Toggle(EnableLog, GUILayout.Width(checkWidth)); GUILayout.Label("\tConsole Log Level:", GUILayout.Width(secondtextWidth)); ConsoleLogLevel = (Logger.LogLevel)EditorGUILayout.EnumPopup(ConsoleLogLevel, GUILayout.Width(50.0f)); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tLog File", GUILayout.Width(textWidth)); LogPath = EditorGUILayout.TextField(LogPath); if (GUILayout.Button("Browse...", EditorStyles.miniButton, GUILayout.Width(buttonWidth))) { GUI.FocusControl(""); LogPath = EditorUtility.SaveFilePanel("Save P4Connect Log", System.Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory), "p4connect", "log"); if (String.IsNullOrEmpty(LogPath)) EnableLog = false; else EnableLog = true; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { GUILayout.Label("\tAdditional Ignore Lines", GUILayout.Width(textWidth)); scroll = EditorGUILayout.BeginScrollView(scroll, GUILayout.Width(pathWidth + 10.0f), GUILayout.MaxHeight(50.0f)); IgnoreLines = EditorGUILayout.TextArea(IgnoreLines, GUILayout.MinHeight(16.0f), GUILayout.Width(pathWidth)); EditorGUILayout.EndScrollView(); } EditorGUILayout.EndHorizontal(); //} //else //{ // EditorGUILayout.HelpBox("You must set the Editor Version Control to \"Meta Files\" under Edit->Project Settings->Editor", MessageType.Info); // if (VerifySettings.CheckMetaFiles()) // { // _ResetState = true; // } //} } // If PerforceEnabled EditorGUILayout.EndToggleGroup(); // Info message GUILayout.FlexibleSpace(); if (PerforceEnabled) { if (_CurrentState != ConfigurationState.SettingsValid) { EditorGUILayout.HelpBox("Perforce Integration is INACTIVE. Please Verify your Settings!", MessageType.Warning); } else { EditorGUILayout.HelpBox("Perforce Integration is ACTIVE.", MessageType.Info); } } else { EditorGUILayout.HelpBox("Perforce Integration is DISABLED.", MessageType.Info); } // Display the bottom "Status" line EditorGUILayout.BeginHorizontal(); GUILayout.Label("Project: " + Main.RootPath); GUILayout.FlexibleSpace(); GUILayout.Label("P4Connect " + Version.p4ConnectVersion + " " + Version.build, EditorStyles.miniLabel); if (GUILayout.Button("Visit Website", EditorStyles.miniButton)) { System.Diagnostics.Process.Start("http://www.perforce.com/perforce/doc.current/manuals/p4connectguide/index.html"); } EditorGUILayout.EndHorizontal(); } void OnSelectionChange() { // UnityEngine.Object cursel = Selection.activeObject; } void OnInspectorUpdate() { if (_Repaint) { _Repaint = false; Repaint(); } } // Check for the "well known" Perforce environment variables. public static void ReadEnvironment() { string value; value = Environment.GetEnvironmentVariable("P4PORT"); if (value != null) Config.ServerURI = value; value = Environment.GetEnvironmentVariable("P4USER"); if (value != null) Config.Username = value; value = Environment.GetEnvironmentVariable("P4PASSWD"); if (value != null) Config.Password = value; value = Environment.GetEnvironmentVariable("P4CLIENT"); if (value != null) Config.Workspace = value; value = Environment.GetEnvironmentVariable("P4HOST"); if (value != null) Config.Hostname = value; value = Environment.GetEnvironmentVariable("P4CHARSET"); if (value != null) Config.Charset = value; value = Environment.GetEnvironmentVariable("P4IGNORE"); if (value != null) Config.IgnoreName = value; } #region EditorPreferences // Utility method to read connection prefs from the registry public static void ReadPrefs() { Debug.Log("ReadPrefs()"); // Check if the keys exist, and if so, read the values out // Otherwise, leave the existing values if (HasStringPrefNotEmpty(ServerURIPrefName)) ServerURI = GetPrefString(ServerURIPrefName); if (HasStringPrefNotEmpty(UserNamePrefName)) Username = GetPrefString(UserNamePrefName); if (HasStringPrefNotEmpty(PasswordPrefName)) Password = Secure.DecryptString(GetPrefString(PasswordPrefName)); if (HasStringPrefNotEmpty(WorkspacePrefName)) Workspace = GetPrefString(WorkspacePrefName); if (HasPref(UnityVSSupportPrefName)) UnityVSSupport = GetPrefBool(UnityVSSupportPrefName); if (HasPref(IncludeProjectFilesPrefName)) IncludeProjectFiles = GetPrefBool(IncludeProjectFilesPrefName); if (HasPref(IncludeSolutionFilesPrefName)) IncludeSolutionFiles = GetPrefBool(IncludeSolutionFilesPrefName); if (HasPref(ShowPathsPrefName)) ShowPaths = GetPrefBool(ShowPathsPrefName); if (HasPref(AskBeforeCheckoutPrefName)) AskBeforeCheckout = GetPrefBool(AskBeforeCheckoutPrefName); if (HasPref(DisplayStatusIconsPrefName)) { //Debug.Log("DisplayStatusIcons in the registry!"); DisplayStatusIcons = GetPrefBool(DisplayStatusIconsPrefName); } if (HasStringPrefNotEmpty(HostnamePrefName)) Hostname = GetPrefString(HostnamePrefName); if (HasStringPrefNotEmpty(DiffToolPathnamePrefName)) DiffToolPathname = GetPrefString(DiffToolPathnamePrefName); if (HasPref(DisplayP4TimingsPrefName)) DisplayP4Timings = GetPrefBool(DisplayP4TimingsPrefName); if (HasPref(DisplayP4CommandsPrefName)) DisplayP4Commands = GetPrefBool(DisplayP4CommandsPrefName); if (HasPref(CheckStatusForMenusPrefName)) CheckStatusForMenus = GetPrefBool(CheckStatusForMenusPrefName); if (HasPref(CheckStatusForMenusMaxItemsPrefName)) CheckStatusForMenusMaxItems = GetPrefInt(CheckStatusForMenusMaxItemsPrefName); if (HasPref(OperationBatchCountPrefName)) OperationBatchCount = GetPrefInt(OperationBatchCountPrefName); if (HasPref(ConnectionTimeOutPrefName)) ConnectionTimeOut = GetPrefInt(ConnectionTimeOutPrefName); if (HasPref(OverrideHostnamePrefName)) OverrideHostname = GetPrefBool(OverrideHostnamePrefName); if (HasPref(WarnOnSpecialCharactersPrefName)) WarnOnSpecialCharacters = GetPrefBool(WarnOnSpecialCharactersPrefName); if (HasPref(UseIgnorePrefName)) UseIgnore = GetPrefBool(UseIgnorePrefName); if (HasStringPrefNotEmpty(IgnoreNamePrefName)) IgnoreName = GetPrefString(IgnoreNamePrefName); if (HasPref(EnableLogPrefName)) EnableLog = GetPrefBool(EnableLogPrefName); if (HasPref(ConsoleLogLevelPrefName)) ConsoleLogLevel = (Logger.LogLevel) GetPrefInt(ConsoleLogLevelPrefName); if (HasStringPrefNotEmpty(IgnoreLinesPrefName)) IgnoreLines = GetPrefString(IgnoreLinesPrefName); // Notify users that prefs changed if (PrefsChanged != null) PrefsChanged(); } // Utility method to write our the connection prefs to the registry public static void WritePrefs() { Debug.Log("WritePrefs"); SetPrefString(ServerURIPrefName, ServerURI); SetPrefString(UserNamePrefName, Username); if (! String.IsNullOrEmpty(Password)) SetPrefString(PasswordPrefName, Secure.EncryptString(Password)); System.Console.WriteLine("After EncryptString"); SetPrefString(WorkspacePrefName, Workspace); SetPrefBool(PerforceEnabledPrefName, PerforceEnabled); SetPrefBool(UnityVSSupportPrefName, UnityVSSupport); SetPrefBool(IncludeProjectFilesPrefName, IncludeProjectFiles); SetPrefBool(IncludeSolutionFilesPrefName, IncludeSolutionFiles); SetPrefBool(ShowPathsPrefName, ShowPaths); SetPrefBool(AskBeforeCheckoutPrefName, AskBeforeCheckout); SetPrefBool(DisplayStatusIconsPrefName, DisplayStatusIcons); SetPrefString(HostnamePrefName, Hostname); SetPrefString(DiffToolPathnamePrefName, DiffToolPathname); SetPrefBool(DisplayP4TimingsPrefName, DisplayP4Timings); SetPrefBool(DisplayP4CommandsPrefName, DisplayP4Commands); SetPrefBool(CheckStatusForMenusPrefName, CheckStatusForMenus); SetPrefInt(CheckStatusForMenusMaxItemsPrefName, CheckStatusForMenusMaxItems); SetPrefInt(OperationBatchCountPrefName, OperationBatchCount); SetPrefInt(ConnectionTimeOutPrefName, ConnectionTimeOut); SetPrefBool(OverrideHostnamePrefName, OverrideHostname); SetPrefBool(WarnOnSpecialCharactersPrefName, WarnOnSpecialCharacters); SetPrefBool(UseIgnorePrefName, UseIgnore); SetPrefString(IgnoreNamePrefName,IgnoreName); SetPrefBool(EnableLogPrefName,EnableLog); SetPrefInt(ConsoleLogLevelPrefName, (int) ConsoleLogLevel); SetPrefString(LogPathPrefName,LogPath); SetPrefString(IgnoreLinesPrefName, IgnoreLines); //System.Console.WriteLine("done writing prefs"); } static string GetFullPrefName(string aPrefName) { // System.Console.WriteLine("P4Connect_" + Main.ProjectName + "_" + aPrefName); return "P4Connect_" + Main.ProjectName + "_" + aPrefName; } static bool HasPref(string aPrefName) { return EditorPrefs.HasKey(GetFullPrefName(aPrefName)); } static bool HasStringPrefNotEmpty(string aPrefName) { return (! String.IsNullOrEmpty(EditorPrefs.GetString(GetFullPrefName(aPrefName)))); } static void SetPrefString(string aPrefName, string aPref) { EditorPrefs.SetString(GetFullPrefName(aPrefName), aPref); } static void SetPrefInt(string aPrefName, int aPref) { EditorPrefs.SetInt(GetFullPrefName(aPrefName), aPref); } static void SetPrefBool(string aPrefName, bool aPref) { EditorPrefs.SetBool(GetFullPrefName(aPrefName), aPref); } static string GetPrefString(string aPrefName) { return EditorPrefs.GetString(GetFullPrefName(aPrefName)); } static int GetPrefInt(string aPrefName) { return EditorPrefs.GetInt(GetFullPrefName(aPrefName)); } static bool GetPrefBool(string aPrefName) { return EditorPrefs.GetBool(GetFullPrefName(aPrefName)); } // [MenuItem("Edit/Delete Project EditorPrefs", false, 300)] static void DeleteAllEditorPrefs() { Debug.Log("DeletePrefs()"); // Delete All keys for this project EditorPrefs.DeleteKey(ServerURIPrefName); EditorPrefs.DeleteKey(UserNamePrefName); EditorPrefs.DeleteKey(PasswordPrefName); EditorPrefs.DeleteKey(WorkspacePrefName); EditorPrefs.DeleteKey(UnityVSSupportPrefName); EditorPrefs.DeleteKey(IncludeProjectFilesPrefName); EditorPrefs.DeleteKey(IncludeSolutionFilesPrefName); EditorPrefs.DeleteKey(ShowPathsPrefName); EditorPrefs.DeleteKey(AskBeforeCheckoutPrefName); EditorPrefs.DeleteKey(DisplayStatusIconsPrefName); EditorPrefs.DeleteKey(HostnamePrefName); EditorPrefs.DeleteKey(DiffToolPathnamePrefName); EditorPrefs.DeleteKey(DisplayP4TimingsPrefName); EditorPrefs.DeleteKey(DisplayP4CommandsPrefName); EditorPrefs.DeleteKey(CheckStatusForMenusPrefName); EditorPrefs.DeleteKey(CheckStatusForMenusMaxItemsPrefName); EditorPrefs.DeleteKey(OperationBatchCountPrefName); EditorPrefs.DeleteKey(ConnectionTimeOutPrefName); EditorPrefs.DeleteKey(OverrideHostnamePrefName); EditorPrefs.DeleteKey(WarnOnSpecialCharactersPrefName); EditorPrefs.DeleteKey(UseIgnorePrefName); EditorPrefs.DeleteKey(IgnoreNamePrefName); EditorPrefs.DeleteKey(EnableLogPrefName); EditorPrefs.DeleteKey(ConsoleLogLevelPrefName); EditorPrefs.DeleteKey(IgnoreLinesPrefName); } #endregion public static SerializationMode CachedSerializationMode { get; private set; } #region P4CONFIG public static string FindP4ConfigFile(string config) { string directoryName; if (! String.IsNullOrEmpty(config)) { string path = Application.dataPath; while (path != null) { directoryName = Path.GetDirectoryName(path); if (!String.IsNullOrEmpty(directoryName)) { string[] files = System.IO.Directory.GetFiles(directoryName, config); if (files.Count() > 0) { return files[0]; } } path = directoryName; } } return null; } public static void LoadP4ConfigFile(string path) { string line; char[] equalsChars = { '=' }; System.IO.StreamReader file = new System.IO.StreamReader(path); while ((line = file.ReadLine()) != null) { string[] segments = line.Split(equalsChars); if (segments.Length >= 2) { string key = segments[0]; string val = segments[1]; // Debug.Log("Key: " + key); // Debug.Log("Value: " + val); switch (segments[0]) { case "P4PORT": { ServerURI = val; } break; case "P4USER": { Username = val; } break; case "P4CLIENT": { Workspace = val; } break; case "P4PASSWD": { Password = val; } break; case "P4HOST": { Hostname = val; } break; case "P4CHARSET": { Charset = val; } break; } } } file.Close(); } #endregion #region ConfigAsset static string configAssetPath = "Assets/P4Connect/Editor/Config.asset"; public static void writeConfigAsset() { ConfigAsset asset = ScriptableObject.CreateInstance<ConfigAsset>(); asset.CopyConfigToAsset(); AssetDatabase.CreateAsset(asset, configAssetPath); AssetDatabase.SaveAssets(); } public static bool readConfigAsset() { ConfigAsset asset = (ConfigAsset)AssetDatabase.LoadAssetAtPath(configAssetPath, typeof(ConfigAsset)); if (asset != null) { asset.CopyAssetToConfig(); return true; } else { return false; } } /* If the inspector is used to view a Config Asset, these properties control the presentation */ [CustomEditor(typeof(ConfigAsset))] public class ConfigAssetPropertiesEditor : Editor { public override void OnInspectorGUI() { GUI.enabled = false; DrawDefaultInspector(); GUI.enabled = true; } } #endregion } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#31 | 16251 | Norman Morse | Update Dev branch to match reorganization in workshop | ||
#30 | 15074 | Norman Morse | Fixed NullReferenceException in Config dialog | ||
#29 | 14800 | Norman Morse |
Fixed Exception in debug statements Improved performance of pending assets menu on large change sets, some other minor premature optimizations Allowed saving of configuration while Perforce is disabled. Improved restoring connection after recompile. |
||
#28 | 14236 | Norman Morse | update dev branch with GA.8 release files | ||
#27 | 13872 | Norman Morse | Update dev branch from GA.5 release | ||
#26 | 12863 | Norman Morse |
import from main Recently updated from internal Several Bugfixes logging clean up |
||
#25 | 12558 | Norman Morse | Integrate from main to dev | ||
#24 | 12510 | Norman Morse |
Another pass at the Configuration UI. password now works but is not obscured in the registry. Fixed browse buttons to use previous paths if set. Removed obsolete fields Removed debugging |
||
#23 | 12501 | Norman Morse |
Rewrote Configuration Window. Provided buttons to read values and to save configurations. Removed P4Config settings, replaced with P4Config button and reports to Debug.Log() Removed SaveConfigurationAsset Setting, replaced with "Save as Asset" button. Made Connection Configuration read only while connected. Made dialogs disappear if they become disconnected during OnGui() Bumped Beta Value. |
||
#22 | 12480 | Norman Morse |
Fixed crash in logging. Worked on UI issues. Cleaned up some connection usage. Still looking for the problem with pending changes. |
||
#21 | 12473 | Norman Morse | More minor fixes to logging and config | ||
#20 | 12467 | Norman Morse |
Many minor changes to improve logging Added a filter for Console log display where you can select a level Hooked the log file location to the Configuration Log Entry. |
||
#19 | 12445 | Norman Morse |
Integrated log4net and nunit into P4Connect. Still need cleanup and debugging, good enough for dev tree Also added ChangeManager and ChangeLists Classes for future use with multiple changes. |
||
#18 | 12424 | Norman Morse | More Logging and Testing in dev branch | ||
#17 | 12363 | Norman Morse |
Merging //guest/perforce_software/p4connect/src/... to //guest/norman_morse/dev/p4connect/src/... |
||
#16 | 12244 | Norman Morse |
Fixes to Configuration GUI. Fixes to ProgramName and ProgramVer being passed to Connection. |
||
#15 | 12131 | Norman Morse |
Unity 5 fixes for icons and loading the DLL. Needed to use reflection to load the icons. |
||
#14 | 12101 | Norman Morse |
Additional movement towards Unity 5. Still gettting DllNotFound exceptions in 5 |
||
#13 | 12099 | Norman Morse |
Various changes to prepare for Beta Fixed VersionInfo to show changeID Added "additional ignore in config". Updated ReleaseNotes |
||
#12 | 12087 | Norman Morse |
Another Day, another dollar Fixed some bad __except clauses for OSX. Debugging ignore stuff passing pwd in |
||
#11 | 12085 | Norman Morse |
Additional Configuration fields added to dialog. Functionality still needs to be hooked up. |
||
#10 | 12057 | Norman Morse | Added Region Tags, work on p4ignore | ||
#9 | 11907 | Norman Morse | p4ignore initial test | ||
#8 | 11889 | Norman Morse | Add ConfigAsset support | ||
#7 | 11853 | Norman Morse | pre release 2.7 workshop dev cleanup | ||
#6 | 11841 | Norman Morse | Multi-platform build for unity 4.x fixup changes | ||
#5 | 11821 | Norman Morse | Move Unity 5 compatible build from internal dev branch to workshop dev branch. | ||
#4 | 11820 | Norman Morse | Project specific preferences saved in .ini file. | ||
#3 | 11214 | Norman Morse | Improved startup P4Config detection - added to P4Connect state machine | ||
#2 | 11172 | Norman Morse | P4Config integration. | ||
#1 | 10941 | Norman Morse | Create dev branch from workshop | ||
//guest/perforce_software/p4connect/src/P4Connect/P4Connect/P4Connect.Config.cs | |||||
#1 | 10940 | Norman Morse |
Inital Workshop release of P4Connect. Released under BSD-2 license |