using UnityEditor; using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.IO; using Perforce.P4; namespace P4Connect { // 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 { // Event triggered when the configuration changes public delegate void OnPrefsChanged(); public static event OnPrefsChanged PrefsChanged; // The actual connection settings // 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 the DLL Location public static string DLLLocation { get; set; } // Look for p4config files to setup configuration? public static bool UseP4Config { 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; } // The location of the project root in relation to the workspace root public static string ProjectRoot { get; set; } // 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; // 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 P4ConfigPrefName = "UseP4Config"; public const string DLLLocationPrefName = "DLLLocation"; public const string ConfigurationStateName = "ConfigurationState"; 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"; // 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 _LabelWidth = GUILayout.MaxWidth(300.0f); public static string p4configFile; // 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; // Toggles the extra options int _FrameIndex = 0; bool _SettingsChanged = false; bool _Repaint = false; /// /// Set some default configuration values /// static Config() { // Set some default values ServerURI = "YourServer:1666"; Username = "YourUsername"; Password = ""; Workspace = "Username_Workspace_Machine"; UseP4Config = true; DLLLocation = "P4Connect/Editor/"; UseP4Config = true; UnityVSSupport = false; PerforceEnabled = true; IncludeProjectFiles = true; IncludeSolutionFiles = true; ShowPaths = false; AskBeforeCheckout = false; DisplayStatusIcons = true; Hostname = ""; Charset = ""; DiffToolPathname = ""; DisplayP4Timings = false; DisplayP4Commands = false; CheckStatusForMenus = true; CheckStatusForMenusMaxItems = 10; ConnectionTimeOut = 30; ProjectRoot = ""; WarnOnSpecialCharacters = true; } // 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("P4 Settings"); window.name = "P4 Settings"; window.title = "P4 Settings"; window.minSize = new UnityEngine.Vector2(500.0f, 500.0f); } /// /// Static Constructor, reads connection settings from Prefs at least once /// public static void Initialize() { ReadPrefs(); CachedSerializationMode = EditorSettings.serializationMode; } /// /// Forces the config to be invalid, usually after an error /// 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"); } /// /// Checks the that settings are valid /// public static void CheckSettings() { if (PerforceEnabled) { // We only display a message when something changes ConfigurationState prevState = _CurrentState; _CurrentState = ConfigurationState.Unknown; // Check the config UpdateConfigState(); // And notify user 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(); } } } public static void SetProjectRootDirectory() { if (Config.ValidConfiguration) { Engine.PerformConnectionOperation(con => { var spec = FileSpec.LocalSpec(System.IO.Path.Combine(Main.RootPath, "...")); var mappings = con.P4Client.GetClientFileMappings(spec); if (mappings != null && mappings.Count > 0) { string clientProjectRoot = mappings[0].ClientPath.Path; int projectRootOffset = clientProjectRoot.ToLowerInvariant().IndexOf(Config.Workspace.ToLowerInvariant()); if (projectRootOffset != -1) { ProjectRoot = clientProjectRoot.Substring(projectRootOffset + Config.Workspace.Length); 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); } else { Debug.LogError("P4Connect - Your Project does not appear to be under your workspace root."); } } }); } } /// /// Updates the current configuration state after checking all the settings /// 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.P4ConfigValid; case ConfigurationState.P4ConfigValid: { if (UseP4Config) { p4configFile = FindP4ConfigFile(); if (p4configFile != null) LoadP4ConfigFile(p4configFile); } // in either case, move on _CurrentState = ConfigurationState.ServerInvalid; 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(); } /// /// Called by Unity when the windows needs to be updated /// void OnGUI() { // This will store whether the user requested to check the settings bool checkSettings = false; // Add a global checkbox to turn perforce integration on/off bool newPerforceEnabled = EditorGUILayout.BeginToggleGroup("Enable Perforce Integration", PerforceEnabled); if (newPerforceEnabled != PerforceEnabled) { PerforceEnabled = newPerforceEnabled; PendingChanges.UpdateDisplay(); Icons.UpdateDisplay(); _SettingsChanged = true; } if (PerforceEnabled) { float textWidth = 250.0f; float secondtextWidth = 200.0f; int maxFrameCount = 2; // seems to be the right number of repaints needed to display something if (_FrameIndex < maxFrameCount) { EditorGUILayout.HelpBox("Please Wait! Checking Perforce Settings. This can take up to 20 seconds...", MessageType.Info); if (Event.current.type == EventType.Repaint) { ++_FrameIndex; _Repaint = true; } if (_FrameIndex == maxFrameCount) { // Force update the config state at least once ConfigurationState oldState = _CurrentState; _CurrentState = ConfigurationState.Unknown; UpdateConfigState(); if (_CurrentState != oldState) { _SettingsChanged = true; } } } else { GUILayout.Label("Connection Settings", EditorStyles.boldLabel); if (_CurrentState >= ConfigurationState.MetaFilesValid) { EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical(); // The edit field for the server bool newUseP4Config = EditorGUILayout.Toggle("\tUse P4Config", UseP4Config); if (newUseP4Config != UseP4Config) { if (newUseP4Config == true) { p4configFile = FindP4ConfigFile(); if (p4configFile != null) LoadP4ConfigFile(p4configFile); } UseP4Config = newUseP4Config; _CurrentState = ConfigurationState.P4ConfigValid; _SettingsChanged = true; } EditorGUILayout.EndVertical(); EditorGUI.BeginDisabledGroup(UseP4Config); { if (string.IsNullOrEmpty(p4configFile)) { GUILayout.Label("Not Found"); } else { GUILayout.Label(Path.GetFullPath(p4configFile)); // Show the name of the config file } } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndHorizontal(); // Don't let the user change any of the remaining settings unless the DLL is valid EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical(); // The edit field for the server string newServerURI = EditorGUILayout.TextField("\tServer URI", ServerURI); if (newServerURI != ServerURI) { ServerURI = newServerURI; _CurrentState = ConfigurationState.MetaFilesValid; _SettingsChanged = true; } EditorGUILayout.EndVertical(); // The button to verify it bool serverValid = _CurrentState >= ConfigurationState.ServerValid; EditorGUI.BeginDisabledGroup(serverValid); { if (GUILayout.Button(serverValid ? "Valid!" : "Verify", EditorStyles.miniButton, _ButtonWidth)) { checkSettings = true; } } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndHorizontal(); if (_CurrentState == ConfigurationState.ServerInvalid) { EditorGUILayout.HelpBox("Invalid Server URI", MessageType.Error); } EditorGUI.BeginDisabledGroup(_CurrentState < ConfigurationState.ServerValid); { EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical(); // The edit field for the username string newUsername = EditorGUILayout.TextField("\tUsername", Username); if (newUsername != Username) { Username = newUsername; _CurrentState = ConfigurationState.ServerValid; _SettingsChanged = true; } // The edit field for the password string newPassword = EditorGUILayout.PasswordField("\tPassword", Password); if (newPassword != Password) { Password = newPassword; _CurrentState = ConfigurationState.ServerValid; _SettingsChanged = true; } EditorGUILayout.EndVertical(); // And the button to verify it bool passwordValid = _CurrentState >= ConfigurationState.UsernamePassValid; EditorGUI.BeginDisabledGroup(passwordValid); { if (GUILayout.Button(passwordValid ? "Valid!" : "Verify", EditorStyles.miniButton, _ButtonWidth)) { checkSettings = true; } } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndHorizontal(); if (_CurrentState == ConfigurationState.UsernamePassInvalid) { EditorGUILayout.HelpBox("Invalid Username / Password", MessageType.Error); } EditorGUI.BeginDisabledGroup(_CurrentState < ConfigurationState.UsernamePassValid); { EditorGUILayout.BeginHorizontal(); { // The edit field for the workspace string newWorkspace = EditorGUILayout.TextField("\tWorkspace", Workspace); if (newWorkspace != Workspace) { Workspace = newWorkspace; _CurrentState = ConfigurationState.UsernamePassValid; _SettingsChanged = true; } // And the check button bool workspaceValid = _CurrentState >= ConfigurationState.ProjectRootValid; EditorGUI.BeginDisabledGroup(workspaceValid); { if (GUILayout.Button(workspaceValid ? "Valid!" : "Verify", EditorStyles.miniButton, _ButtonWidth)) { checkSettings = true; } } EditorGUI.EndDisabledGroup(); } 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); } } EditorGUI.EndDisabledGroup(); } EditorGUI.EndDisabledGroup(); GUILayout.Label("Interface", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tDisplay Status Icons", GUILayout.Width(textWidth)); bool newDisplayIcons = EditorGUILayout.Toggle(DisplayStatusIcons, GUILayout.Width(16.0f)); if (newDisplayIcons != DisplayStatusIcons) { DisplayStatusIcons = newDisplayIcons; _SettingsChanged = true; Icons.UpdateDisplay(); PendingChanges.UpdateDisplay(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tShow File Paths in Console", GUILayout.Width(textWidth)); bool newShowPaths = EditorGUILayout.Toggle(ShowPaths, GUILayout.Width(16.0f)); if (newShowPaths != ShowPaths) { ShowPaths = newShowPaths; _SettingsChanged = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); string newDiffToolPathname = EditorGUILayout.TextField("\tDiff Tool Executable", DiffToolPathname); if (newDiffToolPathname != DiffToolPathname) { DiffToolPathname = newDiffToolPathname; _SettingsChanged = true; } if (GUILayout.Button("Browse...", EditorStyles.miniButton, GUILayout.Width(80.0f))) { GUI.FocusControl(""); DiffToolPathname = EditorUtility.OpenFilePanel("Choose Diff Tool Executable", System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles), ""); _SettingsChanged = true; } EditorGUILayout.EndHorizontal(); GUILayout.Label("Behaviour", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tAsk before checkout on edit", GUILayout.Width(textWidth)); bool newAskBeforeCheckout = EditorGUILayout.Toggle(AskBeforeCheckout, GUILayout.Width(16.0f)); if (newAskBeforeCheckout != AskBeforeCheckout) { AskBeforeCheckout = newAskBeforeCheckout; _SettingsChanged = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tShow warning when adding files with reserved characters (@#*%)", GUILayout.Width(textWidth)); bool newWarnOnSpecialChar = EditorGUILayout.Toggle(WarnOnSpecialCharacters, GUILayout.Width(16.0f)); if (newWarnOnSpecialChar != WarnOnSpecialCharacters) { WarnOnSpecialCharacters = newWarnOnSpecialChar; _SettingsChanged = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tInclude Solution Files", GUILayout.Width(textWidth)); bool newIncludeSolutionFiles = EditorGUILayout.Toggle(IncludeSolutionFiles, GUILayout.Width(16.0f)); if (newIncludeSolutionFiles != IncludeSolutionFiles) { IncludeSolutionFiles = newIncludeSolutionFiles; _SettingsChanged = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tInclude Projects Files", GUILayout.Width(textWidth)); bool newIncludeProjectFiles = EditorGUILayout.Toggle(IncludeProjectFiles, GUILayout.Width(16.0f)); if (newIncludeProjectFiles != IncludeProjectFiles) { IncludeProjectFiles = newIncludeProjectFiles; _SettingsChanged = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tIntegrate with UnityVS", GUILayout.Width(textWidth)); bool newUnityVSSupport = EditorGUILayout.Toggle(UnityVSSupport, GUILayout.Width(16.0f)); if (newUnityVSSupport != UnityVSSupport) { UnityVSSupport = newUnityVSSupport; _SettingsChanged = true; } EditorGUILayout.EndHorizontal(); GUILayout.Label("Advanced", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tOverride P4HOST variable", GUILayout.Width(textWidth)); bool newOverrideP4Host = EditorGUILayout.Toggle(OverrideHostname, GUILayout.Width(16.0f)); if (newOverrideP4Host != OverrideHostname) { OverrideHostname = newOverrideP4Host; _CurrentState = ConfigurationState.MetaFilesValid; _SettingsChanged = true; } EditorGUI.BeginDisabledGroup(!OverrideHostname); GUILayout.Label("Hostname", GUILayout.Width(secondtextWidth)); string newHost = EditorGUILayout.TextField(Hostname, GUILayout.Width(120.0f)); if (newHost != Hostname) { Hostname = newHost; _CurrentState = ConfigurationState.MetaFilesValid; _SettingsChanged = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tOverride P4CHARSET variable", GUILayout.Width(textWidth)); bool newOverrideCharset = EditorGUILayout.Toggle(OverrideCharset, GUILayout.Width(16.0f)); if (newOverrideCharset != OverrideCharset) { OverrideCharset = newOverrideCharset; _CurrentState = ConfigurationState.ServerValid; _SettingsChanged = true; } EditorGUI.BeginDisabledGroup(!OverrideCharset); GUILayout.Label("Charset", GUILayout.Width(secondtextWidth)); string newCharset = EditorGUILayout.TextField(Charset, GUILayout.Width(120.0f)); if (newCharset != Charset) { Charset = newCharset; _CurrentState = ConfigurationState.ServerValid; _SettingsChanged = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tGray out invalid menu options", GUILayout.Width(textWidth)); bool newCheckStatus = EditorGUILayout.Toggle(CheckStatusForMenus, GUILayout.Width(16.0f)); if (newCheckStatus != CheckStatusForMenus) { CheckStatusForMenus = newCheckStatus; _SettingsChanged = true; } EditorGUI.BeginDisabledGroup(!CheckStatusForMenus); GUILayout.Label("Don't check if more than", GUILayout.Width(secondtextWidth)); int newCheckStatusCount = EditorGUILayout.IntField(CheckStatusForMenusMaxItems, GUILayout.Width(40.0f)); if (newCheckStatusCount != CheckStatusForMenusMaxItems) { CheckStatusForMenusMaxItems = newCheckStatusCount; _SettingsChanged = true; } GUILayout.Label("files selected"); GUILayout.FlexibleSpace(); EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tClose Perforce connection after", GUILayout.Width(textWidth)); int newTimeOut = EditorGUILayout.IntField(ConnectionTimeOut, GUILayout.Width(40.0f)); if (newTimeOut != ConnectionTimeOut) { ConnectionTimeOut = newTimeOut; _SettingsChanged = true; } GUILayout.Label("seconds"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tDisplay P4 Timings", GUILayout.Width(textWidth)); bool newDisplayTimings = EditorGUILayout.Toggle(DisplayP4Timings, GUILayout.Width(16.0f)); if (newDisplayTimings != DisplayP4Timings) { DisplayP4Timings = newDisplayTimings; _SettingsChanged = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("\tEcho P4 Commands", GUILayout.Width(textWidth)); bool newDisplayCommands = EditorGUILayout.Toggle(DisplayP4Commands, GUILayout.Width(16.0f)); if (newDisplayCommands != DisplayP4Commands) { DisplayP4Commands = newDisplayCommands; _SettingsChanged = true; } 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()) { _SettingsChanged = true; checkSettings = true; } } } if (checkSettings) { ConfigurationState prevState = _CurrentState; _CurrentState = ConfigurationState.Unknown; // Check the config CheckSettings(); // And notify user if (_CurrentState != prevState) { Icons.UpdateDisplay(); PendingChanges.UpdateDisplay(); } } } EditorGUILayout.EndToggleGroup(); // Info message GUILayout.FlexibleSpace(); if (PerforceEnabled && _CurrentState != ConfigurationState.SettingsValid) { EditorGUILayout.HelpBox("Perforce Integration is inactive. Please Verify your Settings!", MessageType.Warning); } else if (_SettingsChanged) { if (PerforceEnabled) { EditorGUILayout.HelpBox("Perforce Integration is active.", MessageType.Info); } else { EditorGUILayout.HelpBox("Perforce Integration is turned off.", MessageType.Info); } WritePrefs(); } EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("P4Connect", 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 OnInspectorUpdate() { if (_Repaint) { _Repaint = false; Repaint(); } } // Utility method to read connection prefs from the registry public static void ReadPrefs() { // Check if the keys exist, and if so, read the values out // Otherwise, leave the default values if (HasPref(ServerURIPrefName)) ServerURI = GetPrefString(ServerURIPrefName); if (HasPref(UserNamePrefName)) Username = GetPrefString(UserNamePrefName); if (HasPref(PasswordPrefName)) Password = Secure.DecryptString(GetPrefString(PasswordPrefName)); if (HasPref(WorkspacePrefName)) Workspace = GetPrefString(WorkspacePrefName); if (HasPref(P4ConfigPrefName)) UseP4Config = GetPrefBool(P4ConfigPrefName); if (HasPref(DLLLocationPrefName)) DLLLocation = GetPrefString(DLLLocationPrefName); if (HasPref(ConfigurationStateName)) { _CurrentState = (ConfigurationState)GetPrefInt(ConfigurationStateName); if (_CurrentState > ConfigurationState.SettingsValid) { _CurrentState = ConfigurationState.Unknown; } } if (HasPref(PerforceEnabledPrefName)) PerforceEnabled = GetPrefBool(PerforceEnabledPrefName); 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)) DisplayStatusIcons = GetPrefBool(DisplayStatusIconsPrefName); if (HasPref(HostnamePrefName)) Hostname = GetPrefString(HostnamePrefName); if (HasPref(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); // Notify users that prefs changed if (PrefsChanged != null) PrefsChanged(); } // Utility method to write our the connection prefs to the registry public static void WritePrefs() { SetPrefString(ServerURIPrefName, ServerURI); SetPrefString(UserNamePrefName, Username); SetPrefString(PasswordPrefName, Secure.EncryptString(Password)); SetPrefString(WorkspacePrefName, Workspace); SetPrefBool(P4ConfigPrefName, UseP4Config); SetPrefString(DLLLocationPrefName, DLLLocation); SetPrefInt(ConfigurationStateName, (int)_CurrentState); 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); // Notify users that prefs changed if (PrefsChanged != null) PrefsChanged(); } static string GetFullPrefName(string aPrefName) { return "P4Connect_" + Main.ProjectName + "_" + aPrefName; } static bool HasPref(string aPrefName) { return EditorPrefs.HasKey(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)); } public static SerializationMode CachedSerializationMode { get; private set; } public static string FindP4ConfigFile() { string directoryName; string p4config = Environment.GetEnvironmentVariable("P4CONFIG"); if (p4config != null) { string path = Application.dataPath; while (path != null) { directoryName = Path.GetDirectoryName(path); string[] files = System.IO.Directory.GetFiles(directoryName, p4config); 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; } } } file.Close(); } } }