using Microsoft.VisualStudio.Project; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using ANX.Framework.VisualStudio.Nodes; namespace ANX.Framework.VisualStudio { public class AssetFileDescriptor : DesignPropertyDescriptor { ContentProjectNode currentProject; public AssetFileDescriptor(PropertyDescriptor prop) : base(prop) { currentProject = Utilities.GetCurrentProject(); } public override void SetValue(object component, object value) { var prop = (IncludedAssetFileNodeProperties)component; switch (this.Name) { case "AssetName": if (IsAssetNameValid((string)value)) prop.AssetName = (string)value; break; default: base.SetValue(component, value); break; } //By refreshing the property grid, we make sure if a converter didn't have any properties and we changed to a converter with properties, it would refresh. TypeDescriptor.Refresh(component); } private bool IsAssetNameValid(string value) { if (value == null) return true; foreach (var c in Path.GetInvalidFileNameChars()) { if (value.Contains(c)) return false; } return true; } public override bool CanResetValue(object component) { var prop = (IncludedAssetFileNodeProperties)component; switch (this.Name) { case "AssetName": return Path.GetFileNameWithoutExtension(prop.FileName) != prop.AssetName; case "ContentImporter": using (var domain = currentProject.BuildAppDomain.Aquire()) { var importer = domain.Proxy.GuessImporterByFileExtension(prop.FileName); return importer != null && prop.ContentImporter != importer; } case "ContentProcessor": if (string.IsNullOrEmpty(prop.ContentImporter)) return false; using (var domain = currentProject.BuildAppDomain.Aquire()) { return prop.ContentProcessor != domain.Proxy.GetDefaultProcessorForImporter(prop.ContentImporter) || this.Converter.GetProperties(new TypeDescriptorContext(null, component, this), prop.ContentProcessor).Cast().Any((x) => x.CanResetValue(prop.ContentProcessor)); } case "FileName": return false; default: return base.CanResetValue(component); } } public override void ResetValue(object component) { var prop = (IncludedAssetFileNodeProperties)component; switch (this.Name) { case "AssetName": this.SetValue(component, Path.GetFileNameWithoutExtension(prop.FileName)); return; case "ContentImporter": using (var domain = currentProject.BuildAppDomain.Aquire()) { this.SetValue(component, domain.Proxy.GuessImporterByFileExtension(prop.FileName)); } return; case "ContentProcessor": using (var domain = currentProject.BuildAppDomain.Aquire()) { this.SetValue(component, domain.Proxy.GetDefaultProcessorForImporter(prop.ContentImporter)); prop.ProcessorParameters.Clear(); } return; } base.ResetValue(component); } public override bool ShouldSerializeValue(object component) { return this.CanResetValue(component); } public override object GetValue(object component) { var prop = (IncludedAssetFileNodeProperties)component; //if no values are present, create default values, a none value is not allowed. if (string.IsNullOrEmpty(prop.ContentImporter)) using (var buildDomain = currentProject.BuildAppDomain.Aquire()) { prop.ContentImporter = buildDomain.Proxy.GuessImporterByFileExtension(prop.Extension); } if (string.IsNullOrEmpty(prop.ContentProcessor)) using (var buildDomain = currentProject.BuildAppDomain.Aquire()) { prop.ContentProcessor = buildDomain.Proxy.GetDefaultProcessorForImporter(prop.ContentImporter); } return base.GetValue(component); } } }