871 lines
34 KiB
C#
871 lines
34 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Forms;
|
|
using System.Windows.Media;
|
|
using System.IO;
|
|
using System.ComponentModel;
|
|
using System.Collections.ObjectModel;
|
|
using System.Text.RegularExpressions;
|
|
using System.Media;
|
|
using JD.Application.View.Misc;
|
|
using JD.Core;
|
|
using JD.Core.Logging;
|
|
using JD.Core.ProjectManaging;
|
|
using JD.Interfaces.Remoting;
|
|
using JD.Perforce;
|
|
using JD.Remoting.Gui;
|
|
using Ubisoft.Perforce.Data;
|
|
using MessageBox = System.Windows.MessageBox;
|
|
|
|
namespace ResourceViewer
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for MainWindow.xaml
|
|
/// </summary>
|
|
public partial class MainWindow : INotifyPropertyChanged, IDisposable
|
|
{
|
|
#region members
|
|
// specific REsourceViewier plugin member
|
|
private readonly ResourceViewerPlugin _plugin = null;
|
|
// engine manager object that manages the connection with the engine
|
|
private readonly EngineManager _engineManager = null;
|
|
|
|
// statistics to be displayed in the left overall resources information grid
|
|
private readonly List<ResourceStatistics> _statistics = new List<ResourceStatistics>()
|
|
{
|
|
new ResourceStatistics(" Selected resources "),
|
|
new ResourceStatistics(" Filtered resources "),
|
|
new ResourceStatistics(" All resources ")
|
|
};
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
/// <summary>
|
|
/// to contain the resource info objects from the engine
|
|
/// </summary>
|
|
private readonly List<ResourceInfo> _resourceList = new List<ResourceInfo>();
|
|
/// to contain the resource info objects displayed in the grid (Applied from resource type filter)
|
|
private readonly List<ResourceInfo> _datagridResourceList = new List<ResourceInfo>();
|
|
/// to contain the different resource type to fill the combo list of resource types
|
|
private readonly List<string> _resourceTypeList = new List<string>();
|
|
// store the last selected resource during the refresh process
|
|
private string _lastResourceTypeSelected = null;
|
|
// current checkout and open for add
|
|
private int _checkedOutFileCount = 0;
|
|
|
|
|
|
#endregion
|
|
|
|
#region properties
|
|
|
|
public P4Manager P4ManagerInstance => P4Manager.Instance;
|
|
|
|
public bool EngineConnected => _plugin != null && _plugin.IsConnected;
|
|
|
|
private ResourceStatistics OverallStats => _statistics[2];
|
|
|
|
private ResourceStatistics FilteredStats => _statistics[1];
|
|
|
|
private ResourceStatistics SelectedStats => _statistics[0];
|
|
|
|
public object FilterWarningVisibility => string.IsNullOrWhiteSpace(_findkeyTextBox.Text.ToString(CultureInfo.InvariantCulture)) == true
|
|
? Visibility.Hidden
|
|
: Visibility.Visible;
|
|
|
|
private bool GameDataOnly => true;
|
|
|
|
#endregion
|
|
|
|
#region functions
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
|
|
// update window title with version number
|
|
Title += $" - {Version}";
|
|
|
|
PlumeLoggerAdapter plumeLoggerAdapter = PlumeLoggerAdapter.Create();
|
|
P4Manager.Instance.Initialize(plumeLoggerAdapter);
|
|
|
|
_plugin = new ResourceViewerPlugin();
|
|
_engineManager = new EngineManager(_plugin);
|
|
|
|
InitialUpdate();
|
|
|
|
// set the static overall stat in ResourceInfo for computing & binding call
|
|
ResourceInfo.OverallStats = OverallStats;
|
|
}
|
|
|
|
private string Version
|
|
{
|
|
get
|
|
{
|
|
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
|
return $"v{version.Major.ToString()}.{version.Minor.ToString()}";
|
|
}
|
|
}
|
|
|
|
private void InitialUpdate()
|
|
{
|
|
_filterWarningUserControl.Text = "A filter is currently active";
|
|
_checkoutWarningUserControl.Text = "You have no checked out file";
|
|
foreach (object targetName in Enum.GetValues(typeof(PlatformId)))
|
|
this._targetListBox.Items.Add(targetName);
|
|
if (this._targetListBox.Items.Count > 0)
|
|
this._targetListBox.SelectedIndex = 0;
|
|
|
|
UpdateWarningFilterVisibility();
|
|
UpdateWarningPerforceVisibility();
|
|
UpdateControlsWithConnectingState();
|
|
}
|
|
|
|
private void ClearResourceList()
|
|
{
|
|
this._resourceList.Clear();
|
|
this._resourceTypeList.Clear();
|
|
UpdateDataGrid();
|
|
}
|
|
|
|
private string GetDatagridSelectedItemName()
|
|
{
|
|
// keep previous selection
|
|
if (this._resourceDataGrid.SelectedItem != null && this._resourceDataGrid.SelectedItem is ResourceInfo)
|
|
{
|
|
var selectRes = this._resourceDataGrid.SelectedItem as ResourceInfo;
|
|
return selectRes.ShortName;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply filters on the _resourceList member, to create the datagrid resource list, source for datagrid binding
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private void FilterResourceList()
|
|
{
|
|
bool addAllResourceType = true;
|
|
if (this._resourceTypeComboBox.SelectedItem != null)
|
|
addAllResourceType = string.Compare(this._resourceTypeComboBox.SelectedItem.ToString(), ResourceUtils.TypeHelper.ResourceAllSuffix) == 0;
|
|
var utils = new ResourceUtils();
|
|
|
|
ResourceStatistics.ResetStatistic(FilteredStats);
|
|
ResourceStatistics.ResetStatistic(OverallStats);
|
|
|
|
string filterKey = this._findkeyTextBox.Text;
|
|
|
|
foreach (ResourceInfo ri in this._resourceList)
|
|
{
|
|
string resTypeName = ResourceUtils.TypeHelper.ConvertEngineTypeToUIType(ri.TypeName);
|
|
if (addAllResourceType || string.Compare(this._resourceTypeComboBox.SelectedItem.ToString(), resTypeName) == 0)
|
|
{
|
|
bool addResToGrid = true;
|
|
|
|
// filter editor and engine only data
|
|
if (GameDataOnly)
|
|
{
|
|
var filePath = Utils.Instance.PathToP4Path(ri.PathName);
|
|
if (filePath.StartsWith("world/") == false)
|
|
{
|
|
addResToGrid = false;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// check to filter names ?
|
|
if (string.IsNullOrEmpty(filterKey) == false)
|
|
{
|
|
string findNameRegexPattern = @"^(.*)" + filterKey + @"(.*)\.[\w]{2,4}$";
|
|
MatchCollection matches = Utils.Instance.MatchNameWithKey(ri.ShortName, findNameRegexPattern, false);
|
|
addResToGrid = matches.Count > 0;
|
|
}
|
|
|
|
// really add the resource to the list
|
|
if (addResToGrid)
|
|
{
|
|
_datagridResourceList.Add(ri);
|
|
ResourceStatistics.UpdateStatistic(ri, FilteredStats);
|
|
}
|
|
ResourceStatistics.UpdateStatistic(ri, OverallStats);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void RestoreDatagridSelection(string previousSelectedItemName)
|
|
{
|
|
// redo selection if possible
|
|
int index = 0;
|
|
if (string.IsNullOrEmpty(previousSelectedItemName) == false)
|
|
{
|
|
// search the resource by name into observable list
|
|
var search = (from res in ResourceInfoDatagridList
|
|
where res.ShortName == previousSelectedItemName
|
|
select res).FirstOrDefault();
|
|
if (search != null)
|
|
{
|
|
// get current datagrid index for this item
|
|
index = this._datagridResourceList.IndexOf(search);
|
|
}
|
|
}
|
|
if (this._resourceDataGrid.Items.Count > 0)
|
|
{
|
|
this._resourceDataGrid.SelectedIndex = index;
|
|
}
|
|
}
|
|
|
|
private IEnumerable<TextureConfiguration> SelectTextureConfiguration()
|
|
{
|
|
var textureConfigurationToSelect = new List<TextureConfiguration>();
|
|
var selectedTargets = _targetListBox.SelectedItems.OfType<PlatformId>();
|
|
var textureResourceList = this._resourceDataGrid.SelectedItems.OfType<ResourceInfo>().Where(res => res.IsTexture == true);
|
|
|
|
foreach (var resourceInfo in textureResourceList)
|
|
{
|
|
if (resourceInfo.TextureConfigurations == null)
|
|
{
|
|
string tfiFilePath = Utils.Instance.PathToP4Path(DataPath.GetAbsolutePath(resourceInfo.PathName) + Utils.TFIExtension);
|
|
|
|
IEnumerable<TextureConfiguration> textureConfigurations = null;
|
|
if (File.Exists(tfiFilePath))
|
|
{
|
|
textureConfigurations = new TextureConfigFileReader(tfiFilePath).Load();
|
|
}
|
|
resourceInfo.UpdateConfigurations(textureConfigurations, _targetListBox.Items.OfType<PlatformId>());
|
|
}
|
|
textureConfigurationToSelect.AddRange(resourceInfo.EnumerateConfigurations(selectedTargets));
|
|
}
|
|
return textureConfigurationToSelect;
|
|
}
|
|
/// <summary>
|
|
/// Manage single selection preview
|
|
/// </summary>
|
|
/// <param name="selectedResource">resource selected in datagrid</param>
|
|
private void ManagePreviewForSingleSelection(ResourceInfo selectedResource)
|
|
{
|
|
// display texture if resource is visual one
|
|
string rootedFilePath = Utils.Instance.PathToP4Path(DataPath.GetAbsolutePath(selectedResource.PathName));
|
|
|
|
if (selectedResource.BitmapSource == null)
|
|
{
|
|
Size fileImageSize = new Size(0, 0);
|
|
selectedResource.BitmapSource = Utils.Instance.GetSelectedResourceBitmapSource(selectedResource, rootedFilePath, ref fileImageSize);
|
|
selectedResource.FileImageSize = fileImageSize;
|
|
}
|
|
// if height equals width, use fill, else use uniform
|
|
if (Math.Abs(selectedResource.CustomImageSize.Width - selectedResource.CustomImageSize.Height) < float.Epsilon)
|
|
{
|
|
_textureImage.Stretch = Stretch.Fill;
|
|
}
|
|
else
|
|
{
|
|
_textureImage.Stretch = Stretch.Uniform;
|
|
}
|
|
UpdateSelectedResource(selectedResource);
|
|
_textureImage.Source = selectedResource.BitmapSource;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Manage multi resource selection preview icon
|
|
/// </summary>
|
|
/// <param name="selectedItems">When called, it cannot be null or empty</param>
|
|
private void ManagePreviewForMultiSelection(IEnumerable selectedItems)
|
|
{
|
|
// get selected resourceInfo
|
|
var resourceList = selectedItems.OfType<ResourceInfo>();
|
|
// find resources that are texture
|
|
// only one type resource in selected ? Yes Display type res preview No ? Display multi type selection
|
|
if (resourceList.Select(x => x.TypeName).Distinct().Count() <= 1)
|
|
{
|
|
// take the first resource to get corresponding icon, including multi texture one (true passed to GetSelectedResourceBitmapSource)
|
|
ResourceInfo selectedResource = resourceList.FirstOrDefault();
|
|
Size imageSize = new Size(0, 0);
|
|
string rootedFilePath = Utils.Instance.PathToP4Path(DataPath.GetAbsolutePath(selectedResource.PathName));
|
|
_textureImage.Source = Utils.Instance.GetSelectedResourceBitmapSource(selectedResource, rootedFilePath, ref imageSize, true);
|
|
}
|
|
else
|
|
{
|
|
_textureImage.Source = Utils.GetBitmapSource(Properties.Resources.Icons_256x256_NoTexture);
|
|
}
|
|
_labelImageSize.Content = string.Empty;
|
|
}
|
|
|
|
#endregion
|
|
#region handlers
|
|
|
|
private void OnResourceTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
UpdateDataGrid();
|
|
}
|
|
|
|
private void OnFindKeyTextChanged(object sender, TextChangedEventArgs e)
|
|
{
|
|
var filterKeyModerator = new Moderator();
|
|
|
|
filterKeyModerator.ElapsedTime = 2;
|
|
filterKeyModerator.Done += UpdateDataGridHandler;
|
|
filterKeyModerator.Trigger();
|
|
}
|
|
|
|
/// <summary>
|
|
/// This function is event call by blob thread. The function receive the resourceInfo list extracted from blob.
|
|
/// It copies the list into a local ResourceList (_resourceList member).
|
|
/// The function also build the list of type collected, and update the combo list for these types.
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
public void OnUpdate(object sender, UpdateEventArgs e)
|
|
{
|
|
if (this.Dispatcher.Thread != System.Threading.Thread.CurrentThread)
|
|
{
|
|
this.Dispatcher.BeginInvoke(new ResourceViewerPlugin.UpdateEventHandler(OnUpdate), new Object[] { sender, e });
|
|
}
|
|
else
|
|
{
|
|
// fill local list
|
|
_resourceList.Clear();
|
|
_resourceList.AddRange(e.ResourceInfoList);
|
|
|
|
// init combo box with All types, and select it
|
|
string resTypeAll = ResourceUtils.TypeHelper.ResourceAllSuffix;
|
|
// systematic add for All types
|
|
_resourceTypeList.Clear();
|
|
_resourceTypeList.Add(resTypeAll);
|
|
_resourceTypeList.AddRange(e.ResourceTypeList);
|
|
|
|
if (this._resourceTypeComboBox.SelectedItem != null)
|
|
_lastResourceTypeSelected = this._resourceTypeComboBox.SelectedItem.ToString();
|
|
else
|
|
_lastResourceTypeSelected = null;
|
|
|
|
System.Windows.Threading.DispatcherOperation operation =
|
|
this.Dispatcher.BeginInvoke(new Action(NotifyResourceTypeListChanged), System.Windows.Threading.DispatcherPriority.Normal);
|
|
operation.Completed += new EventHandler(NotifyResourceTypeComboListUpdated);
|
|
|
|
// update Target display
|
|
_targetLabel.Content = _plugin.Platform + " connected";
|
|
// update target combolist selection according to current connect target
|
|
_targetListBox.SelectedItems.Clear();
|
|
|
|
PlatformId platform;
|
|
if (!Enum.TryParse(_plugin.Platform, out platform))
|
|
{
|
|
platform = PlatformId.PC;
|
|
}
|
|
_targetListBox.SelectedItems.Add(platform);
|
|
}
|
|
}
|
|
|
|
public void OnDataRootUpdate(object sender, UpdateDataRootPathEventArgs e)
|
|
{
|
|
System.Windows.Application.Current.Dispatcher.Invoke((Action) (() =>
|
|
{
|
|
_textBoxRootDataPath.Text = e.RootPath;
|
|
}));
|
|
}
|
|
|
|
private void OnLoaded(object sender, RoutedEventArgs e)
|
|
{
|
|
// init plugin settings
|
|
_plugin.UpdateHandler += OnUpdate;
|
|
_plugin.UpdateDataRootHandler += OnDataRootUpdate;
|
|
_plugin.ConnectedChanged += OnEngineConnectionChanged;
|
|
|
|
_engineConnectionStatusUserControl.EngineManager = _engineManager;
|
|
|
|
_resourcePropertyGrid.RegisterPropertyValueChangedEventHandler(OnPropertyGridPropertyValueChanged);
|
|
}
|
|
|
|
private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
|
|
{
|
|
_resourcePropertyGrid.UnregisterPropertyValueChangedEventHandler(OnPropertyGridPropertyValueChanged);
|
|
|
|
_plugin.ConnectedChanged -= OnEngineConnectionChanged;
|
|
_plugin.UpdateHandler -= OnUpdate;
|
|
_plugin.UpdateDataRootHandler -= OnDataRootUpdate;
|
|
|
|
_engineConnectionStatusUserControl.EngineManager = null;
|
|
|
|
_engineManager.Disconnect();
|
|
}
|
|
|
|
private void OnEngineConnectionChanged(object sender, IPlugin e)
|
|
{
|
|
System.Windows.Application.Current.Dispatcher.Invoke((Action) (() =>
|
|
{
|
|
if (_plugin.IsConnected)
|
|
{
|
|
_plugin.RequestInitPlugin();
|
|
_plugin.RequestDumpResources(
|
|
ResourceUtils.TypeHelper.ConvertUITypeToEngineType(ResourceUtils.TypeHelper.ResourceAllSuffix));
|
|
}
|
|
else
|
|
{
|
|
ClearResourceList();
|
|
_targetLabel.Content = string.Empty;
|
|
ResourceStatistics.ResetStatistic(OverallStats);
|
|
ResourceStatistics.ResetStatistic(SelectedStats);
|
|
ResourceStatistics.ResetStatistic(FilteredStats);
|
|
}
|
|
NotifyPropertyChanged("EngineConnected");
|
|
UpdateControlsWithConnectingState();
|
|
}));
|
|
}
|
|
|
|
private void OnPropertyGridPropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
|
|
{
|
|
IEnumerable<TextureConfiguration> selectedTextureConfiguration = _resourcePropertyGrid.SelectedObjects.OfType<TextureConfiguration>();
|
|
foreach (var textureConfiguration in selectedTextureConfiguration)
|
|
{
|
|
textureConfiguration.Modify();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handler of grid selection changed. Manage both single and multiple selection.
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void OnDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
var selectedItems = this._resourceDataGrid.SelectedItems;
|
|
if (selectedItems != null && selectedItems.Count > 0)
|
|
{
|
|
// update statistics
|
|
UpdateSelectedResourcesStatistics(selectedItems);
|
|
NotifyPropertyChanged("StatisticsList");
|
|
|
|
if (selectedItems.Count > 1)
|
|
{
|
|
ManagePreviewForMultiSelection(selectedItems);
|
|
}
|
|
else
|
|
{
|
|
var selectedResource = (ResourceInfo)selectedItems[0];
|
|
ManagePreviewForSingleSelection(selectedResource);
|
|
// play sound if resource is sound type
|
|
if (selectedResource.IsSound)
|
|
{
|
|
string rootedFilePath = Utils.Instance.PathToP4Path(DataPath.GetAbsolutePath(selectedResource.PathName));
|
|
var simpleSound = new SoundPlayer(rootedFilePath);
|
|
simpleSound.Play();
|
|
}
|
|
}
|
|
}
|
|
UpdatePreviewVisibility();
|
|
// update property grid for this resource
|
|
UpdatePropertyGridSelection();
|
|
UpdatePropertyGridVisibility();
|
|
}
|
|
|
|
private void OnRefreshButtonClick(object sender, RoutedEventArgs e)
|
|
{
|
|
string resTypeName = ResourceUtils.TypeHelper.ConvertUITypeToEngineType(this._resourceTypeComboBox.SelectedItem.ToString());
|
|
_plugin.RequestDumpResources(resTypeName);
|
|
}
|
|
|
|
private void OnDataGridContextMenuOpening(object sender, ContextMenuEventArgs e)
|
|
{
|
|
string resTypeName = ResourceUtils.TypeHelper.ConvertUITypeToEngineType(this._resourceTypeComboBox.SelectedItem.ToString());
|
|
e.Handled = true;
|
|
}
|
|
|
|
private void OnDataGridMouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
|
{
|
|
var selectedItem = this._resourceDataGrid.SelectedItem;
|
|
if (selectedItem != null)
|
|
{
|
|
var selectedResource = selectedItem as ResourceInfo;
|
|
if (selectedResource != null)
|
|
{
|
|
string rootedFilePath = Utils.Instance.PathToP4Path(DataPath.GetAbsolutePath(selectedResource.PathName));
|
|
Utils.Instance.OpenExplorer(rootedFilePath);
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool PrecheckRevisions(IEnumerable<ResourceInfo> resourceToCheckout)
|
|
{
|
|
if (P4ManagerInstance != null && P4ManagerInstance.Connected)
|
|
{
|
|
var messages = new List<string>();
|
|
foreach (var resourceInfo in resourceToCheckout)
|
|
{
|
|
string tfiFilePath = DataPath.GetAbsolutePath(resourceInfo.PathName) + Utils.TFIExtension;
|
|
tfiFilePath = Utils.Instance.PathToP4Path(tfiFilePath);
|
|
|
|
// look if file is already on depot.
|
|
if (P4ManagerInstance.PerforceWrapper.IsSubmittedInDepot(tfiFilePath))
|
|
{
|
|
// look if file is at head revision on client, we dont allow to edit not at head revision file
|
|
DepotFileInfo file = P4ManagerInstance.PerforceWrapper.GetFileInfo(tfiFilePath);
|
|
if (file.HeadRev != file.HaveRev)
|
|
{
|
|
messages.Add($"{resourceInfo.PathName} is at {file.HaveRev}/{file.HeadRev} revision on client side");
|
|
}
|
|
}
|
|
}
|
|
if (messages.Count > 0)
|
|
{
|
|
|
|
string message = @"File(s)" +
|
|
Environment.NewLine +
|
|
string.Join(Environment.NewLine, messages) +
|
|
Environment.NewLine +
|
|
@"You have to sync files before to save/check out";
|
|
MessageBox.Show(message);
|
|
}
|
|
return messages.Count == 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void OnSaveButtonClick(object sender, RoutedEventArgs e)
|
|
{
|
|
// retrieve all textures
|
|
var resourceToCheckout = new List<ResourceInfo>();
|
|
IEnumerable<ResourceInfo> textureResources = this._resourceList.Where(r => r != null && r.IsTexture == true);
|
|
|
|
// make list with texture configurations that have been modified
|
|
foreach (var textureResource in textureResources)
|
|
{
|
|
if (textureResource.TextureConfigurations != null)
|
|
{
|
|
IEnumerable<TextureConfiguration> configurations = textureResource.TextureConfigurations.Values;
|
|
if (configurations.Any(textureConfiguration => textureConfiguration.ModifyStateChanged) == true)
|
|
{
|
|
resourceToCheckout.Add(textureResource);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (resourceToCheckout.Count > 0)
|
|
{
|
|
bool canCheckout = PrecheckRevisions(resourceToCheckout);
|
|
if (canCheckout == true)
|
|
{
|
|
foreach (var resourceInfo in resourceToCheckout)
|
|
{
|
|
string tfiFilePath = DataPath.GetAbsolutePath(resourceInfo.PathName) + Utils.TFIExtension;
|
|
tfiFilePath = Utils.Instance.PathToP4Path(tfiFilePath);
|
|
|
|
OpenForEditFile(tfiFilePath);
|
|
SaveFile(tfiFilePath, resourceInfo);
|
|
OpenForAdd(tfiFilePath);
|
|
}
|
|
UpdatePropertyGridSelection();
|
|
UpdateWarningPerforceVisibility();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OpenForAdd(string tfiFilePath)
|
|
{
|
|
if (P4ManagerInstance != null && P4ManagerInstance.Connected)
|
|
{
|
|
if (P4ManagerInstance.PerforceWrapper.IsSubmittedInDepot(tfiFilePath) == false)
|
|
{
|
|
if (P4ManagerInstance.PerforceWrapper.IsPendingInDepot(tfiFilePath) == false)
|
|
{
|
|
P4ManagerInstance.PerforceWrapper.OpenForAdd(tfiFilePath);
|
|
_checkedOutFileCount++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SaveFile(string tfiFilePath, ResourceInfo resourceInfo)
|
|
{
|
|
using (var writer = new TextureConfigFileWriter(tfiFilePath))
|
|
{
|
|
writer.Save(resourceInfo.TextureConfigurations.Values);
|
|
Console.WriteLine(resourceInfo.ShortName + " saved.");
|
|
}
|
|
}
|
|
|
|
private void OpenForEditFile(string tfiFilePath)
|
|
{
|
|
if (P4ManagerInstance != null && P4ManagerInstance.Connected)
|
|
{
|
|
// look if file is already on depot.
|
|
if (P4ManagerInstance.PerforceWrapper.IsSubmittedInDepot(tfiFilePath))
|
|
{
|
|
P4ManagerInstance.PerforceWrapper.OpenForEdit(tfiFilePath);
|
|
_checkedOutFileCount++;
|
|
}
|
|
else
|
|
{
|
|
// if file exists, is readonly, but is not submitted, delete this release just before create a new one
|
|
var fileInfo = new FileInfo(tfiFilePath);
|
|
if (fileInfo.Exists && fileInfo.IsReadOnly)
|
|
fileInfo.Delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnTargetListSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
UpdatePropertyGridSelection();
|
|
UpdatePropertyGridVisibility();
|
|
}
|
|
|
|
private void OnRecookButtonClick(object sender, RoutedEventArgs e)
|
|
{
|
|
var selectedItem = this._resourceDataGrid.SelectedItem;
|
|
if (selectedItem != null)
|
|
{
|
|
var selectedResource = selectedItem as ResourceInfo;
|
|
if (selectedResource != null)
|
|
{
|
|
Utils.Instance.CookTexture(_plugin, selectedResource);
|
|
// refresh texture state
|
|
UpdatePropertyGridSelection();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnRecookAllButtonClick(object sender, RoutedEventArgs e)
|
|
{
|
|
IEnumerable<ResourceInfo> textureResources = this._resourceList.Where(r => r != null && r.IsTexture == true);
|
|
foreach (var textureResource in textureResources)
|
|
{
|
|
if (textureResource.TextureConfigurations != null)
|
|
{
|
|
IEnumerable<TextureConfiguration> configurations = textureResource.TextureConfigurations.Values;
|
|
if (configurations.Any(textureConfiguration => textureConfiguration.CookStateChanged) == true)
|
|
{
|
|
Utils.Instance.CookTexture(_plugin, textureResource);
|
|
// refresh texture state
|
|
UpdatePropertyGridSelection();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnReleaseNotesButtonClick(object sender, RoutedEventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void OnHelpButtonClick(object sender, RoutedEventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region notify and update
|
|
|
|
private void NotifyPropertyChanged(string name)
|
|
{
|
|
if (PropertyChanged != null)
|
|
PropertyChanged(this, new PropertyChangedEventArgs(name));
|
|
}
|
|
|
|
public ObservableCollection<string> ResourceTypeComboList => new ObservableCollection<string>(_resourceTypeList);
|
|
|
|
public ObservableCollection<ResourceInfo> ResourceInfoDatagridList => new ObservableCollection<ResourceInfo>(_datagridResourceList);
|
|
|
|
public ObservableCollection<ResourceStatistics> StatisticsList => new ObservableCollection<ResourceStatistics>(_statistics);
|
|
|
|
/// <summary>
|
|
/// Called to bind the combolist on _resourceTypeList member
|
|
/// </summary>
|
|
private void NotifyResourceTypeListChanged()
|
|
{
|
|
NotifyPropertyChanged("ResourceTypeComboList");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called to finish resource Type combo update selected one res type
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void NotifyResourceTypeComboListUpdated(object sender, EventArgs e)
|
|
{
|
|
int index = 0;
|
|
|
|
if (string.IsNullOrEmpty(this._lastResourceTypeSelected) == false)
|
|
{
|
|
if (_resourceTypeList.Contains(_lastResourceTypeSelected))
|
|
{
|
|
index = _resourceTypeList.IndexOf(_lastResourceTypeSelected);
|
|
}
|
|
}
|
|
if (this._resourceTypeComboBox.Items.Count > 0)
|
|
{
|
|
// force redraw on datagrid even if selection resource type did not changed
|
|
if (this._resourceTypeComboBox.SelectedIndex == index)
|
|
UpdateDataGrid();
|
|
|
|
this._resourceTypeComboBox.SelectedIndex = index;
|
|
}
|
|
}
|
|
|
|
|
|
private void UpdateWarningPerforceVisibility()
|
|
{
|
|
if (P4ManagerInstance != null && _checkedOutFileCount > 0)
|
|
{
|
|
_checkoutWarningUserControl.Text = $"You checked out {_checkedOutFileCount} files in default since you began";
|
|
_checkoutWarningUserControl.Visibility = Visibility.Visible;
|
|
}
|
|
else
|
|
{
|
|
_checkoutWarningUserControl.Visibility = Visibility.Hidden;
|
|
}
|
|
}
|
|
|
|
private void UpdateWarningFilterVisibility()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_findkeyTextBox.Text) == false)
|
|
{
|
|
_filterWarningUserControl.Visibility = Visibility.Visible;
|
|
}
|
|
else
|
|
{
|
|
_filterWarningUserControl.Visibility = Visibility.Hidden;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update data grid, recompute content + bind + update selection
|
|
/// </summary>
|
|
private void UpdateDataGrid()
|
|
{
|
|
string selectedItemName = GetDatagridSelectedItemName();
|
|
|
|
// clear data list
|
|
_datagridResourceList.Clear();
|
|
|
|
// reset previous selection
|
|
this._resourceDataGrid.SelectedItem = null;
|
|
this._resourceDataGrid.SelectedIndex = -1;
|
|
|
|
// compute _datagridlist according to filter
|
|
FilterResourceList();
|
|
|
|
// notify control source data changed
|
|
NotifyPropertyChanged("ResourceInfoDatagridList");
|
|
|
|
RestoreDatagridSelection(selectedItemName);
|
|
|
|
UpdateWarningFilterVisibility();
|
|
}
|
|
|
|
private void UpdateDataGridHandler(object sender, EventArgs e)
|
|
{
|
|
System.Windows.Threading.DispatcherOperation operation =
|
|
this.Dispatcher.BeginInvoke(new Action(UpdateDataGrid), System.Windows.Threading.DispatcherPriority.Normal);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update preview texture visibility
|
|
/// </summary>
|
|
private void UpdatePreviewVisibility()
|
|
{
|
|
System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
|
|
{
|
|
var visibility = Visibility.Hidden;
|
|
|
|
var selectedResources = this._resourceDataGrid.SelectedItems;
|
|
if (selectedResources != null && selectedResources.Count > 0)
|
|
visibility = Visibility.Visible;
|
|
|
|
this._labelImageSize.Visibility = visibility;
|
|
this._gridimage.Visibility = visibility;
|
|
}));
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update engine specific controls
|
|
/// </summary>
|
|
private void UpdateControlsWithConnectingState()
|
|
{
|
|
UpdatePreviewVisibility();
|
|
|
|
var visibility = Visibility.Hidden;
|
|
if (EngineConnected)
|
|
visibility = Visibility.Visible;
|
|
_resourceInfoGrid.Visibility = visibility;
|
|
_targetLabel.Visibility = visibility;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Display property grid only if all selected resource are texture resources
|
|
/// </summary>
|
|
private void UpdatePropertyGridSelection()
|
|
{
|
|
var selectedResources = this._resourceDataGrid.SelectedItems;
|
|
if (selectedResources != null)
|
|
{
|
|
IEnumerable<TextureConfiguration> configurations = SelectTextureConfiguration();
|
|
if (configurations.Any())
|
|
{
|
|
_resourcePropertyGrid.SelectedObjects = configurations.ToArray();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_resourcePropertyGrid.SelectedObjects = null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Display property grid only if all selected resource are texture resources
|
|
/// </summary>
|
|
private void UpdatePropertyGridVisibility()
|
|
{
|
|
var selectedResources = this._resourceDataGrid.SelectedItems.OfType<ResourceInfo>();
|
|
// only one type in selection ?
|
|
if (selectedResources.Select(x => x.TypeName).Distinct().Count() == 1 &&
|
|
selectedResources.Any(x => x.IsTexture == true))
|
|
{
|
|
this._resourceGroupBox.Visibility = Visibility.Visible;
|
|
}
|
|
else
|
|
{
|
|
this._resourceGroupBox.Visibility = Visibility.Hidden;
|
|
}
|
|
}
|
|
|
|
private void UpdateSelectedResource(ResourceInfo selectedResource)
|
|
{
|
|
if (selectedResource.IsTexture)
|
|
{
|
|
_labelImageSize.Content = $"Original image size : {selectedResource.FileImageSize.Width}x{selectedResource.FileImageSize.Height}";
|
|
}
|
|
else
|
|
{
|
|
_labelImageSize.Content = string.Empty;
|
|
}
|
|
}
|
|
|
|
private void UpdateSelectedResourcesStatistics(IEnumerable selectedItems)
|
|
{
|
|
ResourceStatistics.ResetStatistic(SelectedStats);
|
|
foreach (var selectedItem in selectedItems)
|
|
{
|
|
var selectedResource = selectedItem as ResourceInfo;
|
|
if (selectedResource != null)
|
|
{
|
|
ResourceStatistics.UpdateStatistic(selectedResource, SelectedStats);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void Dispose()
|
|
{
|
|
_plugin?.Dispose();
|
|
_engineManager?.Dispose();
|
|
}
|
|
}
|
|
}
|
|
|