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 @@
+
@@ -152,9 +153,12 @@
-
-
-
+
+
+
+
+
+
diff --git a/MPF/Windows/OptionsWindow.xaml b/MPF/Windows/OptionsWindow.xaml
index 3032638b..f993124e 100644
--- a/MPF/Windows/OptionsWindow.xaml
+++ b/MPF/Windows/OptionsWindow.xaml
@@ -118,7 +118,7 @@
-
+