using UnityEditor; using UnityEngine; using System; using System.Collections.Generic; using System.Linq; using System.Text; using Perforce.P4; namespace P4Connect { public class Menus { [MenuItem("Assets/Perforce/Refresh", false, 100)] public static void ProjectViewRefresh() { Icons.UpdateDisplay(); } [MenuItem("Assets/Perforce/Add to Depot", true, 100)] public static bool ProjectViewCanAddToDepot() { bool canAdd = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canAdd = false; List statuses = new List(); Engine.PerformConnectionOperation(con => { AssetStatusCache.GetAssetData(con, paths, statuses); }); // 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 addFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState == FileState.None || (statuses[i].LocalState == FileState.InDepot && statuses[i].DepotState == DepotState.Deleted)) { addFiles.Add(paths[i]); } } }); 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() { bool canCheckout = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canCheckout = false; Engine.PerformConnectionOperation(con => { List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); // 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 checkoutFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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() { bool canLock = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canLock = false; Engine.PerformConnectionOperation(con => { List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); // 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 lockFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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() { bool canUnlock = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canUnlock = false; Engine.PerformConnectionOperation(con => { List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); // 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 unlockFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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", false, 100)] public static void ProjectViewGetLatest() { List getLatestFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState != FileState.None) { getLatestFiles.Add(paths[i]); } } }); if (Engine.GetLatestAssets(getLatestFiles.ToArray(), false).Count == 0) { Debug.Log("P4Connect - Get Latest Revision - No Changes"); } } [MenuItem("Assets/Perforce/Force Get Latest Revision", false, 100)] public static void ProjectViewForceGetLatest() { List getLatestFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); for (int i = 0; i < paths.Count; ++i) { if (Utils.IsDirectory(paths[i]) || statuses[i].LocalState != FileState.None) { getLatestFiles.Add(paths[i]); } } }); // 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() { bool canDiff = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canDiff = false; Engine.PerformConnectionOperation(con => { List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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 diffFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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 assetsToRevert = new List(); // Grab the statuses of all the items in the selection Engine.PerformConnectionOperation(con => { List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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() { bool canRevert = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canRevert = false; Engine.PerformConnectionOperation(con => { List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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 revertFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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() { bool canCommit = true; if (Config.CheckStatusForMenus) { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); if (paths.Count < Config.CheckStatusForMenusMaxItems) { canCommit = false; Engine.PerformConnectionOperation(con => { List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); // 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 commitFiles = new List(); Engine.PerformConnectionOperation(con => { // Grab the statuses of all the items in the selection List paths = Utils.GetDeepSelectedEffectivePaths(); List statuses = new List(); AssetStatusCache.GetAssetData(con, paths, statuses); 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); } [MenuItem("CONTEXT/Perforce/Select in Project View", false, 10)] public static void SelectInProjectView(MenuCommand aCommand) { PendingChanges changes = aCommand.context as PendingChanges; List objects = new List(changes.SelectedAssets.Select(path => AssetDatabase.LoadMainAssetAtPath(path))); Selection.objects = objects.ToArray(); } [MenuItem("CONTEXT/Perforce/Force Get Latest Revision", false, 10)] public static void ProjectViewForceGetLatest(MenuCommand aCommand) { PendingChanges changes = aCommand.context as PendingChanges; List assets = new List(changes.SelectedAssets); // 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 assets = new List(changes.SelectedAssets); 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 assets = new List(changes.SelectedAssets); // 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 assets = new List(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 assets = new List(changes.SelectedAssets); Engine.LockAssets(assets.ToArray()); } [MenuItem("CONTEXT/Perforce/Unlock", false, 10)] public static void UnlockAsset(MenuCommand aCommand) { PendingChanges changes = aCommand.context as PendingChanges; List assets = new List(changes.SelectedAssets); Engine.UnlockAssets(assets.ToArray()); } } }