using UnityEditor; using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using Perforce.P4; using log4net; namespace P4Connect { public static class Menus { private static readonly ILog log = LogManager.GetLogger(typeof(Menus)); // Cached values for the menu validation pass public static List SelectedPaths; public static bool MenuValid; private static string _lastSelection; private static bool _serverRequest; /// /// Menu Validation Common Function /// Caches assetPath list in SelectedPaths /// /// true if this menu is enabled public static bool MenuValidation() { if (!Config.CheckStatusForMenus || ! Config.PerforceEnabled) { return false; } SelectedPaths = Utils.GetSelectedAssetPaths().ToList(); string pathNames = Logger.StringEnumerationToString(SelectedPaths); if (pathNames != _lastSelection) { // log.Debug("Selection Now: " + pathNames); MenuValid = false; _lastSelection = pathNames; if (SelectedPaths.Count < Config.CheckStatusForMenusMaxItems) { if (!_serverRequest) { SelectedPaths.PrepareAssetStatuses(); // request that any Defaults get updated (async request) _serverRequest = true; // Only one request for all Menu Validations } MenuValid = true; Icons.UpdateDisplay(); } } return MenuValid; } #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 will go to the server to re-download everything in the selection, synchronously Engine.PerformConnectionOperation(con => { AssetStatusCache.GetAssetMetaData(con, Utils.GetSelectedAssetPaths().AddDirectoryWildcards()); }, false); Icons.UpdateDisplay(); } [MenuItem("Assets/Perforce/Add to Depot", true, 100)] public static bool ProjectViewCanAddToDepot() { if (! MenuValidation()) return false; foreach (string t in SelectedPaths) { if (Utils.IsDirectory(t) || AssetStatusCache.GetCachedAssetStatus(t).IsAddable()) { return true; } } return false; } [MenuItem("Assets/Perforce/Add to Depot", false, 100)] public static void ProjectViewAddToDepot() { if (!Config.ValidConfiguration) return; List addFiles = new List(); // Grab the statuses of all the items in the selection // If any directories (wildcards) explode into child paths // For each entry, check file status to see if it is addable foreach (string t in SelectedPaths.ExplodeAssetPaths().InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(t); // Add files not in the depot, add files which are in Perforce but deleted previously, if (status.IsAddable()) { addFiles.Add(t); } } var addFilesArray = addFiles.ToArray(); var count = Engine.CreateAssets(addFilesArray).Count; Debug.Log("Add to Depot - " + (count > 0 ? count.ToString() : "No") + " Assets created"); } [MenuItem("Assets/Perforce/Checkout", true, 100)] public static bool ProjectViewCanCheckoutAsset() { if (!MenuValidation()) return false; foreach (string t in SelectedPaths) { if (Utils.IsDirectory(t) || AssetStatusCache.GetCachedAssetStatus(t).IsEditable()) { return true; } } return false; } [MenuItem("Assets/Perforce/Checkout", false, 100)] public static void ProjectViewCheckoutAsset() { if (!Config.ValidConfiguration) return; List checkoutFiles = new List(); foreach (string t in SelectedPaths.InitializeAssetStatuses()) { if (Utils.IsDirectory(t) || AssetStatusCache.GetCachedAssetStatus(t).IsEditable()) { checkoutFiles.Add(t); } } var count = Engine.CheckoutAssets(checkoutFiles.ToArray()).Count; Debug.Log("Checkout - " + (count > 0 ? count.ToString() : "No") + " Assets checked out"); } [MenuItem("Assets/Perforce/Lock", true, 100)] public static bool ProjectViewCanLockAsset() { if (!MenuValidation()) return false; foreach (string t in SelectedPaths) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (status.IsLockable() || Utils.IsDirectory(t)) { return true; } } return false; } [MenuItem("Assets/Perforce/Lock", false, 100)] public static void ProjectViewLockAsset() { if (!Config.ValidConfiguration) return; List lockFiles = new List(); foreach (string t in SelectedPaths.ExplodeAssetPaths().InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (status.IsLockable()) { lockFiles.Add(t); } } var count = Engine.LockAssets(lockFiles.ToArray()).Count; Debug.Log("Lock - " + (count > 0 ? count.ToString() : "No") + " Assets locked"); } [MenuItem("Assets/Perforce/Unlock", true, 100)] public static bool ProjectViewCanUnlockAsset() { if (!MenuValidation()) return false; foreach (string t in SelectedPaths) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (status.IsUnlockable() || Utils.IsDirectory(t)) { return true; } } return false; } [MenuItem("Assets/Perforce/Unlock", false, 100)] public static void ProjectViewUnlockAsset() { if (!Config.ValidConfiguration) return; List unlockFiles = new List(); foreach (string t in SelectedPaths.ExplodeAssetPaths().InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (status.IsUnlockable()) { unlockFiles.Add(t); } } var count = Engine.UnlockAssets(unlockFiles.ToArray()).Count; Debug.Log("Unlock - " + (count > 0 ? count.ToString() : "No") + " Assets unlocked"); } [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() { if (!Config.ValidConfiguration) return; int count = 0; List getLatestFiles = new List(); // Grab all the items in the selection, add directory wildcards if needed var paths = Utils.GetSelectedAssetPaths().AddDirectoryWildcards(); foreach (var f in paths.InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(f); if (status.IsOnServer() || Utils.IsDirectory(f)) { getLatestFiles.Add(f); } } if (getLatestFiles.Any()) { count = Engine.GetLatestAssets(getLatestFiles.ToArray(), false).Count; } Debug.Log("P4Connect - Get Latest Revision - " + (count > 0 ? count.ToString() : "No") + " Assets updated"); } [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() { if (!Config.ValidConfiguration) return; int count = 0; List getLatestFiles = new List(); // Grab all the items in the selection, add directory wildcards if needed var paths = Utils.GetSelectedAssetPaths().AddDirectoryWildcards(); foreach (var f in paths.InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(f); if (status.IsOnServer() || Utils.IsDirectory(f)) { getLatestFiles.Add(f); } } // Grab the statuses of all the items in the selection if (getLatestFiles.Any()) { // 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")) { count = Engine.GetLatestAssets(getLatestFiles.ToArray(), true).Count; } Debug.Log("P4Connect - Force Get Latest Revision - " + (count > 0 ? count.ToString() : "No") + " Assets updated"); } } [MenuItem("Assets/Perforce/Diff against Have-Revision", true, 100)] public static bool ProjectViewCanDiffAsset() { if (!MenuValidation()) return false; foreach (string t in SelectedPaths) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (status.IsOnServer() || Utils.IsDirectory(t)) { return true; } } return false; } [MenuItem("Assets/Perforce/Diff against Have-Revision", false, 100)] public static void ProjectViewDiffAsset() { if (!Config.ValidConfiguration) return; List diffFiles = new List(); foreach (string t in SelectedPaths.InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (status.IsOnServer() || Utils.IsDirectory(t)) { diffFiles.Add(t); } } 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() { if (!Config.ValidConfiguration) return; List assetsToRevert = new List(); foreach (string t in SelectedPaths.InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (status.IsMarked() || Utils.IsDirectory(t)) { assetsToRevert.Add(t); } } int count = Engine.RevertAssets(assetsToRevert.ToArray(), false).Count; Debug.Log("P4Connect - Revert if Unchanged - " + (count > 0 ? count.ToString() : "No") + " Assets reverted"); } [MenuItem("Assets/Perforce/Revert", true, 100)] public static bool ProjectViewCanRevertAsset() { if (!MenuValidation()) return false; foreach (string t in SelectedPaths) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (status.IsMarked() || Utils.IsDirectory(t)) { return true; } } return false; } [MenuItem("Assets/Perforce/Revert", false, 100)] public static void ProjectViewRevertAsset() { if (!Config.ValidConfiguration) return; List revertFiles = new List(); foreach (string t in SelectedPaths.InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (Utils.IsDirectory(t) || status.IsMarked()) { revertFiles.Add(t); } } // 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")) { var count = Engine.RevertAssets(revertFiles.ToArray(), true).Count; Debug.Log("Revert - " + (count > 0 ? count.ToString() : "No") + " Assets reverted"); } } [MenuItem("Assets/Perforce/Commit...", true, 100)] public static bool ProjectViewCanCommitAsset() { if (!MenuValidation()) return false; foreach (string t in SelectedPaths) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (!Utils.IsDirectory(t) && status.IsMarked() && status.LockState != LockState.TheirLock) { return true; } } return false; } [MenuItem("Assets/Perforce/Commit...", false, 100)] public static void ProjectViewCommitAsset() { if (!Config.ValidConfiguration) return; List commitFiles = new List(); foreach (string t in SelectedPaths.InitializeAssetStatuses()) { var status = AssetStatusCache.GetCachedAssetStatus(t); if (!Utils.IsDirectory(t) && status.IsMarked()) { commitFiles.Add(t); } } var count = commitFiles.Count; Debug.Log("Commit - " + (count > 0 ? count.ToString() : "No") + " Assets to commit"); if (count == 0) return; // Show the pending changes window and select only the files in the commit list PendingChanges window = EditorWindow.GetWindow(typeof(PendingChanges), false, "Perforce") as PendingChanges; if (window != null) window.SelectAssets(commitFiles); } [MenuItem("Assets/Perforce/Reconcile", false, 100)] public static void ProjectViewReconcile() { List fsl; // Grab all the items in the selection var paths = Utils.GetSelectedAssetPaths().ToList(); if (paths.Count > 0) { fsl = FileSpec.DepotSpecList(paths.AddDirectoryWildcards().ToArray()).ToList(); } else { fsl = new List { FileSpec.DepotSpec(Config.DepotProjectRoot) }; } Engine.PerformConnectionOperation(con => { ReconcileCmdFlags flags = ReconcileCmdFlags.AddEditDelete | ReconcileCmdFlags.PreviewOnly; Options options = new Options(flags, -1); //List fsl = new List { FileSpec.DepotSpec(Config.DepotProjectRoot) }; IList entries = Engine.Reconcile(con, fsl, options); if (entries == null) { Debug.Log("No Reconcile Results"); } else { Debug.Log("rs: " + Logger.ReconcileEntryListToString(entries)); foreach (var entry in entries) { string path = entry.ToAssetPath(); AssetStatus stat = AssetStatusCache.GetCachedAssetStatus(path); AssetStatusCache.AssetStatusFromReconcileEntry(stat, entry); Debug.Log("as: " + stat.ToStringNullSafe() ); } } }); } #endregion } }