// // Copyright 2014 Perforce Software Inc. // using Perforce.View; using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Runtime.Remoting.Metadata.W3cXsd2001; using Perforce.P4; using Perforce.ViewModel; using Perforce.Model; namespace Perforce.Helper { public class ListingHelper { // method to get listings from Perforce public static IList GetDepotDirsAndFiles(ColumnDisplay column, string basePath) { Log.TraceFunction(); if (string.IsNullOrEmpty(basePath)) { basePath = "//"; } //UIHelper.SetBusyState(); var list = new List(); //var helper = Utility.GetPerforceHelper(); var p4 = Utility.GetPerforceHelper(check:true); if (basePath.Equals("//")) { // get list of available depots (local only -- no streams) var depotList = p4.ListDepots(true); if (depotList == null) return list; foreach (var depot in depotList) { var item = new FolderItem(); item.LabelText = depot.Id; item.ColumnContext = column; item.DepotPath = string.Format("//{0}", depot.Id); var paths = new List(); paths.Add(item.DepotPath); var mappings = p4.GetClientMappings(paths, pathsAreDirectories: true); if (mappings.IsDirMapped(item.DepotPath)) { item.ClientPath = mappings.GetMappedDir(item.DepotPath); } item.IsMapped = p4.IsDirectoryMapped(item.DepotPath); item.IsTopLevelMapping = p4.ClientFolderMappingContains(item.DepotPath); item.IsPathInClientView = p4.IsPathInClientView(item.DepotPath); list.Add(item); } } else { var dirList = p4.ListDirectories(basePath); if (dirList == null) return list; var mappings = p4.GetClientMappings(dirList, true); foreach (var dir in dirList) { var dirName = dir.Replace(basePath, string.Empty); if (dirName.StartsWith("/")) { dirName = dirName.Remove(0, 1); } var item = new FolderItem(); item.LabelText = dirName; item.ColumnContext = column; item.DepotPath = dir; item.IsMapped = mappings.IsDirMapped(dir); if (item.IsMapped) { item.ClientPath = mappings.GetMappedDir(item.DepotPath); } item.IsTopLevelMapping = p4.ClientFolderMappingContains(item.DepotPath); item.IsPathInClientView = p4.IsPathInClientView(item.DepotPath); list.Add(item); } var metadataList = p4.ListFiles(depotPath: basePath + "/*", showDeleted: false); if (metadataList != null) { foreach (var md in metadataList) { var item = new FileItem(); item.LabelText = md.GetFileName(); item.Metadata = md; item.ColumnContext = column; list.Add(item); } } } return list; } // method to get listings from the filesystem public static IList GetLocalDirsAndFiles(ColumnDisplay column, string dirName) { Log.TraceFunction(); var p4 = Utility.GetPerforceHelper(); if (string.IsNullOrEmpty(dirName)) { dirName = p4.CurrentClient.Root; } //UIHelper.SetBusyState(); var list = new List(); var di = new DirectoryInfo(dirName); if (di.Exists) { var dirs = di.GetDirectories(); var paths = new List(); foreach (var d in dirs) { paths.Add(d.FullName); } var mappings = p4.GetDepotMappings(paths, true); foreach (var d in dirs) { var item = new FolderItem(); item.LabelText = d.Name; item.ColumnContext = column; item.ClientPath = d.FullName; var normalizedPath = Utility.NormalizeClientPath(d.FullName); item.IsMapped = mappings.IsDirMapped(normalizedPath); item.IsTopLevelMapping = p4.ClientFolderMappingContains(d.FullName); item.DepotPath = p4.PredictDepotPath(d.FullName); item.IsPathInClientView = p4.IsPathInClientView(item.DepotPath); list.Add(item); } var files = di.GetFiles(); var fileList = new List(); foreach (var f in files) { fileList.Add(f.FullName); } var results = p4.GetFileMetaData(fileList); var metadataMap = new Dictionary(StringComparer.CurrentCultureIgnoreCase); if (results != null) { foreach (var md in results) { metadataMap.Add(md.ClientPath.Path, md); } } foreach (var f in files) { var item = new FileItem(); item.LabelText = f.Name; item.ColumnContext = column; if (metadataMap.ContainsKey(f.FullName)) { item.Metadata = metadataMap[f.FullName]; } else { // fake out the file metadata var metadata = new FileMetaData(); metadata.IsMapped = false; metadata.DepotPath = new DepotPath(Constants.DUMMY_DEPOT_PATH); metadata.ClientPath = new ClientPath(f.FullName); item.Metadata = metadata; } list.Add(item); } } return list; } public static IList GetSearchResults(ColumnDisplay column, string[] tagFilter = null) { Log.TraceFunction(); var list = new List(); // get the search view model var model = column.Selector.Model as SearchSelectorViewModel; if (model.SearchStr != null) { // get the search helper var searchHelper = Utility.GetSearchHelper(); if (searchHelper != null) { var results = searchHelper.DoSearch(model.SearchStr, files: model.FileSearch, content: model.ContentSearch, tags: model.TagSearch); if (results.Count > 0) { var paths = new List(); foreach (var r in results) { paths.Add(r.depotFile); } List uniquePaths = paths.Distinct().ToList(); var helper = Utility.GetPerforceHelper(); var metadataList = helper.GetSearchFileMetaData(uniquePaths, mappedOnly: model.MyWorkspaceLocation); if (metadataList != null) { foreach (var md in metadataList) { if (model.RestrictSearchToFolder) { if (!md.DepotPath.Path.StartsWith(model.DepotPath, StringComparison.InvariantCultureIgnoreCase)) continue; } if (tagFilter != null && tagFilter.Count() > 0) { // skip if there are no tags if (!md.Attributes.ContainsKey("tags")) continue; var hexTags = md.Attributes["tags"] as string; var tagList = ListingHelper.HexToString(hexTags).Split(','); var foundAllTagFilters = true; foreach (var t in tagFilter) { if (!string.IsNullOrEmpty(t)) { if (!tagList.Contains(t)) foundAllTagFilters = false; } } if (!foundAllTagFilters) continue; } var item = new FileItem(); item.LabelText = md.GetFileName(); item.Metadata = md; item.ColumnContext = column; list.Add(item); } } } } } return list; } public static IList GetChangelistFiles(ColumnDisplay column) { Log.TraceFunction(); var list = new List(); var p4 = Utility.GetPerforceHelper(); if (p4 != null && p4.ClientEnabled) { var changeFiles = p4.GetChangelistFiles(); if (changeFiles != null && changeFiles.Count > 0) { var flist = new List(); foreach (var f in changeFiles) { if (f.Action.Equals(FileAction.Delete)) continue; flist.Add(PerforceHelper.UnescapePath(f.DepotPath.Path)); } var mdsList = p4.RunFstat(flist); if (mdsList != null) { foreach (var md in mdsList) { var item = new FileItem(); item.LabelText = PerforceHelper.UnescapePath(md.GetFileName()); item.ColumnContext = column; item.Metadata = md; list.Add(item); } } } } return list; } public static IList GetTrashFiles(ColumnDisplay column) { Log.TraceFunction(); var list = new List(); var helper = Utility.GetPerforceHelper(); if (helper != null && helper.ClientEnabled) { //UIHelper.SetBusyState(); var changeFiles = helper.GetChangelistFiles(); if (changeFiles != null && changeFiles.Count > 0) { foreach (var f in changeFiles) { if (f.Action.Equals(FileAction.Delete)) { var item = new FileItem(); item.LabelText = PerforceHelper.UnescapePath(f.GetFileName()); item.ColumnContext = column; item.Metadata = helper.RunFstat(f.DepotPath.Path); list.Add(item); } } } } return list; } public static IList GetRecentFiles(ColumnDisplay column) { Log.TraceFunction(); var list = Utility.GetRecentList(); if (list != null && list.Count > 0) { foreach (var i in list) { i.ColumnContext = column; } } return list; } public static ListingItem GetItem(string path, ColumnDisplay column, bool isDirectory = false) { Log.TraceFunction(); ListingItem item = null; var helper = Utility.GetPerforceHelper(); if (isDirectory) { item = new FolderItem(); if (Utility.IsDepotPath(path)) { item.DepotPath = path; var paths = new List(); paths.Add(path); var mappings = helper.GetClientMappings(paths, true); if (mappings.IsDirMapped(path)) { item.ClientPath = mappings.GetMappedDir(path); item.IsMapped = true; } else { item.ClientPath = helper.PredictClientPath(path); item.IsMapped = false; } } else { item.ClientPath = path; var paths = new List(); paths.Add(path); var mappings = helper.GetDepotMappings(paths, true); if (mappings.IsDirMapped(path)) { item.DepotPath = mappings.GetMappedDir(path); item.IsMapped = true; } else { item.DepotPath = Constants.DUMMY_DEPOT_PATH; item.IsMapped = false; } } var parts = path.Split('/'); item.LabelText = parts[parts.Length - 1]; } else { var md = helper.RunFstat(path); if (md != null) { item = new FileItem(); item.LabelText = md.GetFileName(); (item as FileItem).Metadata = md; } } if (item != null) item.ColumnContext = column; return item; } public static ListingItem FindItemInList(string label, IList list) { Log.TraceFunction(); ListingItem item = null; foreach (var i in list) { if (label.Equals(i.LabelText, StringComparison.CurrentCultureIgnoreCase)) { item = i; break; } } return item; } public static string HexToString(string hex) { var byteArray = HexToBytes(hex); return System.Text.Encoding.UTF8.GetString(byteArray); } public static byte[] HexToBytes(string value) { SoapHexBinary shb = SoapHexBinary.Parse(value); return shb.Value; } public static string BytesToHex(byte[] value) { SoapHexBinary shb = new SoapHexBinary(value); return shb.ToString(); } public static byte[] GetBytesFromFile(string fullFilePath) { Log.TraceFunction(); // this method is limited to 2^32 byte files (4.2 GB) FileStream fs = null; try { fs = System.IO.File.OpenRead(fullFilePath); byte[] bytes = new byte[fs.Length]; fs.Read(bytes, 0, Convert.ToInt32(fs.Length)); return bytes; } finally { if (fs != null) { fs.Close(); } } } } }