diff --git a/DICUI.Test/DICUI.Test.csproj b/DICUI.Test/DICUI.Test.csproj index 2c2aeea3..a18cab5e 100644 --- a/DICUI.Test/DICUI.Test.csproj +++ b/DICUI.Test/DICUI.Test.csproj @@ -65,6 +65,7 @@ + diff --git a/DICUI.Test/DumpEnvironmentTest.cs b/DICUI.Test/DumpEnvironmentTest.cs index bdafdaa1..f701afcb 100644 --- a/DICUI.Test/DumpEnvironmentTest.cs +++ b/DICUI.Test/DumpEnvironmentTest.cs @@ -1,4 +1,5 @@ using DICUI.Data; +using DICUI.Utilities; using Xunit; namespace DICUI.Test @@ -6,18 +7,18 @@ namespace DICUI.Test public class DumpEnvironmentTest { [Theory] - [InlineData(null, false, MediaType.NONE, false)] - [InlineData("", false, MediaType.NONE, false)] - [InlineData("cd F test.bin 8 /c2 20", false, MediaType.CD, true)] - [InlineData("fd A test.img", true, MediaType.Floppy, true)] - [InlineData("dvd X test.iso 8 /raw", false, MediaType.Floppy, false)] - [InlineData("stop D", false, MediaType.DVD, true)] - public void IsConfigurationValidTest(string parameters, bool isFloppy, MediaType? mediaType, bool expected) + [InlineData(null, 'D', false, MediaType.NONE, false)] + [InlineData("", 'D', false, MediaType.NONE, false)] + [InlineData("cd F test.bin 8 /c2 20", 'F', false, MediaType.CD, true)] + [InlineData("fd A test.img", 'A', true, MediaType.Floppy, true)] + [InlineData("dvd X test.iso 8 /raw", 'X', false, MediaType.Floppy, false)] + [InlineData("stop D", 'D', false, MediaType.DVD, true)] + public void IsConfigurationValidTest(string parameters, char letter, bool isFloppy, MediaType? mediaType, bool expected) { var env = new DumpEnvironment { DICParameters = parameters, - IsFloppy = isFloppy, + Drive = isFloppy ? Drive.Floppy(letter) : Drive.Optical(letter, ""), Type = mediaType, }; @@ -44,7 +45,7 @@ namespace DICUI.Test Assert.Equal(parameters, env.DICParameters); Assert.Equal(expectedMediaType, env.Type); Assert.Equal(expectedKnownSystem, env.System); - Assert.Equal(expectedDriveLetter, env.DriveLetter); + Assert.Equal(expectedDriveLetter, env.Drive.Letter); Assert.Equal(expectedOutputDirectory, env.OutputDirectory); Assert.Equal(expectedOutputFilename, env.OutputFilename); } diff --git a/DICUI.Test/Utilities/ConvertersTest.cs b/DICUI.Test/Utilities/ConvertersTest.cs index ca554c7f..c8c1acee 100644 --- a/DICUI.Test/Utilities/ConvertersTest.cs +++ b/DICUI.Test/Utilities/ConvertersTest.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using DICUI.Data; using DICUI.Utilities; using Xunit; @@ -119,5 +120,39 @@ namespace DICUI.Test.Utilities string actual = Converters.KnownSystemToString(knownSystem); Assert.Equal(expected, actual); } + + [Fact] + public void KnownSystemHasValidCategory() + { + var values = Validators.CreateListOfSystems(); + KnownSystem[] markers = { KnownSystem.MarkerArcadeEnd, KnownSystem.MarkerConsoleEnd, KnownSystem.MarkerComputerEnd, KnownSystem.MarkerOtherEnd }; + + values.ForEach(system => { + if (system == KnownSystem.NONE || system == KnownSystem.Custom) + return; + + // we check that the category is the first category value higher than the system + KnownSystemCategory category = ((KnownSystem?)system).Category(); + KnownSystem marker = KnownSystem.NONE; + + switch (category) + { + case KnownSystemCategory.Arcade: marker = KnownSystem.MarkerArcadeEnd; break; + case KnownSystemCategory.Console: marker = KnownSystem.MarkerConsoleEnd; break; + case KnownSystemCategory.Computer: marker = KnownSystem.MarkerComputerEnd; break; + case KnownSystemCategory.Other: marker = KnownSystem.MarkerOtherEnd; break; + } + + Assert.NotEqual(KnownSystem.NONE, marker); + Assert.True(marker > system); + + Array.ForEach(markers, mmarker => + { + // a marker can be the same of the found one, or one of a category before or a category after but never in the middle between + // the system and the mapped category + Assert.True(mmarker == marker || mmarker < system || mmarker > marker); + }); + }); + } } } diff --git a/DICUI.Test/Utilities/DriveTest.cs b/DICUI.Test/Utilities/DriveTest.cs new file mode 100644 index 00000000..2d96348e --- /dev/null +++ b/DICUI.Test/Utilities/DriveTest.cs @@ -0,0 +1,21 @@ +using DICUI.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + + +namespace DICUI.Test.Utilities +{ + public class DriveTest + { + [Fact] + public void DriveConstructorsTest() + { + Assert.True(Drive.Floppy('a').IsFloppy); + Assert.False(Drive.Optical('d', "test").IsFloppy); + } + } +} diff --git a/DICUI.Test/Utilities/KnownSystemExtensionsTest.cs b/DICUI.Test/Utilities/KnownSystemExtensionsTest.cs index 0e1fed27..9611295f 100644 --- a/DICUI.Test/Utilities/KnownSystemExtensionsTest.cs +++ b/DICUI.Test/Utilities/KnownSystemExtensionsTest.cs @@ -1,4 +1,5 @@ -using DICUI.Data; +using System; +using DICUI.Data; using DICUI.Utilities; using Xunit; @@ -6,6 +7,20 @@ namespace DICUI.Test.Utilities { public class KnownSystemExtensionsTest { + [Fact] + public void NameTest() + { + var values = (KnownSystem[])Enum.GetValues(typeof(KnownSystem)); + + Array.ForEach(values, system => + { + string expected = Converters.KnownSystemToString(system); + string actual = ((KnownSystem?)system).Name(); + + Assert.Equal(expected, actual); + }); + } + [Theory] [InlineData(KnownSystem.AppleMacintosh, true)] [InlineData(KnownSystem.MicrosoftXBOX, false)] @@ -17,5 +32,38 @@ namespace DICUI.Test.Utilities bool actual = knownSystem.DoesSupportDriveSpeed(); Assert.Equal(expected, actual); } + + + [Fact] + public void IsMarkerTest() + { + var values = (KnownSystem[])Enum.GetValues(typeof(KnownSystem)); + + Array.ForEach(values, system => + { + bool expected = system == KnownSystem.MarkerArcadeEnd || system == KnownSystem.MarkerComputerEnd || + system == KnownSystem.MarkerOtherEnd || system == KnownSystem.MarkerConsoleEnd; + + bool actual = ((KnownSystem?)system).IsMarker(); + + Assert.Equal(expected, actual); + }); + } + + [Fact] + public void CategoryNameNotEmptyTest() + { + var values = (KnownSystemCategory[])Enum.GetValues(typeof(KnownSystemCategory)); + + Array.ForEach(values, system => + { + string actual = ((KnownSystem?)system).Name(); + + Assert.NotEqual("", actual); + }); + } + + + } } diff --git a/DICUI.Test/Utilities/ValidatorsTest.cs b/DICUI.Test/Utilities/ValidatorsTest.cs index 16d34347..c2d69d54 100644 --- a/DICUI.Test/Utilities/ValidatorsTest.cs +++ b/DICUI.Test/Utilities/ValidatorsTest.cs @@ -23,7 +23,7 @@ namespace DICUI.Test.Utilities [Fact] public void CreateListOfSystemsTest() { - int expected = Enum.GetValues(typeof(KnownSystem)).Length + 4; // + 4 for the separators + int expected = Enum.GetValues(typeof(KnownSystem)).Length - 4; // - 4 for markers categories var actual = Validators.CreateListOfSystems(); Assert.Equal(expected, actual.Count); } diff --git a/DICUI/DICUI.csproj b/DICUI/DICUI.csproj index afa2b9e6..29631f7d 100644 --- a/DICUI/DICUI.csproj +++ b/DICUI/DICUI.csproj @@ -92,8 +92,6 @@ Designer - - diff --git a/DICUI/Data/Constants.cs b/DICUI/Data/Constants.cs index 46f6702a..3c7b7ebc 100644 --- a/DICUI/Data/Constants.cs +++ b/DICUI/Data/Constants.cs @@ -1,4 +1,5 @@ -using System; +using DICUI.Utilities; +using System; using System.Collections.Generic; using System.Linq; using System.Windows.Media; @@ -12,7 +13,6 @@ namespace DICUI.Data { public const string StartDumping = "Start Dumping"; public const string StopDumping = "Stop Dumping"; - public const string FloppyDriveString = "<>"; // Private lists of known drive speed ranges private static IReadOnlyList AllowedDriveSpeedsForCD { get; } = new List { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 }; @@ -50,6 +50,32 @@ namespace DICUI.Data public static DoubleCollection AllowedDriveSpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(AllowedDriveSpeedsForBD); private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList list) => new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList()); + + public class KnownSystemComboBoxItem + { + private object data; + + public KnownSystemComboBoxItem(KnownSystem? system) => data = system; + public KnownSystemComboBoxItem(KnownSystemCategory? category) => data = category; + + public Brush Foreground { get => IsHeader() ? Brushes.Gray : Brushes.Black; } + + public bool IsHeader() => data is KnownSystemCategory?; + public bool IsSystem() => data is KnownSystem?; + + public static implicit operator KnownSystem? (KnownSystemComboBoxItem item) => item.data as KnownSystem?; + + public string Name + { + get + { + if (IsHeader()) + return "---------- " + (data as KnownSystemCategory?).Name() + " ----------"; + else + return (data as KnownSystem?).Name(); + } + } + } } /// diff --git a/DICUI/Data/Enumerations.cs b/DICUI/Data/Enumerations.cs index adf36fd3..7286f260 100644 --- a/DICUI/Data/Enumerations.cs +++ b/DICUI/Data/Enumerations.cs @@ -39,6 +39,8 @@ VTechVFlashVSmilePro, ZAPiTGamesGameWaveFamilyEntertainmentSystem, + MarkerConsoleEnd, + #endregion #region Computers @@ -52,6 +54,8 @@ NECPC98, SharpX68000, + MarkerComputerEnd, + #endregion #region Arcade @@ -110,6 +114,8 @@ TandyMemorexVisualInformationSystem, TsunamiTsuMoMultiGameMotionSystem, + MarkerArcadeEnd, + #endregion #region Other @@ -127,11 +133,25 @@ TomyKissSite, VideoCD, + MarkerOtherEnd, + #endregion - Custom = -1 + Custom = 0x0EADBEEF } + /// + /// Known system category + /// + public enum KnownSystemCategory + { + Console = 0, + Computer, + Arcade, + Other, + Custom + }; + /// /// Known media types /// diff --git a/DICUI/External/IOrderedDictionary.cs b/DICUI/External/IOrderedDictionary.cs deleted file mode 100644 index 17fc4c37..00000000 --- a/DICUI/External/IOrderedDictionary.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace DICUI.External -{ - // Adapted from https://www.codeproject.com/Articles/18615/OrderedDictionary-T-A-generic-implementation-of-IO - public interface IOrderedDictionary : IOrderedDictionary, IDictionary - { - } -} diff --git a/DICUI/External/OrderedDictionary.cs b/DICUI/External/OrderedDictionary.cs deleted file mode 100644 index 5460c626..00000000 --- a/DICUI/External/OrderedDictionary.cs +++ /dev/null @@ -1,330 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace DICUI.External -{ - // Adapted from https://www.codeproject.com/Articles/18615/OrderedDictionary-T-A-generic-implementation-of-IO - public class OrderedDictionary : IOrderedDictionary - { - private List> _list; - private Dictionary _dictionary; - - #region Interface properties - - public int Count { get; private set; } - - int ICollection.Count => Count; - int ICollection>.Count => Count; - - ICollection IDictionary.Keys => _dictionary.Keys; - ICollection IDictionary.Keys => _dictionary.Keys; - - ICollection IDictionary.Values => _dictionary.Values; - ICollection IDictionary.Values => _dictionary.Values; - - bool IDictionary.IsReadOnly => false; - bool ICollection>.IsReadOnly => false; - - bool IDictionary.IsFixedSize => false; - - object ICollection.SyncRoot => new object(); - - bool ICollection.IsSynchronized => true; - - public TValue this[int index] - { - get - { - return _list[index].Value; - } - set - { - if (index >= Count || index < 0) - throw new ArgumentOutOfRangeException("index", - "'index' must be non-negative and less than" + - " the size of the collection"); - - TKey key = _list[index].Key; - - _list[index] = new KeyValuePair(key, value); - _dictionary[key] = value; - } - } - - object IOrderedDictionary.this[int index] - { - get - { - return _list[index].Value; - } - set - { - if (index >= Count || index < 0) - throw new ArgumentOutOfRangeException("index", - "'index' must be non-negative and less than" + - " the size of the collection"); - - var valueObj = (TValue)value; - if (valueObj == null) - throw new ArgumentException($"Value must be of type {typeof(TValue)}"); - - TKey key = _list[index].Key; - - _list[index] = new KeyValuePair(key, valueObj); - _dictionary[key] = valueObj; - } - } - - object IDictionary.this[object key] - { - get - { - var keyObj = (TKey)key; - if (keyObj == null) - throw new ArgumentException($"Key must be of type {typeof(TKey)}"); - - return _dictionary[keyObj]; - } - set - { - var keyObj = (TKey)key; - if (keyObj == null) - throw new ArgumentException($"Key must be of type {typeof(TKey)}"); - - var valueObj = (TValue)value; - if (valueObj == null) - throw new ArgumentException($"Value must be of type {typeof(TValue)}"); - - if (_dictionary.ContainsKey(keyObj)) - { - _dictionary[keyObj] = valueObj; - _list[IndexOfKey(keyObj)] = new KeyValuePair(keyObj, valueObj); - } - else - { - Add(keyObj, valueObj); - } - } - } - - TValue IDictionary.this[TKey key] - { - get - { - return _dictionary[key]; - } - set - { - if (_dictionary.ContainsKey(key)) - { - _dictionary[key] = value; - _list[IndexOfKey(key)] = new KeyValuePair(key, value); - } - else - { - Add(key, value); - } - } - } - - #endregion - - public OrderedDictionary() - { - _list = new List>(); - _dictionary = new Dictionary(); - Count = 0; - } - - public int Add(TKey key, TValue value) - { - _dictionary.Add(key, value); - _list.Add(new KeyValuePair(key, value)); - Count++; - return Count - 1; - } - - public void Insert(int index, TKey key, TValue value) - { - if (index > Count || index < 0) - throw new ArgumentOutOfRangeException("index"); - - _dictionary.Add(key, value); - _list.Insert(index, new KeyValuePair(key, value)); - Count++; - } - - void IOrderedDictionary.RemoveAt(int index) - { - if (index >= Count || index < 0) - throw new ArgumentOutOfRangeException("index", - "'index' must be non-negative and less than " + - "the size of the collection"); - - TKey key = _list[index].Key; - - _list.RemoveAt(index); - _dictionary.Remove(key); - Count--; - } - - public bool Remove(TKey key) - { - if (null == key) - throw new ArgumentNullException("key"); - - int index = IndexOfKey(key); - if (index >= 0) - { - if (_dictionary.Remove(key)) - { - _list.RemoveAt(index); - Count--; - return true; - } - } - return false; - } - - public bool ContainsKey(TKey key) - { - return _dictionary.ContainsKey(key); - } - - private int IndexOfKey(TKey key) - { - return _list.FindIndex(kvp => kvp.Key.Equals(key)); - } - - #region Interface methods - - IDictionaryEnumerator IOrderedDictionary.GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - - void IOrderedDictionary.Insert(int index, object key, object value) - { - var keyObj = (TKey)key; - if (keyObj == null) - throw new ArgumentException($"Key must be of type {typeof(TKey)}"); - - var valueObj = (TValue)value; - if (valueObj == null) - throw new ArgumentException($"Value must be of type {typeof(TValue)}"); - - Insert(index, keyObj, valueObj); - } - - bool IDictionary.Contains(object key) - { - var keyObj = (TKey)key; - if (keyObj == null) - throw new ArgumentException($"Key must be of type {typeof(TKey)}"); - - return _dictionary.ContainsKey(keyObj); - } - - void IDictionary.Add(object key, object value) - { - var keyObj = (TKey)key; - if (keyObj == null) - throw new ArgumentException($"Key must be of type {typeof(TKey)}"); - - var valueObj = (TValue)value; - if (valueObj == null) - throw new ArgumentException($"Value must be of type {typeof(TValue)}"); - - Add(keyObj, valueObj); - } - - void IDictionary.Clear() - { - _dictionary.Clear(); - _list.Clear(); - } - - IDictionaryEnumerator IDictionary.GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - - void IDictionary.Remove(object key) - { - var keyObj = (TKey)key; - if (keyObj == null) - throw new ArgumentException($"Key must be of type {typeof(TKey)}"); - - Remove(keyObj); - } - - void ICollection.CopyTo(Array array, int index) - { - var arrayObj = array as KeyValuePair[]; - if (arrayObj == null) - throw new ArgumentException($"Key must be of type {typeof(KeyValuePair[])}"); - - _list.CopyTo(arrayObj, index); - } - - bool IDictionary.ContainsKey(TKey key) - { - return ContainsKey(key); - } - - void IDictionary.Add(TKey key, TValue value) - { - Add(key, value); - } - - bool IDictionary.Remove(TKey key) - { - return Remove(key); - } - - bool IDictionary.TryGetValue(TKey key, out TValue value) - { - return _dictionary.TryGetValue(key, out value); - } - - void ICollection>.Add(KeyValuePair item) - { - Add(item.Key, item.Value); - } - - void ICollection>.Clear() - { - _dictionary.Clear(); - _list.Clear(); - } - - bool ICollection>.Contains(KeyValuePair item) - { - return _list.Contains(item); - } - - void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) - { - _list.CopyTo(array, arrayIndex); - } - - bool ICollection>.Remove(KeyValuePair item) - { - return Remove(item.Key); - } - - IEnumerator> IEnumerable>.GetEnumerator() - { - return _list.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _list.GetEnumerator(); - } - - #endregion - } -} diff --git a/DICUI/MainWindow.xaml b/DICUI/MainWindow.xaml index 422b69e2..b1da9fff 100644 --- a/DICUI/MainWindow.xaml +++ b/DICUI/MainWindow.xaml @@ -48,7 +48,13 @@ private void PopulateMediaTypeAccordingToChosenSystem() { - var currentSystem = cmb_SystemType.SelectedItem as KeyValuePair?; + KnownSystem? currentSystem = cmb_SystemType.SelectedItem as KnownSystemComboBoxItem; if (currentSystem != null) { - _mediaTypes = Validators.GetValidMediaTypes(currentSystem?.Value).ToList(); + _mediaTypes = Validators.GetValidMediaTypes(currentSystem).ToList(); cmb_MediaType.ItemsSource = _mediaTypes; cmb_MediaType.IsEnabled = _mediaTypes.Count > 1; @@ -168,11 +176,26 @@ namespace DICUI /// private void PopulateSystems() { - _systems = Validators.CreateListOfSystems() - .Select(i => new KeyValuePair(i.Key, i.Value)) - .ToList(); - cmb_SystemType.ItemsSource = _systems; - cmb_SystemType.DisplayMemberPath = "Key"; + _systems = Validators.CreateListOfSystems(); + + Dictionary> mapping = _systems + .GroupBy(s => s.Category()) + .ToDictionary( + k => k.Key, + v => v + .OrderBy(s => s.Name()) + .ToList() + ); + + List comboBoxItems = new List(); + + foreach (var group in mapping) + { + comboBoxItems.Add(new KnownSystemComboBoxItem(group.Key)); + group.Value.ForEach(system => comboBoxItems.Add(new KnownSystemComboBoxItem(system))); + } + + cmb_SystemType.ItemsSource = comboBoxItems; cmb_SystemType.SelectedIndex = 0; btn_StartStop.IsEnabled = false; @@ -185,11 +208,8 @@ namespace DICUI private void PopulateDrives() { // Populate the list of drives and add it to the combo box - _drives = Validators.CreateListOfDrives() - .Select(i => new KeyValuePair(i.Key, i.Value)) - .ToList(); + _drives = Validators.CreateListOfDrives(); cmb_DriveLetter.ItemsSource = _drives; - cmb_DriveLetter.DisplayMemberPath = "Key"; if (cmb_DriveLetter.Items.Count > 0) { @@ -226,8 +246,6 @@ namespace DICUI private DumpEnvironment DetermineEnvironment() { // Populate all KVPs - var driveKvp = cmb_DriveLetter.SelectedItem as KeyValuePair?; - var systemKvp = cmb_SystemType.SelectedValue as KeyValuePair?; return new DumpEnvironment() { @@ -239,12 +257,11 @@ namespace DICUI OutputFilename = txt_OutputFilename.Text, // Get the currently selected options - DriveLetter = (char)driveKvp?.Key, - IsFloppy = (driveKvp?.Value == UIElements.FloppyDriveString), + Drive = cmb_DriveLetter.SelectedItem as Drive, DICParameters = txt_Parameters.Text, - System = systemKvp?.Value, + System = (KnownSystem?)(cmb_SystemType.SelectedItem as KnownSystemComboBoxItem), Type = cmb_MediaType.SelectedItem as MediaType? }; } @@ -274,23 +291,14 @@ namespace DICUI /// private void EnsureDiscInformation() { - var systemKvp = cmb_SystemType.SelectedItem as KeyValuePair?; - - // If we're on a separator, go to the next item and return - if (systemKvp?.Value == null) - { - cmb_SystemType.SelectedIndex++; - return; - } - // Get the selected system info - var selectedSystem = systemKvp?.Value; + KnownSystem? selectedSystem = (KnownSystem?)(cmb_SystemType.SelectedItem as KnownSystemComboBoxItem) ?? KnownSystem.NONE; MediaType? selectedMediaType = cmb_MediaType.SelectedItem as MediaType? ?? MediaType.NONE; Result result = GetSupportStatus(selectedSystem, selectedMediaType); lbl_Status.Content = result.Message; - btn_StartStop.IsEnabled = result && (_drives.Count > 0 ? true : false); + btn_StartStop.IsEnabled = result && (_drives != null && _drives.Count > 0 ? true : false); // If we're in a type that doesn't support drive speeds cmb_DriveSpeed.IsEnabled = selectedMediaType.DoesSupportDriveSpeed() && selectedSystem.DoesSupportDriveSpeed(); @@ -318,16 +326,16 @@ namespace DICUI // Populate with the correct params for inputs (if we're not on the default option) if (selectedSystem != KnownSystem.NONE && selectedMediaType != MediaType.NONE) { - var driveletter = cmb_DriveLetter.SelectedValue as KeyValuePair?; + Drive drive = cmb_DriveLetter.SelectedValue as Drive; // If drive letter is invalid, skip this - if (driveletter == null) + if (drive == null) return; string command = Converters.KnownSystemAndMediaTypeToBaseCommand(selectedSystem, selectedMediaType); List defaultParams = Converters.KnownSystemAndMediaTypeToParameters(selectedSystem, selectedMediaType); txt_Parameters.Text = command - + " " + driveletter?.Key + + " " + drive.Letter + " \"" + Path.Combine(txt_OutputDirectory.Text, txt_OutputFilename.Text) + "\" " + (selectedMediaType != MediaType.Floppy && selectedMediaType != MediaType.BluRay @@ -413,18 +421,18 @@ namespace DICUI /// private void GetOutputNames() { - var driveKvp = cmb_DriveLetter.SelectedItem as KeyValuePair?; - var systemKvp = cmb_SystemType.SelectedItem as KeyValuePair?; + Drive drive = cmb_DriveLetter.SelectedItem as Drive; + KnownSystem? systemType = (KnownSystem?)(cmb_SystemType.SelectedItem as KnownSystemComboBoxItem); MediaType? mediaType = cmb_MediaType.SelectedItem as MediaType?; - if (driveKvp != null - && !String.IsNullOrWhiteSpace(driveKvp?.Value) - && driveKvp?.Value != UIElements.FloppyDriveString - && systemKvp != null + if (drive != null + && !String.IsNullOrWhiteSpace(drive.VolumeLabel) + && !drive.IsFloppy + && systemType != null && mediaType != null) { - txt_OutputDirectory.Text = Path.Combine(_options.defaultOutputPath, driveKvp?.Value); - txt_OutputFilename.Text = driveKvp?.Value + mediaType.Extension(); + txt_OutputDirectory.Text = Path.Combine(_options.defaultOutputPath, drive.VolumeLabel); + txt_OutputFilename.Text = drive.VolumeLabel + mediaType.Extension(); } else { @@ -444,11 +452,9 @@ namespace DICUI cmb_DriveSpeed.SelectedIndex = values.Count / 2; // Get the drive letter from the selected item - var selected = cmb_DriveLetter.SelectedItem as KeyValuePair?; - if (selected == null || (selected?.Value == UIElements.FloppyDriveString)) - { + Drive drive = cmb_DriveLetter.SelectedItem as Drive; + if (drive == null || drive.IsFloppy) return; - } //Validators.GetDriveSpeed((char)selected?.Key); //Validators.GetDriveSpeedEx((char)selected?.Key, _currentMediaType); @@ -460,13 +466,12 @@ namespace DICUI return; } - char driveLetter = (char)selected?.Key; Process childProcess = new Process() { StartInfo = new ProcessStartInfo() { FileName = _options.dicPath, - Arguments = DICCommands.DriveSpeed + " " + driveLetter, + Arguments = DICCommands.DriveSpeed + " " + drive.Letter, CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, @@ -499,14 +504,12 @@ namespace DICUI private void SetCurrentDiscType() { // Get the drive letter from the selected item - var selected = cmb_DriveLetter.SelectedItem as KeyValuePair?; - if (selected == null || (selected?.Value == UIElements.FloppyDriveString)) - { + Drive drive = cmb_DriveLetter.SelectedItem as Drive; + if (drive == null || drive.IsFloppy) return; - } // Get the current optical disc type - _currentMediaType = Validators.GetDiscType(selected?.Key); + _currentMediaType = Validators.GetDiscType(drive.Letter); // If we have an invalid current type, we don't care and return if (_currentMediaType == null || _currentMediaType == MediaType.NONE) diff --git a/DICUI/Tasks.cs b/DICUI/Tasks.cs index 9a66d6b2..873c6de2 100644 --- a/DICUI/Tasks.cs +++ b/DICUI/Tasks.cs @@ -49,15 +49,16 @@ namespace DICUI public string OutputFilename; // UI information - public char DriveLetter; + public Drive Drive; public KnownSystem? System; public MediaType? Type; - public bool IsFloppy; public string DICParameters; // External process information public Process dicProcess; + public bool IsFloppy { get => Drive.IsFloppy; } + /// /// Checks if the configuration is valid /// @@ -66,7 +67,7 @@ namespace DICUI { return !((string.IsNullOrWhiteSpace(DICParameters) || !Validators.ValidateParameters(DICParameters) - || (IsFloppy ^ Type == MediaType.Floppy))); + || (Drive.IsFloppy ^ Type == MediaType.Floppy))); } /// @@ -78,7 +79,7 @@ namespace DICUI if (System == KnownSystem.Custom) { Validators.DetermineFlags(DICParameters, out Type, out System, out string letter, out string path); - DriveLetter = (String.IsNullOrWhiteSpace(letter) ? new char() : letter[0]); + Drive = Drive.Optical(String.IsNullOrWhiteSpace(letter) ? new char() : letter[0], ""); OutputDirectory = Path.GetDirectoryName(path); OutputFilename = Path.GetFileName(path); } @@ -129,7 +130,7 @@ namespace DICUI StartInfo = new ProcessStartInfo() { FileName = env.DICPath, - Arguments = DICCommands.Eject + " " + env.DriveLetter, + Arguments = DICCommands.Eject + " " + env.Drive.Letter, CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, @@ -269,7 +270,7 @@ namespace DICUI StartInfo = new ProcessStartInfo() { FileName = env.SubdumpPath, - Arguments = "-i " + env.DriveLetter + ": -f " + Path.Combine(env.OutputDirectory, Path.GetFileNameWithoutExtension(env.OutputFilename) + "_subdump.sub") + "-mode 6 -rereadnum 25 -fix 2", + Arguments = "-i " + env.Drive.Letter + ": -f " + Path.Combine(env.OutputDirectory, Path.GetFileNameWithoutExtension(env.OutputFilename) + "_subdump.sub") + "-mode 6 -rereadnum 25 -fix 2", }, }; childProcess.Start(); @@ -288,7 +289,7 @@ namespace DICUI if (!DumpInformation.FoundAllFiles(env.OutputDirectory, env.OutputFilename, env.Type)) return Result.Failure("Error! Please check output directory as dump may be incomplete!"); - Dictionary templateValues = DumpInformation.ExtractOutputInformation(env.OutputDirectory, env.OutputFilename, env.System, env.Type, env.DriveLetter); + Dictionary templateValues = DumpInformation.ExtractOutputInformation(env.OutputDirectory, env.OutputFilename, env.System, env.Type, env.Drive.Letter); List formattedValues = DumpInformation.FormatOutputData(templateValues, env.System, env.Type); bool success = DumpInformation.WriteOutputData(env.OutputDirectory, env.OutputFilename, formattedValues); diff --git a/DICUI/Utilities/Converters.cs b/DICUI/Utilities/Converters.cs index f9dd6c41..4706b6d5 100644 --- a/DICUI/Utilities/Converters.cs +++ b/DICUI/Utilities/Converters.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.Windows.Data; using IMAPI2; using DICUI.Data; +using static DICUI.Data.UIElements; namespace DICUI.Utilities { @@ -44,12 +45,67 @@ namespace DICUI.Utilities /// public static class KnownSystemExtensions { + public static string Name(this KnownSystem? system) + { + return Converters.KnownSystemToString(system); + } + public static bool DoesSupportDriveSpeed(this KnownSystem? system) { return system != KnownSystem.MicrosoftXBOX && system != KnownSystem.MicrosoftXBOX360XDG2 && system != KnownSystem.MicrosoftXBOX360XDG3; } + + public static KnownSystemCategory Category(this KnownSystem? system) + { + if (system < KnownSystem.MarkerConsoleEnd) + return KnownSystemCategory.Console; + else if (system < KnownSystem.MarkerComputerEnd) + return KnownSystemCategory.Computer; + else if (system < KnownSystem.MarkerArcadeEnd) + return KnownSystemCategory.Arcade; + else if (system < KnownSystem.MarkerOtherEnd) + return KnownSystemCategory.Other; + else + return KnownSystemCategory.Custom; + } + + public static bool IsMarker(this KnownSystem? system) + { + switch (system) + { + case KnownSystem.MarkerArcadeEnd: + case KnownSystem.MarkerComputerEnd: + case KnownSystem.MarkerConsoleEnd: + case KnownSystem.MarkerOtherEnd: + return true; + default: + return false; + } + } + } + + /// + /// Extensions for KnownSystemCategory? + /// + public static class KnownSystemCategoryExtensions + { + /// + /// Get the string representation of a KnownSystemCategory + /// + public static string Name(this KnownSystemCategory? category) + { + switch (category) + { + case KnownSystemCategory.Arcade: return "Arcade"; + case KnownSystemCategory.Computer: return "Computers"; + case KnownSystemCategory.Console: return "Consoles"; + case KnownSystemCategory.Other: return "Other"; + case KnownSystemCategory.Custom: return "Custom"; + default: return ""; + } + } } /// diff --git a/DICUI/Utilities/DumpInformation.cs b/DICUI/Utilities/DumpInformation.cs index ba8385f8..15e0a4ef 100644 --- a/DICUI/Utilities/DumpInformation.cs +++ b/DICUI/Utilities/DumpInformation.cs @@ -143,8 +143,8 @@ namespace DICUI.Utilities { Template.TitleField, Template.RequiredValue }, { Template.DiscNumberField, Template.OptionalValue }, { Template.DiscTitleField, Template.OptionalValue }, - { Template.SystemField, Converters.KnownSystemToString(sys) }, - { Template.MediaTypeField, Converters.MediaTypeToString(type) }, + { Template.SystemField, sys.Name() }, + { Template.MediaTypeField, type.Name() }, { Template.CategoryField, "Games" }, { Template.RegionField, "World (CHANGE THIS)" }, { Template.LanguagesField, "Klingon (CHANGE THIS)" }, diff --git a/DICUI/Utilities/Validators.cs b/DICUI/Utilities/Validators.cs index a11972e4..308cb33a 100644 --- a/DICUI/Utilities/Validators.cs +++ b/DICUI/Utilities/Validators.cs @@ -8,9 +8,27 @@ using System.Text.RegularExpressions; using IMAPI2; using DICUI.Data; using DICUI.External; +using static DICUI.Data.UIElements; namespace DICUI.Utilities { + public class Drive + { + public char Letter { get; private set; } + public bool IsFloppy { get; private set; } + public string VolumeLabel { get; private set; } + + private Drive(char letter, string volumeLabel, bool isFloppy) + { + this.Letter = letter; + this.IsFloppy = isFloppy; + this.VolumeLabel = volumeLabel; + } + + public static Drive Floppy(char letter) => new Drive(letter, null, true); + public static Drive Optical(char letter, string volumeLabel) => new Drive(letter, volumeLabel, false); + } + public static class Validators { /// @@ -378,54 +396,27 @@ namespace DICUI.Utilities /// If something has a "string, null" value, it should be assumed that it is a separator /// /// TODO: Figure out a way that the sections can be generated more automatically - public static OrderedDictionary CreateListOfSystems() + public static List CreateListOfSystems() { - var systemsDict = new OrderedDictionary(); - - foreach (KnownSystem system in Enum.GetValues(typeof(KnownSystem))) - { - // In the special cases of breaks, we want to add the proper mappings for sections - switch (system) - { - // Consoles section - case KnownSystem.BandaiPlaydiaQuickInteractiveSystem: - systemsDict.Add("---------- Consoles ----------", null); - break; - - // Computers section - case KnownSystem.AcornArchimedes: - systemsDict.Add("---------- Computers ----------", null); - break; - - // Arcade section - case KnownSystem.AmigaCUBOCD32: - systemsDict.Add("---------- Arcade ----------", null); - break; - - // Other section - case KnownSystem.AudioCD: - systemsDict.Add("---------- Others ----------", null); - break; - } - - systemsDict.Add(Converters.KnownSystemToString(system), system); - } - - return systemsDict; + return Enum.GetValues(typeof(KnownSystem)) + .OfType() + .Where(s => !s.IsMarker()) + .ToList(); } /// - /// Create a list of active optical drives matched to their volume labels + /// Create a list of active drives matched to their volume labels /// /// Active drives, matched to labels, if possible /// /// https://stackoverflow.com/questions/3060796/how-to-distinguish-between-usb-and-floppy-devices?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa /// https://msdn.microsoft.com/en-us/library/aa394173(v=vs.85).aspx /// - public static OrderedDictionary CreateListOfDrives() + public static List CreateListOfDrives() { + var drives = new List(); + // Get the floppy drives - var floppyDrives = new List>(); try { ManagementObjectSearcher searcher = @@ -439,7 +430,7 @@ namespace DICUI.Utilities if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22))) { char devId = queryObj["DeviceID"].ToString()[0]; - floppyDrives.Add(new KeyValuePair(devId, UIElements.FloppyDriveString)); + drives.Add(Drive.Floppy(devId)); } } } @@ -449,23 +440,16 @@ namespace DICUI.Utilities } // Get the optical disc drives - List> discDrives = DriveInfo.GetDrives() + List discDrives = DriveInfo.GetDrives() .Where(d => d.DriveType == DriveType.CDRom && d.IsReady) - .Select(d => new KeyValuePair(d.Name[0], d.VolumeLabel)) + .Select(d => Drive.Optical(d.Name[0], d.VolumeLabel)) .ToList(); // Add the two lists together and order - floppyDrives.AddRange(discDrives); - floppyDrives = floppyDrives.OrderBy(i => i.Key).ToList(); + drives.AddRange(discDrives); + drives = drives.OrderBy(i => i.Letter).ToList(); - // Add to the ordered dictionary and return - var drivesDict = new OrderedDictionary(); - foreach (var drive in floppyDrives) - { - drivesDict.Add(drive.Key, drive.Value); - } - - return drivesDict; + return drives; } ///