diff --git a/BizHawk.Client.Common/FilesystemFilter.cs b/BizHawk.Client.Common/FilesystemFilter.cs new file mode 100644 index 0000000000..438be7c373 --- /dev/null +++ b/BizHawk.Client.Common/FilesystemFilter.cs @@ -0,0 +1,72 @@ +#nullable enable + +using System.Collections.Generic; +using System.Linq; + +namespace BizHawk.Client.Common +{ + public sealed class FilesystemFilter + { + public readonly string Description; + + public readonly IReadOnlyCollection Extensions; + + public FilesystemFilter(string description, IReadOnlyCollection extensions, bool addArchiveExts = false) + { + Description = description; + Extensions = addArchiveExts ? extensions.Concat(ArchiveExtensions).ToList() : extensions; + } + + /// When is set to for release, this behaves identically to the other ctor. + /// On dev builds, are appended to . + /// + public FilesystemFilter( + string description, + IReadOnlyCollection extensions, + IReadOnlyCollection devBuildExtraExts, + bool addArchiveExts = false, + bool devBuildAddArchiveExts = false) + { + Description = description; + if (!VersionInfo.DeveloperBuild) + { + // same as other ctor + Extensions = addArchiveExts ? extensions.Concat(ArchiveExtensions).ToList() : extensions; + } + else + { + Extensions = addArchiveExts || devBuildAddArchiveExts + ? extensions.Concat(devBuildExtraExts).Concat(ArchiveExtensions).ToList() + : extensions.Concat(devBuildExtraExts).ToList(); + } + } + + /// delegated to + /// return value is a valid Filter for Save-/OpenFileDialog + public override string ToString() => SerializeEntry(Description, Extensions); + + public const string AllFilesEntry = "All Files|*"; + + public static readonly IReadOnlyCollection ArchiveExtensions = new[] { "zip", "rar", "7z", "gz" }; + + public static readonly FilesystemFilter Archives = new FilesystemFilter("Archives", ArchiveExtensions); + + public static readonly FilesystemFilter BizHawkMovies = new FilesystemFilter("Movie Files", new[] { MovieService.DefaultExtension }); + + public static readonly FilesystemFilter EmuHawkSaveStates = new FilesystemFilter("Save States", new[] { "State" }); + + public static readonly FilesystemFilter LuaScripts = new FilesystemFilter("Lua Scripts", new[] { "lua" }); + + public static readonly FilesystemFilter Palettes = new FilesystemFilter("Palette Files", new[] { "pal" }); + + public static readonly FilesystemFilter PNGs = new FilesystemFilter("PNG Files", new[] { "png" }); + + public static readonly FilesystemFilter TAStudioProjects = new FilesystemFilter("TAS Project Files", new[] { TasMovie.Extension }); + + public static readonly FilesystemFilter TextFiles = new FilesystemFilter("Text Files", new[] { "txt" }); + + /// return value is a valid Filter for Save-/OpenFileDialog + public static string SerializeEntry(string desc, IEnumerable exts) + => string.Format("{0} ({1})|{1}", desc, string.Join(";", exts.Select(ext => $"*.{ext}"))); + } +} diff --git a/BizHawk.Client.Common/FilesystemFilterSet.cs b/BizHawk.Client.Common/FilesystemFilterSet.cs new file mode 100644 index 0000000000..1cc436bbba --- /dev/null +++ b/BizHawk.Client.Common/FilesystemFilterSet.cs @@ -0,0 +1,31 @@ +#nullable enable + +using System.Collections.Generic; +using System.Linq; + +namespace BizHawk.Client.Common +{ + public sealed class FilesystemFilterSet + { + public readonly IReadOnlyCollection Filters; + + public FilesystemFilterSet(params FilesystemFilter[] filters) + { + Filters = filters; + } + + /// appends All Files entry (calls with ), return value is a valid Filter for Save-/OpenFileDialog + public override string ToString() => ToString(true); + + /// call other overload to prepend combined entry, return value is a valid Filter for Save-/OpenFileDialog + public string ToString(bool addAllFilesEntry) => addAllFilesEntry + ? $"{ToString(false)}|{FilesystemFilter.AllFilesEntry}" + : string.Join("|", Filters.Select(filter => filter.ToString())); + + /// call other overload (omit ) to not prepend combined entry, return value is a valid Filter for Save-/OpenFileDialog + public string ToString(string combinedEntryDesc, bool addAllFilesEntry = true) + => $"{FilesystemFilter.SerializeEntry(combinedEntryDesc, Filters.SelectMany(filter => filter.Extensions).Distinct().OrderBy(s => s))}|{ToString(addAllFilesEntry)}"; + + public static readonly FilesystemFilterSet Screenshots = new FilesystemFilterSet(FilesystemFilter.PNGs, new FilesystemFilter(".bmp Files", new[] { "bmp" })); + } +} diff --git a/BizHawk.Client.Common/movie/import/MovieImport.cs b/BizHawk.Client.Common/movie/import/MovieImport.cs index 4dabc80e46..cdb17eece2 100644 --- a/BizHawk.Client.Common/movie/import/MovieImport.cs +++ b/BizHawk.Client.Common/movie/import/MovieImport.cs @@ -23,13 +23,11 @@ namespace BizHawk.Client.Common .Any(e => string.Equals(extension, e.Extension, StringComparison.OrdinalIgnoreCase)); } - public static Dictionary AvailableImporters() - { - return Importers - .OrderBy(i => i.Value.Emulator) - .ToDictionary(tkey => tkey.Value.Emulator, tvalue => tvalue.Value.Extension); - } - + public static readonly FilesystemFilterSet AvailableImporters = new FilesystemFilterSet( + Importers.Values.OrderBy(attr => attr.Emulator) + .Select(attr => new FilesystemFilter(attr.Emulator, new[] { attr.Extension.Substring(1) })) // substring removes initial '.' + .ToArray() + ); // Attempt to import another type of movie file into a movie object. public static ImportResult ImportFile(string path) diff --git a/BizHawk.Client.EmuHawk/FileFilterEntry.cs b/BizHawk.Client.EmuHawk/FileFilterEntry.cs deleted file mode 100644 index 9465b9b940..0000000000 --- a/BizHawk.Client.EmuHawk/FileFilterEntry.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace BizHawk.Client.EmuHawk -{ - public class FileFilterEntry - { - public string Description { get; } - public string[] Filters { get; } - public string[] DeveloperFilters { get; } - - public FileFilterEntry(string description, string filters, string developerFilters = null) - { - Description = description; - Filters = filters?.Split(';') ?? Array.Empty(); - DeveloperFilters = developerFilters?.Split(';') ?? Array.Empty(); - } - - public IEnumerable EffectiveFilters - { - get - { - IEnumerable effectiveFilters = Filters; - if (VersionInfo.DeveloperBuild) - { - effectiveFilters = effectiveFilters.Concat(DeveloperFilters); - } - return effectiveFilters; - } - } - } -} diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index eb8aacc4b6..96d68d6bc1 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -341,7 +341,7 @@ namespace BizHawk.Client.EmuHawk else if (oac.Result == AdvancedRomLoaderType.MAMELaunchGame) { args.OpenAdvanced = new OpenAdvanced_MAME(); - filter = "MAME Arcade ROMs (*.zip)|*.zip"; + filter = new FilesystemFilter("MAME Arcade ROMs", new[] { "zip" }).ToString(); } else { @@ -510,7 +510,7 @@ namespace BizHawk.Client.EmuHawk { InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId), Multiselect = true, - Filter = ToFilter("Movie Files", MovieImport.AvailableImporters()), + Filter = MovieImport.AvailableImporters.ToString("Movie Files"), RestoreDirectory = false }; @@ -628,7 +628,7 @@ namespace BizHawk.Client.EmuHawk { InitialDirectory = Path.GetDirectoryName(path), FileName = Path.GetFileName(path), - Filter = "PNG File (*.png)|*.png" + Filter = FilesystemFilter.PNGs.ToString() }; if (sfd.ShowHawkDialog().IsOk()) @@ -1329,7 +1329,7 @@ namespace BizHawk.Client.EmuHawk { InitialDirectory = Path.GetDirectoryName(path), FileName = Path.GetFileName(path), - Filter = "Config File (*.ini)|*.ini" + Filter = ConfigFileFSFilterString }; if (sfd.ShowHawkDialog().IsOk()) @@ -1354,7 +1354,7 @@ namespace BizHawk.Client.EmuHawk { InitialDirectory = Path.GetDirectoryName(path), FileName = Path.GetFileName(path), - Filter = "Config File (*.ini)|*.ini" + Filter = ConfigFileFSFilterString }; if (ofd.ShowHawkDialog().IsOk()) @@ -1851,8 +1851,9 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId) - , Filter = "TI-83 Program Files (*.83p,*.8xp)|*.83P;*.8xp|All Files|*.*", RestoreDirectory = true + Filter = new FilesystemFilterSet(new FilesystemFilter("TI-83 Program Files", new[] { "83p", "8xp" })).ToString(), + InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId), + RestoreDirectory = true }; if (ofd.ShowDialog() @@ -2591,11 +2592,11 @@ namespace BizHawk.Client.EmuHawk { using var zxSnapExpDialog = new SaveFileDialog { - RestoreDirectory = true - , Title = "EXPERIMENTAL - Export 3rd party snapshot formats" - , DefaultExt = "szx" - , Filter = "ZX-State files (*.szx)|*.szx" - , SupportMultiDottedExtensions = true + DefaultExt = "szx", + Filter = new FilesystemFilter("ZX-State files", new[] { "szx" }).ToString(), + RestoreDirectory = true, + SupportMultiDottedExtensions = true, + Title = "EXPERIMENTAL - Export 3rd party snapshot formats" }; try diff --git a/BizHawk.Client.EmuHawk/MainForm.FileLoader.cs b/BizHawk.Client.EmuHawk/MainForm.FileLoader.cs index 23239c657b..4685f85921 100644 --- a/BizHawk.Client.EmuHawk/MainForm.FileLoader.cs +++ b/BizHawk.Client.EmuHawk/MainForm.FileLoader.cs @@ -39,9 +39,6 @@ namespace BizHawk.Client.EmuHawk } } - private IEnumerable KnownRomExtensions => - RomFilterEntries.SelectMany(f => f.EffectiveFilters.Where(s => s.StartsWith("*.", StringComparison.Ordinal)).Select(s => s.Substring(1).ToUpperInvariant())); - private readonly string[] _nonArchive = { ".ISO", ".CUE", ".CCD" }; #region Loaders diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 4598d4315c..fd0474b56e 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -6,7 +6,6 @@ using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; -using System.Text; using System.Threading; using System.Windows.Forms; @@ -1436,7 +1435,7 @@ namespace BizHawk.Client.EmuHawk } ofd.RestoreDirectory = true; - ofd.Filter = "Libretro Cores (*.dll)|*.dll"; + ofd.Filter = new FilesystemFilter("Libretro Cores", new[] { "dll" }).ToString(); if (ofd.ShowDialog() == DialogResult.Cancel) { @@ -2210,107 +2209,50 @@ namespace BizHawk.Client.EmuHawk } } - public static string ToFilter(string name, IDictionary entries) - { - var items = new List - { - name, - string.Join(";", entries.Select(e => $"*{e.Value}")) - }; + /// TODO add and handle (you can drag-and-drop scripts and there are already non-rom things in this list, so why not?) + private static readonly FilesystemFilterSet RomFSFilterSet = new FilesystemFilterSet( + new FilesystemFilter("Music Files", new string[0], devBuildExtraExts: new[] { "psf", "minipsf", "sid", "nsf" }), + new FilesystemFilter("Disc Images", new[] { "cue", "ccd", "mds", "m3u" }), + new FilesystemFilter("NES", new[] { "nes", "fds", "unf", "nsf" }, addArchiveExts: true), + new FilesystemFilter("Super NES", new[] { "smc", "sfc", "xml" }, addArchiveExts: true), + new FilesystemFilter("PlayStation", new[] { "cue", "ccd", "mds", "m3u" }), + new FilesystemFilter("PSX Executables (experimental)", new string[0], devBuildExtraExts: new[] { "exe" }), + new FilesystemFilter("PSF Playstation Sound File", new[] { "psf", "minipsf" }), + new FilesystemFilter("Nintendo 64", new[] { "z64", "v64", "n64" }), + new FilesystemFilter("Gameboy", new[] { "gb", "gbc", "sgb" }, addArchiveExts: true), + new FilesystemFilter("Gameboy Advance", new[] { "gba" }, addArchiveExts: true), + new FilesystemFilter("Master System", new[] { "sms", "gg", "sg" }, addArchiveExts: true), + new FilesystemFilter("PC Engine", new[] { "pce", "sgx", "cue", "ccd", "mds" }, addArchiveExts: true), + new FilesystemFilter("Atari 2600", new[] { "a26" }, devBuildExtraExts: new[] { "bin" }, addArchiveExts: true), + new FilesystemFilter("Atari 7800", new[] { "a78" }, devBuildExtraExts: new[] { "bin" }, addArchiveExts: true), + new FilesystemFilter("Atari Lynx", new[] { "lnx" }, addArchiveExts: true), + new FilesystemFilter("ColecoVision", new[] { "col" }, addArchiveExts: true), + new FilesystemFilter("IntelliVision", new[] { "int", "bin", "rom" }, addArchiveExts: true), + new FilesystemFilter("TI-83", new[] { "rom" }, addArchiveExts: true), + FilesystemFilter.Archives, + new FilesystemFilter("Genesis", new[] { "gen", "md", "smd", "32x", "bin", "cue", "ccd" }, addArchiveExts: true), + new FilesystemFilter("SID Commodore 64 Music File", new string[0], devBuildExtraExts: new[] { "sid" }, devBuildAddArchiveExts: true), + new FilesystemFilter("WonderSwan", new[] { "ws", "wsc" }, addArchiveExts: true), + new FilesystemFilter("Apple II", new[] { "dsk", "do", "po" }, addArchiveExts: true), + new FilesystemFilter("Virtual Boy", new[] { "vb" }, addArchiveExts: true), + new FilesystemFilter("Neo Geo Pocket", new[] { "ngp", "ngc" }, addArchiveExts: true), + new FilesystemFilter("Commodore 64", new[] { "prg", "d64", "g64", "crt", "tap" }, addArchiveExts: true), + new FilesystemFilter("Amstrad CPC", new string[0], devBuildExtraExts: new[] { "cdt", "dsk" }, devBuildAddArchiveExts: true), + new FilesystemFilter("Sinclair ZX Spectrum", new[] { "tzx", "tap", "dsk", "pzx", "csw", "wav" }, addArchiveExts: true), + new FilesystemFilter("Odyssey 2", new[] { "o2" }), + FilesystemFilter.EmuHawkSaveStates + ); - foreach (var kvp in entries) - { - items.Add(kvp.Key); - items.Add($"*{kvp.Value}"); - } + private static readonly IReadOnlyCollection KnownRomExtensions = RomFSFilterSet.Filters + .SelectMany(f => f.Extensions) + .Distinct() + .Except(FilesystemFilter.ArchiveExtensions.Concat(new[] { "State" })) + .Select(s => $".{s.ToUpperInvariant()}") // this is what's expected at call-site + .ToList(); - items.Add("All Files"); - items.Add("*.*"); + public static readonly string RomFilter = RomFSFilterSet.ToString("Everything"); - return FormatFilter(items.ToArray()); - } - - /// contains unpaired element - public static string FormatFilter(params string[] args) - { - var sb = new StringBuilder(); - if (args.Length % 2 != 0) - { - throw new ArgumentException(); - } - - var num = args.Length / 2; - for (int i = 0; i < num; i++) - { - sb.AppendFormat("{0} ({1})|{1}", args[i * 2], args[(i * 2) + 1]); - if (i != num - 1) - { - sb.Append('|'); - } - } - - var str = sb.ToString().Replace("%ARCH%", ArchiveFilters); - str = str.Replace(";", "; "); - return str; - } - - public static FileFilterEntry[] RomFilterEntries { get; } = - { - new FileFilterEntry("Music Files", null, developerFilters: "*.psf;*.minipsf;*.sid;*.nsf"), - new FileFilterEntry("Disc Images", "*.cue;*.ccd;*.mds;*.m3u"), - new FileFilterEntry("NES", "*.nes;*.fds;*.unf;*.nsf;%ARCH%"), - new FileFilterEntry("Super NES", "*.smc;*.sfc;*.xml;%ARCH%"), - new FileFilterEntry("PlayStation", "*.cue;*.ccd;*.mds;*.m3u"), - new FileFilterEntry("PSX Executables (experimental)", null, developerFilters: "*.exe"), - new FileFilterEntry("PSF Playstation Sound File", "*.psf;*.minipsf"), - new FileFilterEntry("Nintendo 64", "*.z64;*.v64;*.n64"), - new FileFilterEntry("Gameboy", "*.gb;*.gbc;*.sgb;%ARCH%"), - new FileFilterEntry("Gameboy Advance", "*.gba;%ARCH%"), - new FileFilterEntry("Master System", "*.sms;*.gg;*.sg;%ARCH%"), - new FileFilterEntry("PC Engine", "*.pce;*.sgx;*.cue;*.ccd;*.mds;%ARCH%"), - new FileFilterEntry("Atari 2600", "*.a26;%ARCH%", developerFilters: "*.bin"), - new FileFilterEntry("Atari 7800", "*.a78;%ARCH%", developerFilters: "*.bin"), - new FileFilterEntry("Atari Lynx", "*.lnx;%ARCH%"), - new FileFilterEntry("ColecoVision", "*.col;%ARCH%"), - new FileFilterEntry("IntelliVision", "*.int;*.bin;*.rom;%ARCH%"), - new FileFilterEntry("TI-83", "*.rom;%ARCH%"), - new FileFilterEntry("Archive Files", "%ARCH%"), - new FileFilterEntry("Genesis", "*.gen;*.md;*.smd;*.32x;*.bin;*.cue;*.ccd;%ARCH%"), - new FileFilterEntry("SID Commodore 64 Music File", null, developerFilters: "*.sid;%ARCH%"), - new FileFilterEntry("WonderSwan", "*.ws;*.wsc;%ARCH%"), - new FileFilterEntry("Apple II", "*.dsk;*.do;*.po;%ARCH%"), - new FileFilterEntry("Virtual Boy", "*.vb;%ARCH%"), - new FileFilterEntry("Neo Geo Pocket", "*.ngp;*.ngc;%ARCH%"), - new FileFilterEntry("Commodore 64", "*.prg;*.d64;*.g64;*.crt;*.tap;%ARCH%"), - new FileFilterEntry("Amstrad CPC", null, developerFilters: "*.cdt;*.dsk;%ARCH%"), - new FileFilterEntry("Sinclair ZX Spectrum", "*.tzx;*.tap;*.dsk;*.pzx;*.csw;*.wav;%ARCH%"), - new FileFilterEntry("Odyssey 2", "*.o2") - }; - - public const string ArchiveFilters = "*.zip;*.rar;*.7z;*.gz"; - - public static string RomFilter - { - get - { - string GetRomFilterStrings() - { - var values = new HashSet(RomFilterEntries.SelectMany(f => f.EffectiveFilters)); - if (values.Remove("%ARCH%")) - { - values.UnionWith(ArchiveFilters.Split(';')); - } - return string.Join(";", values.OrderBy(n => n)); - } - - var allFilters = new List { new FileFilterEntry("Rom Files", GetRomFilterStrings()) }; - allFilters.AddRange(RomFilterEntries.Where(f => f.EffectiveFilters.Any())); - allFilters.Add(new FileFilterEntry("Savestate", "*.state")); - allFilters.Add(new FileFilterEntry("All Files", "*.*")); - - return FormatFilter(allFilters.SelectMany(f => new[] { f.Description, string.Join(";", f.EffectiveFilters) }).ToArray()); - } - } + public static readonly string ConfigFileFSFilterString = new FilesystemFilter("Config File", new[] { "ini" }).ToString(); private void OpenRom() { @@ -3332,7 +3274,7 @@ namespace BizHawk.Client.EmuHawk sfd.InitialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.AvPathFragment, null); } - sfd.Filter = string.Format("{0} (*.{0})|*.{0}|All Files|*.*", ext); + sfd.Filter = new FilesystemFilterSet(new FilesystemFilter(ext, new[] { ext })).ToString(); var result = sfd.ShowHawkDialog(); if (result == DialogResult.Cancel) @@ -4267,7 +4209,7 @@ namespace BizHawk.Client.EmuHawk { AddExtension = true, DefaultExt = "State", - Filter = "Save States (*.State)|*.State|All Files|*.*", + Filter = new FilesystemFilterSet(FilesystemFilter.EmuHawkSaveStates).ToString(), InitialDirectory = path, FileName = $"{PathManager.SaveStatePrefix(Game)}.QuickSave0.State" }; @@ -4300,7 +4242,7 @@ namespace BizHawk.Client.EmuHawk using var ofd = new OpenFileDialog { InitialDirectory = PathManager.GetSaveStatePath(Game), - Filter = "Save States (*.State)|*.State|All Files|*.*", + Filter = new FilesystemFilterSet(FilesystemFilter.EmuHawkSaveStates).ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs b/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs index 42d9a1e3c6..4009956e9c 100644 --- a/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs +++ b/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs @@ -94,26 +94,9 @@ namespace BizHawk.Client.EmuHawk private void btnLibretroLaunchGame_Click(object sender, EventArgs e) { - //build a list of extensions suggested for use for this core - StringWriter sw = new StringWriter(); - foreach(var ext in _currentDescription.ValidExtensions.Split('|')) - sw.Write("*.{0};",ext); - var filter = sw.ToString(); - filter = filter.Substring(0,filter.Length-1); //remove last semicolon - var args = new List { "Rom Files" }; - if (!_currentDescription.NeedsArchives) - filter += ";%ARCH%"; - args.Add(filter); - if (!_currentDescription.NeedsArchives) - { - args.Add("Archive Files"); - args.Add("%ARCH%"); - } - args.Add("All Files"); - args.Add("*.*"); - filter = MainForm.FormatFilter(args.ToArray()); - SuggestedExtensionFilter = filter; - + var entries = new List { new FilesystemFilter("ROMs", _currentDescription.ValidExtensions.Split('|')) }; + if (!_currentDescription.NeedsArchives) entries.Add(FilesystemFilter.Archives); // "needs archives" means the relevant archive extensions are already in the list, and we shouldn't scan archives for roms + SuggestedExtensionFilter = new FilesystemFilterSet(entries.ToArray()).ToString(); Result = AdvancedRomLoaderType.LibretroLaunchGame; DialogResult = DialogResult.OK; Close(); diff --git a/BizHawk.Client.EmuHawk/config/DisplayConfig.cs b/BizHawk.Client.EmuHawk/config/DisplayConfig.cs index f1e7b8bf79..2774b5a254 100644 --- a/BizHawk.Client.EmuHawk/config/DisplayConfig.cs +++ b/BizHawk.Client.EmuHawk/config/DisplayConfig.cs @@ -243,7 +243,7 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - Filter = ".CGP (*.cgp)|*.cgp", + Filter = new FilesystemFilter(".CGP Files", new[] { "cgp" }).ToString(), FileName = _pathSelection }; if (ofd.ShowDialog() == DialogResult.OK) diff --git a/BizHawk.Client.EmuHawk/config/GB/BmpView.cs b/BizHawk.Client.EmuHawk/config/GB/BmpView.cs index 9adb98c73b..4d13cd23e7 100644 --- a/BizHawk.Client.EmuHawk/config/GB/BmpView.cs +++ b/BizHawk.Client.EmuHawk/config/GB/BmpView.cs @@ -106,7 +106,7 @@ namespace BizHawk.Client.EmuHawk { FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Palettes", InitialDirectory = path, - Filter = "PNG (*.png)|*.png|Bitmap (*.bmp)|*.bmp|All Files|*.*", + Filter = FilesystemFilterSet.Screenshots.ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/config/GB/ColorChooserForm.cs b/BizHawk.Client.EmuHawk/config/GB/ColorChooserForm.cs index 0b34b1a967..422eedcdef 100644 --- a/BizHawk.Client.EmuHawk/config/GB/ColorChooserForm.cs +++ b/BizHawk.Client.EmuHawk/config/GB/ColorChooserForm.cs @@ -309,7 +309,7 @@ namespace BizHawk.Client.EmuHawk using var ofd = new OpenFileDialog { InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["GB", "Palettes"].Path, "GB"), - Filter = "Gambatte Palettes (*.pal)|*.pal|All Files|*.*", + Filter = new FilesystemFilterSet(FilesystemFilter.Palettes).ToString(), RestoreDirectory = true }; @@ -346,7 +346,7 @@ namespace BizHawk.Client.EmuHawk { InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["GB", "Palettes"].Path, "GB"), FileName = $"{Global.Game.Name}.pal", - Filter = "Gambatte Palettes (*.pal)|*.pal|All Files|*.*", + Filter = new FilesystemFilterSet(FilesystemFilter.Palettes).ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/config/NES/NESGraphicsConfig.cs b/BizHawk.Client.EmuHawk/config/NES/NESGraphicsConfig.cs index 6cea4a179c..be5544629f 100644 --- a/BizHawk.Client.EmuHawk/config/NES/NESGraphicsConfig.cs +++ b/BizHawk.Client.EmuHawk/config/NES/NESGraphicsConfig.cs @@ -56,7 +56,7 @@ namespace BizHawk.Client.EmuHawk using var ofd = new OpenFileDialog { InitialDirectory = PathManager.MakeAbsolutePath(_config.PathEntries["NES", "Palettes"].Path, "NES"), - Filter = "Palette Files (.pal)|*.PAL|All Files (*.*)|*.*", + Filter = new FilesystemFilterSet(FilesystemFilter.Palettes).ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/config/NES/QuickNesConfig.cs b/BizHawk.Client.EmuHawk/config/NES/QuickNesConfig.cs index fe31f41089..3431e265c4 100644 --- a/BizHawk.Client.EmuHawk/config/NES/QuickNesConfig.cs +++ b/BizHawk.Client.EmuHawk/config/NES/QuickNesConfig.cs @@ -82,7 +82,7 @@ namespace BizHawk.Client.EmuHawk using var ofd = new OpenFileDialog { InitialDirectory = PathManager.MakeAbsolutePath(_config.PathEntries["NES", "Palettes"].Path, "NES"), - Filter = "Palette Files (.pal)|*.PAL|All Files (*.*)|*.*", + Filter = new FilesystemFilterSet(FilesystemFilter.Palettes).ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/movie/EditSubtitlesForm.cs b/BizHawk.Client.EmuHawk/movie/EditSubtitlesForm.cs index ce30c37b7e..f515efd328 100644 --- a/BizHawk.Client.EmuHawk/movie/EditSubtitlesForm.cs +++ b/BizHawk.Client.EmuHawk/movie/EditSubtitlesForm.cs @@ -200,7 +200,7 @@ namespace BizHawk.Client.EmuHawk using var form = new SaveFileDialog { AddExtension = true, - Filter = "SubRip Files (*.srt)|*.srt|All files (*.*)|*.*" + Filter = new FilesystemFilterSet(new FilesystemFilter("SubRip Files", new[] { "srt" })).ToString() }; var result = form.ShowDialog(); diff --git a/BizHawk.Client.EmuHawk/movie/PlayMovie.cs b/BizHawk.Client.EmuHawk/movie/PlayMovie.cs index 4975530ed5..ae9ea53e50 100644 --- a/BizHawk.Client.EmuHawk/movie/PlayMovie.cs +++ b/BizHawk.Client.EmuHawk/movie/PlayMovie.cs @@ -570,7 +570,7 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - Filter = $"Movie Files (*.{MovieService.DefaultExtension})|*.{MovieService.DefaultExtension}|TAS project Files (*.{TasMovie.Extension})|*.{TasMovie.Extension}|All Files|*.*", + Filter = new FilesystemFilterSet(FilesystemFilter.BizHawkMovies, FilesystemFilter.TAStudioProjects).ToString(), InitialDirectory = PathManager.MakeAbsolutePath(_config.PathEntries.MoviesPathFragment, null) }; diff --git a/BizHawk.Client.EmuHawk/movie/RecordMovie.cs b/BizHawk.Client.EmuHawk/movie/RecordMovie.cs index db53487a8d..093fc618d7 100644 --- a/BizHawk.Client.EmuHawk/movie/RecordMovie.cs +++ b/BizHawk.Client.EmuHawk/movie/RecordMovie.cs @@ -184,7 +184,7 @@ namespace BizHawk.Client.EmuHawk DefaultExt = $".{_movieSession.Movie.PreferredExtension}", FileName = RecordBox.Text, OverwritePrompt = false, - Filter = $"Movie Files (*.{_movieSession.Movie.PreferredExtension})|*.{_movieSession.Movie.PreferredExtension}|All Files|*.*" + Filter = new FilesystemFilterSet(new FilesystemFilter("Movie Files", new[] { _movieSession.Movie.PreferredExtension })).ToString() }; var result = sfd.ShowHawkDialog(); diff --git a/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs b/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs index ae26b4c960..bd7da76e47 100644 --- a/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs +++ b/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs @@ -926,12 +926,12 @@ namespace BizHawk.Client.EmuHawk { using var sfd = new SaveFileDialog { - Filter = "Text (*.txt)|*.txt|All Files|*.*" - , RestoreDirectory = true - , InitialDirectory = RomDirectory - , FileName = _domain.Name == "File on Disk" + FileName = _domain.Name == "File on Disk" ? $"{Path.GetFileNameWithoutExtension(RomName)}.txt" - : PathManager.FilesystemSafeName(Global.Game) + : PathManager.FilesystemSafeName(Global.Game), + Filter = new FilesystemFilterSet(FilesystemFilter.TextFiles).ToString(), + InitialDirectory = RomDirectory, + RestoreDirectory = true }; var result = sfd.ShowHawkDialog(); @@ -1253,7 +1253,10 @@ namespace BizHawk.Client.EmuHawk using var sfd = new OpenFileDialog { - Filter = "Binary (*.bin)|*.bin|Save Files (*.sav)|*.sav|All Files|*.*", + Filter = new FilesystemFilterSet( + new FilesystemFilter("Binary", new[] { "bin" }), + new FilesystemFilter("Save Files", new[] { "sav" }) + ).ToString(), RestoreDirectory = true, }; @@ -1307,7 +1310,7 @@ namespace BizHawk.Client.EmuHawk { FileName = $"{Path.GetFileNameWithoutExtension(romName)}.tbl", InitialDirectory = initialDirectory, - Filter = "Text Table files (*.tbl)|*.tbl|All Files|*.*", + Filter = new FilesystemFilterSet(new FilesystemFilter("Text Table Files", new[] { "tbl" })).ToString(), RestoreDirectory = false }; diff --git a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Forms.cs b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Forms.cs index 035a650cee..90f71c4172 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Forms.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Forms.cs @@ -408,7 +408,7 @@ namespace BizHawk.Client.EmuHawk } openFileDialog1.AddExtension = true; - openFileDialog1.Filter = filter ?? "All Files (*.*)|*"; + openFileDialog1.Filter = filter ?? FilesystemFilter.AllFilesEntry; if (openFileDialog1.ShowDialog() == DialogResult.OK) { diff --git a/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs b/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs index f2e50bc478..bc703b7ac8 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs @@ -21,6 +21,8 @@ namespace BizHawk.Client.EmuHawk private const string ScriptColumnName = "Script"; private const string PathColumnName = "PathName"; + private static readonly FilesystemFilterSet SessionsFSFilterSet = new FilesystemFilterSet(new FilesystemFilter("Lua Session Files", new[] { "luases" })); + private readonly LuaAutocompleteInstaller _luaAutoInstaller = new LuaAutocompleteInstaller(); private readonly List _watches = new List(); @@ -581,7 +583,7 @@ namespace BizHawk.Client.EmuHawk sfd.InitialDirectory = PathManager.GetLuaPath(); } - sfd.Filter = "Lua Session Files (*.luases)|*.luases|All Files|*.*"; + sfd.Filter = SessionsFSFilterSet.ToString(); sfd.RestoreDirectory = true; var result = sfd.ShowHawkDialog(); if (result != DialogResult.OK) @@ -709,7 +711,7 @@ namespace BizHawk.Client.EmuHawk var ofd = new OpenFileDialog { InitialDirectory = PathManager.GetLuaPath(), - Filter = "Lua Session Files (*.luases)|*.luases|All Files|*.*", + Filter = SessionsFSFilterSet.ToString(), RestoreDirectory = true, Multiselect = false }; @@ -790,7 +792,7 @@ namespace BizHawk.Client.EmuHawk Path.GetFileNameWithoutExtension(LuaImp.ScriptList.Filename) : Path.GetFileNameWithoutExtension(Global.Game.Name), OverwritePrompt = true, - Filter = "Lua Scripts (*.lua)|*.lua|All Files (*.*)|*.*" + Filter = new FilesystemFilterSet(FilesystemFilter.LuaScripts).ToString() }; var result = sfd.ShowHawkDialog(); @@ -815,7 +817,7 @@ namespace BizHawk.Client.EmuHawk var ofd = new OpenFileDialog { InitialDirectory = PathManager.GetLuaPath(), - Filter = "Lua Scripts (*.lua)|*.lua|Text (*.text)|*.txt|All Files|*.*", + Filter = new FilesystemFilterSet(FilesystemFilter.LuaScripts, FilesystemFilter.TextFiles).ToString(), RestoreDirectory = true, Multiselect = true }; @@ -945,7 +947,7 @@ namespace BizHawk.Client.EmuHawk DefaultExt = ".lua", FileName = $"{Path.GetFileNameWithoutExtension(script.Path)} (1)", OverwritePrompt = true, - Filter = "Lua Scripts (*.lua)|*.lua|All Files (*.*)|*.*" + Filter = new FilesystemFilterSet(FilesystemFilter.LuaScripts).ToString() }; if (sfd.ShowDialog() == DialogResult.OK) diff --git a/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs b/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs index bb06dacc10..59d8859d42 100644 --- a/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs +++ b/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs @@ -15,6 +15,8 @@ namespace BizHawk.Client.EmuHawk [RequiredService] private IEmulator Emulator { get; set; } + private static readonly FilesystemFilterSet MacrosFSFilterSet = new FilesystemFilterSet(new FilesystemFilter("Movie Macros", new[] { "bk2m" })); + private readonly List _zones = new List(); private readonly List _unsavedZones = new List(); private bool _selecting; @@ -288,7 +290,7 @@ namespace BizHawk.Client.EmuHawk { InitialDirectory = SuggestedFolder(), FileName = macro.Name, - Filter = "Movie Macros (*.bk2m)|*.bk2m|All Files|*.*" + Filter = MacrosFSFilterSet.ToString() }; // Create directory? @@ -321,7 +323,7 @@ namespace BizHawk.Client.EmuHawk using var dialog = new OpenFileDialog { InitialDirectory = SuggestedFolder(), - Filter = "Movie Macros (*.bk2m)|*.bk2m|All Files|*.*" + Filter = MacrosFSFilterSet.ToString() }; DialogResult result = dialog.ShowHawkDialog(); diff --git a/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskBundler.cs b/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskBundler.cs index 842c5f709e..78fe092692 100644 --- a/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskBundler.cs +++ b/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskBundler.cs @@ -249,7 +249,7 @@ namespace BizHawk.Client.EmuHawk { FileName = filename, InitialDirectory = initialDirectory, - Filter = "xml (*.xml)|*.xml|All Files|*.*" + Filter = new FilesystemFilterSet(new FilesystemFilter("XML Files", new[] { "xml" })).ToString() }; var result = sfd.ShowHawkDialog(); diff --git a/BizHawk.Client.EmuHawk/tools/NES/NESMusicRipper.cs b/BizHawk.Client.EmuHawk/tools/NES/NESMusicRipper.cs index cd2c8014e7..dc7817200a 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/NESMusicRipper.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/NESMusicRipper.cs @@ -112,7 +112,7 @@ namespace BizHawk.Client.EmuHawk //acquire target using var sfd = new SaveFileDialog { - Filter = "XRNS (*.xrns)|*.xrns" + Filter = new FilesystemFilter("Renoise Song Files", new[] { "xrns" }).ToString() }; if (sfd.ShowDialog() != DialogResult.OK) { diff --git a/BizHawk.Client.EmuHawk/tools/NES/NameTableViewer.cs b/BizHawk.Client.EmuHawk/tools/NES/NameTableViewer.cs index 77737b2779..11bb024f94 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/NameTableViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/NameTableViewer.cs @@ -70,7 +70,7 @@ namespace BizHawk.Client.EmuHawk { FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Nametables", InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Screenshots"].Path, "NES"), - Filter = "PNG (*.png)|*.png|Bitmap (*.bmp)|*.bmp|All Files|*.*", + Filter = FilesystemFilterSet.Screenshots.ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/tools/NES/PaletteViewer.cs b/BizHawk.Client.EmuHawk/tools/NES/PaletteViewer.cs index bca3623644..a95d433d2a 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/PaletteViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/PaletteViewer.cs @@ -76,7 +76,7 @@ namespace BizHawk.Client.EmuHawk { FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Palettes", InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Screenshots"].Path, "NES"), - Filter = "PNG (*.png)|*.png|Bitmap (*.bmp)|*.bmp|All Files|*.*", + Filter = FilesystemFilterSet.Screenshots.ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/tools/NES/PatternViewer.cs b/BizHawk.Client.EmuHawk/tools/NES/PatternViewer.cs index a37f2fa3cf..61b1d085a3 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/PatternViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/PatternViewer.cs @@ -38,7 +38,7 @@ namespace BizHawk.Client.EmuHawk { FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Patterns", InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Screenshots"].Path, "NES"), - Filter = "PNG (*.png)|*.png|Bitmap (*.bmp)|*.bmp|All Files|*.*", + Filter = FilesystemFilterSet.Screenshots.ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/tools/NES/SpriteViewer.cs b/BizHawk.Client.EmuHawk/tools/NES/SpriteViewer.cs index ba50de9063..77638853ec 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/SpriteViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/SpriteViewer.cs @@ -40,7 +40,7 @@ namespace BizHawk.Client.EmuHawk { FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Sprites", InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Screenshots"].Path, "NES"), - Filter = "PNG (*.png)|*.png|Bitmap (*.bmp)|*.bmp|All Files|*.*", + Filter = FilesystemFilterSet.Screenshots.ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs index 899c1c2dc9..f7da21a81d 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs @@ -100,14 +100,15 @@ namespace BizHawk.Client.EmuHawk } // need to be fancy here, so call the ofd constructor directly instead of helper - var all = $"*.{string.Join(";*.", MovieService.MovieExtensions.Reverse())}"; var ofd = new OpenFileDialog { FileName = filename, InitialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.MoviesPathFragment, null), - Filter = string.Format( - "All Available Files ({0})|{0}|TAS Project Files (*.{1})|*.{1}|Movie Files (*.{2})|*.{2}|All Files|*.*", - all, TasMovie.Extension, MovieService.DefaultExtension) + Filter = new FilesystemFilterSet( + new FilesystemFilter("All Available Files", MovieService.MovieExtensions.Reverse().ToArray()), + FilesystemFilter.TAStudioProjects, + FilesystemFilter.BizHawkMovies + ).ToString() }; var result = ofd.ShowHawkDialog(); diff --git a/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs b/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs index 0edb3c1e0c..dfc595272f 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs @@ -28,7 +28,7 @@ namespace BizHawk.Client.EmuHawk ? Path.GetFileName(currentFile) : $"{PathManager.FilesystemSafeName(Global.Game)}.{fileExt}", InitialDirectory = path, - Filter = string.Format("{0} (*.{1})|*.{1}|All Files|*.*", fileType, fileExt), + Filter = new FilesystemFilterSet(new FilesystemFilter(fileType, new[] { fileExt })).ToString(), RestoreDirectory = true }; @@ -54,7 +54,7 @@ namespace BizHawk.Client.EmuHawk ? Path.GetFileName(currentFile) : $"{PathManager.FilesystemSafeName(Global.Game)}.{fileExt}", InitialDirectory = path, - Filter = string.Format("{0} (*.{1})|*.{1}|All Files|*.*", fileType, fileExt), + Filter = new FilesystemFilterSet(new FilesystemFilter(fileType, new[] { fileExt })).ToString(), RestoreDirectory = true, }; diff --git a/BizHawk.Client.EmuHawk/tools/TraceLogger.cs b/BizHawk.Client.EmuHawk/tools/TraceLogger.cs index dac0291bb8..24d1ad8a8e 100644 --- a/BizHawk.Client.EmuHawk/tools/TraceLogger.cs +++ b/BizHawk.Client.EmuHawk/tools/TraceLogger.cs @@ -301,7 +301,10 @@ namespace BizHawk.Client.EmuHawk sfd.InitialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.LogPathFragment, null); } - sfd.Filter = "Log Files (*.log)|*.log|Text Files (*.txt)|*.txt|All Files|*.*"; + sfd.Filter = new FilesystemFilterSet( + new FilesystemFilter("Log Files", new[] { "log" }), + FilesystemFilter.TextFiles + ).ToString(); sfd.RestoreDirectory = true; var result = sfd.ShowHawkDialog(); return result.IsOk() ? new FileInfo(sfd.FileName) : null;