diff --git a/CHANGELIST.md b/CHANGELIST.md index 5e31bbd2..a03f8708 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -21,6 +21,7 @@ - Add PIC models for BD (unused) - Handle PIC based on disc type - UMDs always have "2 layers" +- Add dumping program selection to main UI ### 2.5 (2023-03-12) diff --git a/MPF.Check/Program.cs b/MPF.Check/Program.cs index a2a19b23..c587dfb0 100644 --- a/MPF.Check/Program.cs +++ b/MPF.Check/Program.cs @@ -59,7 +59,7 @@ namespace MPF.Check if (!string.IsNullOrWhiteSpace(path)) drive = Drive.Create(null, path); - var env = new DumpEnvironment(options, filepath, drive, knownSystem, mediaType, null); + var env = new DumpEnvironment(options, filepath, drive, knownSystem, mediaType, internalProgram: null, parameters: null); // Finally, attempt to do the output dance var result = env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress).ConfigureAwait(false).GetAwaiter().GetResult(); diff --git a/MPF.Core/Converters/EnumConverter.cs b/MPF.Core/Converters/EnumConverter.cs index e11be6bc..0b935dd3 100644 --- a/MPF.Core/Converters/EnumConverter.cs +++ b/MPF.Core/Converters/EnumConverter.cs @@ -98,7 +98,6 @@ namespace MPF.Core.Converters if (!LongNameMethods.TryGetValue(sourceType, out MethodInfo method)) { - method = typeof(RedumpLib.Data.Extensions).GetMethod("LongName", new[] { typeof(Nullable<>).MakeGenericType(sourceType) }); if (method == null) method = typeof(EnumConverter).GetMethod("LongName", new[] { typeof(Nullable<>).MakeGenericType(sourceType) }); diff --git a/MPF.Library/DumpEnvironment.cs b/MPF.Library/DumpEnvironment.cs index 21013c3a..5deed256 100644 --- a/MPF.Library/DumpEnvironment.cs +++ b/MPF.Library/DumpEnvironment.cs @@ -42,6 +42,11 @@ namespace MPF.Library /// public MediaType? Type { get; private set; } + /// + /// Currently selected dumping program + /// + public InternalProgram InternalProgram { get; private set; } + /// /// Options object representing user-defined options /// @@ -86,12 +91,14 @@ namespace MPF.Library /// /// /// + /// /// public DumpEnvironment(Options options, string outputPath, Drive drive, RedumpSystem? system, MediaType? type, + InternalProgram? internalProgram, string parameters) { // Set options object @@ -104,6 +111,7 @@ namespace MPF.Library this.Drive = drive; this.System = system ?? options.DefaultSystem; this.Type = type ?? MediaType.NONE; + this.InternalProgram = internalProgram ?? options.InternalProgram; // Dumping program SetParameters(parameters); @@ -154,7 +162,7 @@ namespace MPF.Library /// String representation of the parameters public void SetParameters(string parameters) { - switch (Options.InternalProgram) + switch (this.InternalProgram) { // Dumping support case InternalProgram.Aaru: @@ -212,7 +220,7 @@ namespace MPF.Library return null; // Set the proper parameters - switch (Options.InternalProgram) + switch (this.InternalProgram) { case InternalProgram.Aaru: Parameters = new Modules.Aaru.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options); @@ -283,10 +291,10 @@ namespace MPF.Library } // Execute internal tool - progress?.Report(Result.Success($"Executing {Options.InternalProgram}... {(Options.ToolsInSeparateWindow ? "please wait!" : "see log for output!")}")); + progress?.Report(Result.Success($"Executing {this.InternalProgram}... {(Options.ToolsInSeparateWindow ? "please wait!" : "see log for output!")}")); Directory.CreateDirectory(Path.GetDirectoryName(this.OutputPath)); await Task.Run(() => Parameters.ExecuteInternalProgram(Options.ToolsInSeparateWindow)); - progress?.Report(Result.Success($"{Options.InternalProgram} has finished!")); + progress?.Report(Result.Success($"{this.InternalProgram} has finished!")); // Execute additional tools progress?.Report(Result.Success("Running any additional tools... see log for output!")); @@ -350,7 +358,7 @@ namespace MPF.Library } // Reset the drive automatically if configured to - if (Options.InternalProgram == InternalProgram.DiscImageCreator && Options.DICResetDriveAfterDump) + if (this.InternalProgram == InternalProgram.DiscImageCreator && Options.DICResetDriveAfterDump) { resultProgress?.Report(Result.Success($"Resetting drive {Drive.Letter}")); await ResetDrive(); diff --git a/MPF.Test/Library/DumpEnvironmentTests.cs b/MPF.Test/Library/DumpEnvironmentTests.cs index d0717af4..370321ee 100644 --- a/MPF.Test/Library/DumpEnvironmentTests.cs +++ b/MPF.Test/Library/DumpEnvironmentTests.cs @@ -24,7 +24,7 @@ namespace MPF.Test.Library ? Drive.Create(InternalDriveType.Floppy, letter.ToString()) : Drive.Create(InternalDriveType.Optical, letter.ToString()); - var env = new DumpEnvironment(options, string.Empty, drive, RedumpSystem.IBMPCcompatible, mediaType, parameters); + var env = new DumpEnvironment(options, string.Empty, drive, RedumpSystem.IBMPCcompatible, mediaType, null, parameters); bool actual = env.ParametersValid(); Assert.Equal(expected, actual); diff --git a/MPF.Test/Library/InfoToolTests.cs b/MPF.Test/Library/InfoToolTests.cs index 88803914..28775bf1 100644 --- a/MPF.Test/Library/InfoToolTests.cs +++ b/MPF.Test/Library/InfoToolTests.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; using MPF.Library; using RedumpLib.Data; using Xunit; @@ -58,6 +59,9 @@ namespace MPF.Test.Library [InlineData("superhero\\blah&foo.bin", "superhero\\blah&foo.bin")] public void NormalizeOutputPathsTest(string outputPath, string expectedPath) { + if (!string.IsNullOrWhiteSpace(expectedPath)) + expectedPath = Path.GetFullPath(expectedPath); + string actualPath = InfoTool.NormalizeOutputPaths(outputPath); Assert.Equal(expectedPath, actualPath); } diff --git a/MPF/ComboBoxItems/KnownSystemComboBoxItem.cs b/MPF/ComboBoxItems/RedumpSystemComboBoxItem.cs similarity index 100% rename from MPF/ComboBoxItems/KnownSystemComboBoxItem.cs rename to MPF/ComboBoxItems/RedumpSystemComboBoxItem.cs diff --git a/MPF/ViewModels/MainViewModel.cs b/MPF/ViewModels/MainViewModel.cs index d2feea16..87df3a87 100644 --- a/MPF/ViewModels/MainViewModel.cs +++ b/MPF/ViewModels/MainViewModel.cs @@ -51,6 +51,11 @@ namespace MPF.UI.ViewModels /// public List Systems { get; set; } = RedumpSystemComboBoxItem.GenerateElements().ToList(); + /// + /// List of available internal programs + /// + public List> InternalPrograms { get; set; } = new List>(); + #endregion #region Private Event Flags @@ -161,7 +166,7 @@ namespace MPF.UI.ViewModels /// /// Populate media type according to system type /// - public void PopulateMediaType() + private void PopulateMediaType() { RedumpSystem? currentSystem = App.Instance.SystemTypeComboBox.SelectedItem as RedumpSystemComboBoxItem; @@ -186,6 +191,27 @@ namespace MPF.UI.ViewModels App.Instance.UpdateLayout(); } + /// + /// Populate media type according to system type + /// + private void PopulateInternalPrograms() + { + // Get the current internal program + InternalProgram internalProgram = App.Options.InternalProgram; + + // Create a static list of supported programs, not everything + var internalPrograms = new List { InternalProgram.DiscImageCreator, InternalProgram.Aaru, InternalProgram.Redumper, InternalProgram.DD }; + InternalPrograms = internalPrograms.Select(ip => new Element(ip)).ToList(); + App.Instance.DumpingProgramComboBox.ItemsSource = InternalPrograms; + + // Select the current default dumping program + int currentIndex = InternalPrograms.FindIndex(m => m == internalProgram); + App.Instance.DumpingProgramComboBox.SelectedIndex = (currentIndex > -1 ? currentIndex : 0); + + // Ensure the UI gets updated + App.Instance.UpdateLayout(); + } + #endregion #region UI Commands @@ -557,6 +583,9 @@ namespace MPF.UI.ViewModels CacheCurrentDiscType(); SetCurrentDiscType(); + // Set the dumping program + await App.Instance.Dispatcher.InvokeAsync(PopulateInternalPrograms); + // Set the initial environment and UI values SetSupportedDriveSpeed(); Env = DetermineEnvironment(); @@ -632,6 +661,7 @@ namespace MPF.UI.ViewModels App.Instance.MediaTypeComboBox.SelectionChanged += MediaTypeComboBoxSelectionChanged; App.Instance.DriveLetterComboBox.SelectionChanged += DriveLetterComboBoxSelectionChanged; App.Instance.DriveSpeedComboBox.SelectionChanged += DriveSpeedComboBoxSelectionChanged; + App.Instance.DumpingProgramComboBox.SelectionChanged += DumpingProgramComboBoxSelectionChanged; // User Area TextChanged App.Instance.OutputPathTextBox.TextChanged += OutputPathTextBoxTextChanged; @@ -929,6 +959,7 @@ namespace MPF.UI.ViewModels App.Instance.DriveLetterComboBox.SelectedItem as Drive, App.Instance.SystemTypeComboBox.SelectedItem as RedumpSystemComboBoxItem, App.Instance.MediaTypeComboBox.SelectedItem as Element, + App.Instance.DumpingProgramComboBox.SelectedItem as Element, App.Instance.ParametersTextBox.Text); } @@ -1116,7 +1147,7 @@ namespace MPF.UI.ViewModels string output = Protection.FormatProtections(protections); // If SmartE is detected on the current disc, remove `/sf` from the flags for DIC only - if (Env.Options.InternalProgram == InternalProgram.DiscImageCreator && output.Contains("SmartE")) + if (Env.InternalProgram == InternalProgram.DiscImageCreator && output.Contains("SmartE")) { ((Modules.DiscImageCreator.Parameters)Env.Parameters)[Modules.DiscImageCreator.FlagStrings.ScanFileProtect] = false; App.Logger.VerboseLogLn($"SmartE detected, removing {Modules.DiscImageCreator.FlagStrings.ScanFileProtect} from parameters"); @@ -1515,6 +1546,15 @@ namespace MPF.UI.ViewModels EnsureDiscInformation(); } + /// + /// Handler for DumpingProgramComboBox SelectionChanged event + /// + private void DumpingProgramComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (_canExecuteSelectionChanged) + EnsureDiscInformation(); + } + /// /// Handler for EnableParametersCheckBox Click event /// diff --git a/MPF/Windows/MainWindow.xaml b/MPF/Windows/MainWindow.xaml index fff10854..5fbb7dc9 100644 --- a/MPF/Windows/MainWindow.xaml +++ b/MPF/Windows/MainWindow.xaml @@ -119,6 +119,7 @@ +