using UnityEditor; using UnityEngine; using System; using System.Collections.Generic; using System.Linq; using System.Text; using Perforce.P4; using log4net; namespace P4Connect { public class Menus { private static readonly ILog log = LogManager.GetLogger(typeof(Menus)); #region Perforce Menus [MenuItem("Assets/Perforce/Refresh", true, 100)] public static bool ProjectViewCanRefresh() { return Config.ValidConfiguration; } [MenuItem("Assets/Perforce/Refresh", false, 100)] public static void ProjectViewRefresh() { // This command should go to the server to re-download everything. var paths = Utils.GetDeepSelectedEffectivePaths(); //log.Debug("Refresh Called on: " + Logger.StringArrayToString(paths.ToArray())); AssetStatusCache.Refresh(paths); Icons.UpdateDisplay(); } [MenuItem("Assets/Perforce/Add to Depot", true, 100)] public static bool ProjectViewCanAddToDepot() { if (!Config.ValidConfiguration) return false; bool canAdd = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canAdd = false; Engine.PerformConnectionOperation(con => { List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); // And indicate we can add to the depot if at least one of them isn't in the depot canAdd = statuses.Any(status => status.LocalState == FileState.None || (status.LocalState == FileState.InDepot && status.DepotState == DepotState.Deleted)); }); } } return canAdd; } [MenuItem("Assets/Perforce/Add to Depot", false, 100)] public static void ProjectViewAddToDepot() { List<string> addFiles = new List<string>(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection IEnumerable<string> paths = Utils.GetDeepSelectedEffectivePaths().AssetToLocalPaths(); List<string> xpaths = Utils.ExplodeLocalPaths(paths).ToList(); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, xpaths); for (int i = 0; i < xpaths.Count; ++i) { // Add directories, Add files not in the depot, add files which are in perforce but deleted previously, //if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState == FileState.None || (statuses[i].LocalState == FileState.InDepot && statuses[i].DepotState == DepotState.Deleted)) if (statuses[i].LocalState == FileState.None || statuses[i].LocalState == FileState.InDepot) { addFiles.Add(xpaths[i]); } } }); log.Debug("ATD adding: " + Logger.StringArrayToString(addFiles.ToArray())); if (Engine.CreateAssets(addFiles.ToArray()).Count == 0) { Debug.Log("P4Connect - Add to Depot - No Changes"); } } [MenuItem("Assets/Perforce/Checkout", true, 100)] public static bool ProjectViewCanCheckoutAsset() { if (!Config.ValidConfiguration) return false; bool canCheckout = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canCheckout = false; Engine.PerformConnectionOperation(con => { List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); // And indicate we can add to the depot if at least one of them in the depot for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState == FileState.InDepot) { canCheckout = true; } } }); } } return canCheckout; } [MenuItem("Assets/Perforce/Checkout", false, 100)] public static void ProjectViewCheckoutAsset() { List<string> checkoutFiles = new List<string>(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].IsOnServer()) { checkoutFiles.Add(paths[i]); } } }); if (Engine.CheckoutAssets(checkoutFiles.ToArray()).Count == 0) { Debug.Log("P4Connect - Checkout - No Changes"); } } [MenuItem("Assets/Perforce/Lock", true, 100)] public static bool ProjectViewCanLockAsset() { if (!Config.ValidConfiguration) return false; bool canLock = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canLock = false; Engine.PerformConnectionOperation(con => { List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); // And indicate we can add to the depot if at least one of them in the depot for (int i = 0; i < paths.Count; ++i) { if ((statuses[i].IsOpened() && !statuses[i].IsLocked()) || Utils.IsDirectory(paths[i])) { canLock = true; } } }); } } return canLock; } [MenuItem("Assets/Perforce/Lock", false, 100)] public static void ProjectViewLockAsset() { List<string> lockFiles = new List<string>(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || !statuses[i].IsLocked()) { lockFiles.Add(paths[i]); } } }); if (Engine.LockAssets(lockFiles.ToArray()).Count == 0) { Debug.Log("P4Connect - Lock - No Changes"); } } [MenuItem("Assets/Perforce/Unlock", true, 100)] public static bool ProjectViewCanUnlockAsset() { if (!Config.ValidConfiguration) return false; bool canUnlock = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canUnlock = false; Engine.PerformConnectionOperation(con => { List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); // And indicate we can add to the depot if at least one of them in the depot for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LockState == LockState.OurLock) { canUnlock = true; } } }); } } return canUnlock; } [MenuItem("Assets/Perforce/Unlock", false, 100)] public static void ProjectViewUnlockAsset() { List<string> unlockFiles = new List<string>(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LockState == LockState.OurLock) { unlockFiles.Add(paths[i]); } } }); if (Engine.UnlockAssets(unlockFiles.ToArray()).Count == 0) { Debug.Log("P4Connect - Unlock - No Changes"); } } [MenuItem("Assets/Perforce/Get Latest Revision", true, 100)] public static bool ProjectViewCanGetLatest() { return Config.ValidConfiguration; } [MenuItem("Assets/Perforce/Get Latest Revision", false, 100)] public static void ProjectViewGetLatest() { //Debug.Log("XYZZY"); // Grab all the items in the selection, add directory wildcards if needed List<string> paths = Utils.GetDeepSelectedEffectivePaths().AddDirectoryWildcards().ToList(); Debug.Log("WithDirs: " + Logger.StringArrayToString(paths.ToArray())); List<string> noDirPaths = paths.StripDirectories().ToList(); Debug.Log("noDirs: " + Logger.StringArrayToString(noDirPaths.ToArray())); List<string> getLatestFiles = new List<string>(); // Get Asset statuses for non-directores (if any). Then add them to list if in Perforce if (noDirPaths.Count != 0) { Engine.PerformConnectionOperation(con => { List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, noDirPaths); for (int i = 0; i < noDirPaths.Count; ++i) { if (statuses[i].LocalState != FileState.None) { getLatestFiles.Add(noDirPaths[i]); } } }); } // Always add the directories List<string> dpaths = paths.JustDirectories().ToList(); foreach (string p in dpaths) { getLatestFiles.Add(p); } string[] aGetLatestFiles = getLatestFiles.ToArray(); //log.Debug("Filtered: " + Logger.StringArrayToString(aGetLatestFiles)); if (getLatestFiles.Count() > 0) { if (Engine.GetLatestAssets(aGetLatestFiles, false).Count == 0) { Debug.Log("P4Connect - Get Latest Revision - No Changes"); } } } [MenuItem("Assets/Perforce/Force Get Latest Revision", true, 100)] public static bool ProjectViewCanForceGetLatest() { return Config.ValidConfiguration; } [MenuItem("Assets/Perforce/Force Get Latest Revision", false, 100)] public static void ProjectViewForceGetLatest() { List<string> getLatestFiles = new List<string>(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); log.Debug("Selected: " + Logger.StringArrayToString(paths.ToArray())); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState != FileState.None) { getLatestFiles.Add(paths[i]); } } }); string[] aGetLatestFiles = getLatestFiles.ToArray(); log.Debug("Filtered: " + Logger.StringArrayToString(aGetLatestFiles)); if (aGetLatestFiles.Count() > 0) { // Build a string of the names StringBuilder builder = new StringBuilder(); builder.AppendLine("Are you sure you want to force-get the latest revision of the following assets?"); builder.AppendLine(); foreach (string path in getLatestFiles) { builder.AppendLine(path); } if (EditorUtility.DisplayDialog("P4Connect - Force Get Latest", builder.ToString(), "Yes", "No")) { if (Engine.GetLatestAssets(getLatestFiles.ToArray(), true).Count == 0) { Debug.Log("P4Connect - Force Get Latest - No Changes"); } } } } [MenuItem("Assets/Perforce/Diff against Have-Revision", true, 100)] public static bool ProjectViewCanDiffAsset() { if (!Config.ValidConfiguration) return false; bool canDiff = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canDiff = false; Engine.PerformConnectionOperation(con => { List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState != FileState.None) { canDiff = true; } } }); } } return canDiff; } [MenuItem("Assets/Perforce/Diff against Have-Revision", false, 100)] public static void ProjectViewDiffAsset() { List<string> diffFiles = new List<string>(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState != FileState.None) { diffFiles.Add(paths[i]); } } }); foreach (string file in diffFiles) { if (Utils.IsDirectory(file)) Utils.LaunchDiffAgainstHaveRev(Utils.MetaFromAsset(file)); else Utils.LaunchDiffAgainstHaveRev(file); } } [MenuItem("Assets/Perforce/Revert if Unchanged", true, 100)] public static bool ProjectViewCanRevertIfUnchanged() { return ProjectViewCanRevertAsset(); } [MenuItem("Assets/Perforce/Revert if Unchanged", false, 100)] public static void ProjectViewRevertAssetIfUnchanged() { List<string> assetsToRevert = new List<string>(); // Grab the statuses of all the items in the selection Engine.PerformConnectionOperation(con => { List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState != FileState.InDepot) { assetsToRevert.Add(paths[i]); } } }); if (Engine.RevertAssets(assetsToRevert.ToArray(), false).Count == 0) { Debug.Log("P4Connect - Revert if unchanged - No Changes"); } } [MenuItem("Assets/Perforce/Revert", true, 100)] public static bool ProjectViewCanRevertAsset() { if (!Config.ValidConfiguration) return false; bool canRevert = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canRevert = false; Engine.PerformConnectionOperation(con => { List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState != FileState.InDepot) { canRevert = true; } } }); } } return canRevert; } [MenuItem("Assets/Perforce/Revert", false, 100)] public static void ProjectViewRevertAsset() { List<string> revertFiles = new List<string>(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState != FileState.InDepot) { revertFiles.Add(paths[i]); } } }); // Build a string of the names StringBuilder builder = new StringBuilder(); builder.AppendLine("Are you sure you want to revert the following assets?"); builder.AppendLine(); foreach (string path in revertFiles) { builder.AppendLine(path); } if (EditorUtility.DisplayDialog("P4Connect - Revert", builder.ToString(), "Yes", "No")) { if (Engine.RevertAssets(revertFiles.ToArray(), true).Count == 0) { Debug.Log("P4Connect - Revert - No Changes"); } } } [MenuItem("Assets/Perforce/Commit...", true, 100)] public static bool ProjectViewCanCommitAsset() { if (!Config.ValidConfiguration) return false; bool canCommit = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canCommit = false; Engine.PerformConnectionOperation(con => { List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); // We can only commit is all files can be committed for (int i = 0; i < paths.Count; ++i) { if (!Utils.IsDirectory(paths[i]) && (statuses[i].LocalState == FileState.MarkedForEdit || statuses[i].LocalState == FileState.MarkedForAdd || statuses[i].LocalState == FileState.MarkedForDelete || statuses[i].LocalState == FileState.MarkedForAddMove || statuses[i].LocalState == FileState.MarkedForDeleteMove) && statuses[i].LockState != LockState.TheirLock) { canCommit = true; } } }); } } return canCommit; } [MenuItem("Assets/Perforce/Commit...", false, 100)] public static void ProjectViewCommitAsset() { List<string> commitFiles = new List<string>(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List<string> paths = Utils.GetDeepSelectedEffectivePaths().ToList(); List<AssetStatusCache.AssetStatus> statuses = AssetStatusCache.GetAssetStatusesFromPaths(con, paths); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState == FileState.MarkedForEdit || statuses[i].LocalState == FileState.MarkedForAdd || statuses[i].LocalState == FileState.MarkedForDelete || statuses[i].LocalState == FileState.MarkedForAddMove || statuses[i].LocalState == FileState.MarkedForDeleteMove) { commitFiles.Add(paths[i]); } } }); // Show the pending changes window and select only the files in the commit list PendingChanges window = EditorWindow.GetWindow(typeof(PendingChanges), false, "Perforce") as PendingChanges; window.SelectAssets(commitFiles); } #endregion #region PendingChanges Menus // Menu entries associated with the Pending Changes Dialog [MenuItem("CONTEXT/Perforce/Select in Project View", false, 10)] public static void SelectInProjectView(MenuCommand aCommand) { PendingChanges changes = aCommand.context as PendingChanges; List<UnityEngine.Object> objects = new List<UnityEngine.Object>(changes.SelectedAssets.Select(path => AssetDatabase.LoadMainAssetAtPath(path))); Selection.objects = objects.ToArray(); EditorUtility.FocusProjectWindow(); } [MenuItem("CONTEXT/Perforce/Force Get Latest Revision", false, 10)] public static void ProjectViewForceGetLatest1(MenuCommand aCommand) { PendingChanges changes = aCommand.context as PendingChanges; List<string> assets = new List<string>(changes.SelectedAssets); log.Debug("files: " + Logger.StringArrayToString(assets.ToArray())); if (assets.Count == 0) return; // Build a string of the names StringBuilder builder = new StringBuilder(); builder.AppendLine("Are you sure you want to force-get the latest revision of the following assets?"); builder.AppendLine(); foreach (string path in assets) { builder.AppendLine(path); } if (EditorUtility.DisplayDialog("P4Connect - Force Get Latest", builder.ToString(), "Yes", "No")) { Engine.GetLatestAssets(assets.ToArray(), true); } } [MenuItem("CONTEXT/Perforce/Revert if Unchanged", false, 10)] public static void RevertAssetIfUnchanged(MenuCommand aCommand) { PendingChanges changes = aCommand.context as PendingChanges; List<string> assets = new List<string>(changes.SelectedAssets); log.Debug("files: " + Logger.StringArrayToString(assets.ToArray())); Engine.RevertAssets(assets.ToArray(), false); } [MenuItem("CONTEXT/Perforce/Revert", false, 10)] public static void RevertAsset(MenuCommand aCommand) { // Grab the selected assets PendingChanges changes = aCommand.context as PendingChanges; List<string> assets = new List<string>(changes.SelectedAssets); log.Debug("files: " + Logger.StringArrayToString(assets.ToArray())); // Build a string of the names StringBuilder builder = new StringBuilder(); builder.AppendLine("Are you sure you want to revert the following assets?"); builder.AppendLine(); foreach (string path in assets) { builder.AppendLine(path); } if (EditorUtility.DisplayDialog("P4Connect - Revert", builder.ToString(), "Yes", "No")) { Engine.RevertAssets(assets.ToArray(), true); } } [MenuItem("CONTEXT/Perforce/Diff against Have-Revision", false, 10)] public static void DiffAsset(MenuCommand aCommand) { // Grab the selected assets PendingChanges changes = aCommand.context as PendingChanges; List<string> assets = new List<string>(changes.SelectedAssets); foreach (string asset in assets) { Utils.LaunchDiffAgainstHaveRev(asset); } } [MenuItem("CONTEXT/Perforce/Lock", false, 10)] public static void LockAsset(MenuCommand aCommand) { // Grab the selected assets PendingChanges changes = aCommand.context as PendingChanges; List<string> assets = new List<string>(changes.SelectedAssets); log.Debug("files: " + Logger.StringArrayToString(assets.ToArray())); Engine.LockAssets(assets.ToArray()); } [MenuItem("CONTEXT/Perforce/Unlock", false, 10)] public static void UnlockAsset(MenuCommand aCommand) { PendingChanges changes = aCommand.context as PendingChanges; List<string> assets = new List<string>(changes.SelectedAssets); log.Debug("files: " + Logger.StringArrayToString(assets.ToArray())); Engine.UnlockAssets(assets.ToArray()); } #endregion } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 22026 | prizkall |
Populate -o //guest/perforce_software/p4connect/... //guest/prizkall/p4connect/.... |
||
//guest/perforce_software/p4connect/dev/shelves/src/P4Connect/P4Connect/P4Connect.Menus.cs | |||||
#1 | 17331 | Norman Morse | Dev branch for Shelves | ||
//guest/perforce_software/p4connect/main/src/P4Connect/P4Connect/P4Connect.Menus.cs | |||||
#3 | 16485 | Norman Morse |
Asynchronous status requests Update release notes Minor cleanup |
||
#2 | 16413 | Norman Morse | Code cleanup | ||
#1 | 16209 | Norman Morse | Move entire source tree into "main" branch so workshop code will act correctly. | ||
//guest/perforce_software/p4connect/src/P4Connect/P4Connect/P4Connect.Menus.cs | |||||
#8 | 16117 | Norman Morse |
Fix for EditorPrefs related Disconnection. Cleaned up some code. Removed Spurious Comments Initialize Config from within Main |
||
#7 | 15424 | Norman Morse |
Fixed exceptions in Dialogs. Updated release Notes. Added checks to menus for PerforceEnabled |
||
#6 | 15401 | Norman Morse |
Fixed serialization of Config so P4Connect remains connected after a Game Run Cleaned up some menus. |
||
#5 | 15383 | Norman Morse |
Improved Diagnostics, cleaned up unnecessary log output Moved some Dialog Initialization to OnEnable() Fixed Unity 5.1.1 incompatibilities Added Operation support for In Depot Deleted files |
||
#4 | 15244 | Norman Morse |
Better Directory support in "add" "get latest" "refresh" and other commands. Improved Project Root detection Various Bug Fixes and Clean up |
||
#3 | 15079 | Norman Morse |
Rewrote AssetStatusCache to Cache AssetStatuses and FileMetaData Fixed Edge conditions on Engine Operations Change Debug output defaults. Will now Checkout files which request to be "added" but which already exist in perforce. Output P4Connect version to log on initialization. |
||
#2 | 14193 | Norman Morse |
GA.7 release Refactor Pending Changes Resolve Submit issues. Fixed Menu entries. Handle mismatched file and meta states. |
||
#1 | 10940 | Norman Morse |
Inital Workshop release of P4Connect. Released under BSD-2 license |